├── docs ├── CNAME ├── architecture.md ├── features.md ├── tests-ixia-c.md ├── developer │ ├── introduction.md │ └── snappi-install.md ├── quick-start │ ├── sample-test.md │ ├── deployment.md │ └── introduction.md ├── res │ ├── topo.png │ ├── UHD100T32.png │ ├── clearOwnership.PNG │ ├── uhd-connections.png │ ├── UHD400T_front_view.png │ ├── server-connections.png │ ├── hello-snappi-packets.png │ ├── packet-instrumentation.png │ └── hw-server.drawio ├── assets │ ├── logo.png │ ├── favicon.png │ └── keng-diagram.png ├── roadmap.md ├── contribute.md ├── integrated-environments.md ├── eula.md ├── support.md ├── usecases.md ├── resources.md ├── limitations.md ├── deployments-containerlab.md ├── tests-uhd400.md ├── prerequisites.md ├── reference │ ├── capabilities.md │ ├── resource-requirements.md │ └── licensing.md ├── index.md ├── user-guide-introduction.md ├── troubleshooting.md ├── tests-chassis-app.md ├── deployments-docker-compose.md ├── stylesheets │ └── extra.css ├── licensing.md ├── deployments-kne.md ├── deployments.md └── faq.md ├── requirements.txt ├── .gitignore ├── .markdownlint.json ├── .gitmodules ├── deployments ├── k8s │ ├── bases │ │ ├── namespace │ │ │ ├── namespace.yaml │ │ │ └── kustomization.yaml │ │ ├── otg-controller │ │ │ ├── kustomization.yaml │ │ │ ├── service.yaml │ │ │ └── pod.yaml │ │ └── otg-traffic-port │ │ │ ├── kustomization.yaml │ │ │ ├── service.yaml │ │ │ └── pod.yaml │ ├── network-emulation │ │ ├── namespace.yaml │ │ ├── kind.yaml │ │ ├── links.yaml │ │ ├── services.yaml │ │ ├── go.mod │ │ ├── pods.yaml │ │ ├── ipfwd.go │ │ ├── readme.md │ │ └── go.sum │ ├── overlays │ │ ├── one-traffic-port-eth0 │ │ │ ├── port1 │ │ │ │ ├── pod-patch.yaml │ │ │ │ ├── service-patch.yaml │ │ │ │ └── kustomization.yaml │ │ │ ├── kustomization.yaml │ │ │ └── config-map.yaml │ │ └── two-traffic-ports-eth0 │ │ │ ├── port1 │ │ │ ├── pod-patch.yaml │ │ │ ├── service-patch.yaml │ │ │ └── kustomization.yaml │ │ │ ├── port2 │ │ │ ├── pod-patch.yaml │ │ │ ├── service-patch.yaml │ │ │ └── kustomization.yaml │ │ │ ├── config-map.yaml │ │ │ ├── init-container.yaml │ │ │ ├── kustomization.yaml │ │ │ └── gen-test-config.sh │ ├── components │ │ └── images │ │ │ └── kustomization.yaml │ ├── kind.yaml │ └── readme.md ├── .env ├── raw-one-arm.yml ├── raw-two-arm.yml ├── raw-three-arm-mesh.yml └── docker │ ├── readme.md │ └── deployment.sh ├── .github └── workflows │ ├── publish.yml │ └── ci.yml ├── license ├── CONTRIBUTING.md ├── mkdocs.md ├── mkdocs.yml ├── notes.md ├── CODE_OF_CONDUCT.md └── readme.md /docs/CNAME: -------------------------------------------------------------------------------- 1 | ixia-c.dev -------------------------------------------------------------------------------- /docs/architecture.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocs-material -------------------------------------------------------------------------------- /docs/features.md: -------------------------------------------------------------------------------- 1 | ### Feature metrics showcasing free vs commercial usage -------------------------------------------------------------------------------- /docs/tests-ixia-c.md: -------------------------------------------------------------------------------- 1 | # Ixia-c tests 2 | 3 | How to run tests with Ixia-c 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | scratch 2 | env 3 | *.pcap 4 | *.log 5 | venv 6 | site 7 | .DS_Store 8 | *.bkp 9 | -------------------------------------------------------------------------------- /docs/developer/introduction.md: -------------------------------------------------------------------------------- 1 | # Developer guide introduction 2 | 3 | Introduction to snappi 4 | -------------------------------------------------------------------------------- /docs/quick-start/sample-test.md: -------------------------------------------------------------------------------- 1 | # Quick start sample test 2 | 3 | How to run the sample test 4 | -------------------------------------------------------------------------------- /docs/res/topo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-traffic-generator/ixia-c/HEAD/docs/res/topo.png -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "default": true, 3 | "MD013" : false, 4 | "MD033": false 5 | } 6 | 7 | -------------------------------------------------------------------------------- /docs/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-traffic-generator/ixia-c/HEAD/docs/assets/logo.png -------------------------------------------------------------------------------- /docs/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-traffic-generator/ixia-c/HEAD/docs/assets/favicon.png -------------------------------------------------------------------------------- /docs/res/UHD100T32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-traffic-generator/ixia-c/HEAD/docs/res/UHD100T32.png -------------------------------------------------------------------------------- /docs/assets/keng-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-traffic-generator/ixia-c/HEAD/docs/assets/keng-diagram.png -------------------------------------------------------------------------------- /docs/res/clearOwnership.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-traffic-generator/ixia-c/HEAD/docs/res/clearOwnership.PNG -------------------------------------------------------------------------------- /docs/res/uhd-connections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-traffic-generator/ixia-c/HEAD/docs/res/uhd-connections.png -------------------------------------------------------------------------------- /docs/res/UHD400T_front_view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-traffic-generator/ixia-c/HEAD/docs/res/UHD400T_front_view.png -------------------------------------------------------------------------------- /docs/res/server-connections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-traffic-generator/ixia-c/HEAD/docs/res/server-connections.png -------------------------------------------------------------------------------- /docs/res/hello-snappi-packets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-traffic-generator/ixia-c/HEAD/docs/res/hello-snappi-packets.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "conformance"] 2 | path = conformance 3 | url = https://github.com/open-traffic-generator/conformance.git 4 | -------------------------------------------------------------------------------- /docs/res/packet-instrumentation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/open-traffic-generator/ixia-c/HEAD/docs/res/packet-instrumentation.png -------------------------------------------------------------------------------- /deployments/k8s/bases/namespace/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | app: ixia-c 6 | name: ixia-c -------------------------------------------------------------------------------- /deployments/k8s/network-emulation/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | app: ixia-c 6 | name: ixia-c -------------------------------------------------------------------------------- /docs/roadmap.md: -------------------------------------------------------------------------------- 1 | # Roadmap 2 | 3 | Ixia-c is released periodically. This page does NOT list all the minor/bug-fix releases that are planned. 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /deployments/k8s/bases/namespace/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - namespace.yaml 6 | -------------------------------------------------------------------------------- /deployments/k8s/bases/otg-controller/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - pod.yaml 6 | - service.yaml -------------------------------------------------------------------------------- /deployments/k8s/bases/otg-traffic-port/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - pod.yaml 6 | - service.yaml -------------------------------------------------------------------------------- /deployments/k8s/overlays/one-traffic-port-eth0/port1/pod-patch.yaml: -------------------------------------------------------------------------------- 1 | - op: replace 2 | path: /metadata/labels/role 3 | value: otg-port1 4 | - op: replace 5 | path: /metadata/name 6 | value: otg-port1 -------------------------------------------------------------------------------- /deployments/k8s/overlays/one-traffic-port-eth0/port1/service-patch.yaml: -------------------------------------------------------------------------------- 1 | - op: replace 2 | path: /metadata/name 3 | value: otg-port1 4 | - op: replace 5 | path: /spec/selector/role 6 | value: otg-port1 -------------------------------------------------------------------------------- /deployments/k8s/overlays/two-traffic-ports-eth0/port1/pod-patch.yaml: -------------------------------------------------------------------------------- 1 | - op: replace 2 | path: /metadata/labels/role 3 | value: otg-port1 4 | - op: replace 5 | path: /metadata/name 6 | value: otg-port1 -------------------------------------------------------------------------------- /deployments/k8s/overlays/two-traffic-ports-eth0/port1/service-patch.yaml: -------------------------------------------------------------------------------- 1 | - op: replace 2 | path: /metadata/name 3 | value: otg-port1 4 | - op: replace 5 | path: /spec/selector/role 6 | value: otg-port1 -------------------------------------------------------------------------------- /deployments/k8s/overlays/two-traffic-ports-eth0/port2/pod-patch.yaml: -------------------------------------------------------------------------------- 1 | - op: replace 2 | path: /metadata/labels/role 3 | value: otg-port2 4 | - op: replace 5 | path: /metadata/name 6 | value: otg-port2 -------------------------------------------------------------------------------- /deployments/k8s/overlays/two-traffic-ports-eth0/port2/service-patch.yaml: -------------------------------------------------------------------------------- 1 | - op: replace 2 | path: /metadata/name 3 | value: otg-port2 4 | - op: replace 5 | path: /spec/selector/role 6 | value: otg-port2 -------------------------------------------------------------------------------- /deployments/.env: -------------------------------------------------------------------------------- 1 | CONTROLLER_VERSION=latest 2 | TRAFFIC_ENGINE_VERSION=latest 3 | AUR_VERSION=latest 4 | IFC1=eth1 5 | IFC2=eth2 6 | IFC3=eth3 7 | TCP_PORT_IFC1=5555 8 | TCP_PORT_IFC2=5556 9 | TCP_PORT_IFC3=5557 10 | CPU_CORES_IFC1="0,1,2" 11 | CPU_CORES_IFC2="0,3,4" 12 | CPU_CORES_IFC3="0,5,6" -------------------------------------------------------------------------------- /deployments/k8s/bases/otg-traffic-port/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: otg-port 5 | namespace: ixia-c 6 | spec: 7 | ports: 8 | - name: zeromq 9 | port: 5555 10 | protocol: TCP 11 | targetPort: zeromq-port 12 | selector: 13 | role: otg-port -------------------------------------------------------------------------------- /deployments/k8s/overlays/one-traffic-port-eth0/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ../../bases/namespace 6 | - ../../bases/otg-controller 7 | - port1 8 | - config-map.yaml 9 | 10 | components: 11 | - ../../components/images 12 | -------------------------------------------------------------------------------- /deployments/k8s/overlays/one-traffic-port-eth0/config-map.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | labels: 5 | app: ixia-c 6 | name: controller-config 7 | namespace: ixia-c 8 | data: 9 | config.yaml: | 10 | location_map: 11 | - location: port1 12 | endpoint: otg-port1.ixia-c.svc.cluster.local:5555 13 | -------------------------------------------------------------------------------- /docs/contribute.md: -------------------------------------------------------------------------------- 1 | # Contribute 2 | 3 | We encourage you to contribute to Ixia-c by : 4 | 5 | - using it 6 | - reporting issues 7 | - requesting enhancements 8 | - contributing your Ixia-c based use-cases 9 | - reviewing and contributing to [Open Traffic Generator Data Models](https://github.com/open-traffic-generator/models) 10 | 11 | You can reach out to us on Slack as noted [here](support.md). 12 | -------------------------------------------------------------------------------- /deployments/k8s/overlays/two-traffic-ports-eth0/config-map.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | labels: 5 | app: ixia-c 6 | name: controller-config 7 | namespace: ixia-c 8 | data: 9 | config.yaml: | 10 | location_map: 11 | - location: port1 12 | endpoint: otg-port1.ixia-c.svc.cluster.local:5555 13 | - location: port2 14 | endpoint: otg-port2.ixia-c.svc.cluster.local:5555 -------------------------------------------------------------------------------- /deployments/k8s/overlays/one-traffic-port-eth0/port1/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ../../../bases/otg-traffic-port 6 | 7 | patches: 8 | - target: 9 | version: v1 10 | kind: Pod 11 | name: otg-port 12 | path: pod-patch.yaml 13 | - target: 14 | version: v1 15 | kind: Service 16 | name: otg-port 17 | path: service-patch.yaml -------------------------------------------------------------------------------- /deployments/k8s/overlays/two-traffic-ports-eth0/port1/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ../../../bases/otg-traffic-port 6 | 7 | patches: 8 | - target: 9 | version: v1 10 | kind: Pod 11 | name: otg-port 12 | path: pod-patch.yaml 13 | - target: 14 | version: v1 15 | kind: Service 16 | name: otg-port 17 | path: service-patch.yaml -------------------------------------------------------------------------------- /deployments/k8s/overlays/two-traffic-ports-eth0/port2/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ../../../bases/otg-traffic-port 6 | 7 | patches: 8 | - target: 9 | version: v1 10 | kind: Pod 11 | name: otg-port 12 | path: pod-patch.yaml 13 | - target: 14 | version: v1 15 | kind: Service 16 | name: otg-port 17 | path: service-patch.yaml -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: publish 2 | on: 3 | push: 4 | branches: 5 | - main 6 | workflow_dispatch: 7 | jobs: 8 | deploy: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | with: 13 | submodules: recursive 14 | - uses: actions/setup-python@v4 15 | with: 16 | python-version: 3.x 17 | - run: pip install mkdocs-material 18 | - run: mkdocs gh-deploy --force 19 | -------------------------------------------------------------------------------- /docs/integrated-environments.md: -------------------------------------------------------------------------------- 1 | ## Network Topology Emulation 2 | 3 | Ixia-c supports the following modern network emulation software: 4 | 5 | * [Containerlab:](deployments-containerlab.md) Simple yet powerful specialized tool for orchestrating and managing container-based networking labs. 6 | * [OpenConfig KNE:](deployments-kne.md) Kubernetes Network Emulation, which is a Google initiative to develop tooling for quickly setting up topologies of containers running various device OSes. 7 | -------------------------------------------------------------------------------- /deployments/k8s/overlays/two-traffic-ports-eth0/init-container.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: _ 5 | spec: 6 | initContainers: 7 | - name: init-setup 8 | image: ubuntu:22.04 9 | command: 10 | - bash 11 | - -c 12 | - apt-get update && apt-get install -y iptables && iptables -A INPUT -p udp --destination-port 7000:8000 -j DROP && iptables -A INPUT -p tcp --destination-port 7000:8000 -j DROP 13 | securityContext: 14 | privileged: true -------------------------------------------------------------------------------- /deployments/k8s/overlays/two-traffic-ports-eth0/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ../../bases/namespace 6 | - ../../bases/otg-controller 7 | - port1 8 | - port2 9 | - config-map.yaml 10 | 11 | components: 12 | - ../../components/images 13 | 14 | patches: 15 | - path: init-container.yaml 16 | target: 17 | kind: Pod 18 | name: otg-port1 19 | - path: init-container.yaml 20 | target: 21 | kind: Pod 22 | name: otg-port2 -------------------------------------------------------------------------------- /deployments/k8s/components/images/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1alpha1 2 | kind: Component 3 | 4 | # Release: https://github.com/open-traffic-generator/ixia-c/releases/tag/v1.42.0-4 5 | images: 6 | - name: keng-controller 7 | newName: ghcr.io/open-traffic-generator/keng-controller 8 | newTag: "1.42.0-4" 9 | - name: otg-gnmi-server 10 | newName: ghcr.io/open-traffic-generator/otg-gnmi-server 11 | newTag: "1.42.4" 12 | - name: ixia-c-traffic-engine 13 | newName: ghcr.io/open-traffic-generator/ixia-c-traffic-engine 14 | newTag: "1.8.0.245" 15 | -------------------------------------------------------------------------------- /docs/eula.md: -------------------------------------------------------------------------------- 1 | # End User License Agreement 2 | 3 | By using Keysight Elastic Network Generator and Ixia-c software you accept Keysight Technologies' End User License Agreement (EULA). The agreement can be found at [www.keysight.com/find/sweula](https://www.keysight.com/find/sweula). 4 | 5 | The End-User License Agreement must be accepted before the KENG controller can start. The user can accept the EULA by specifying `--accept-eula` command line option while 6 | starting the `keng-controller` container. 7 | 8 | ## Copyright notice 9 | 10 | © Copyright Keysight Technologies, Inc. 2021, 2022, 2023 -------------------------------------------------------------------------------- /deployments/k8s/bases/otg-controller/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: service-otg-controller 5 | namespace: ixia-c 6 | spec: 7 | type: NodePort 8 | ports: 9 | - name: https 10 | port: 8443 11 | protocol: TCP 12 | targetPort: https-port 13 | nodePort: 30443 14 | - name: grpc 15 | port: 40051 16 | protocol: TCP 17 | targetPort: grpc-port 18 | nodePort: 30451 19 | - name: gnmi 20 | port: 50051 21 | protocol: TCP 22 | targetPort: gnmi-port 23 | nodePort: 30551 24 | selector: 25 | role: otg-controller 26 | -------------------------------------------------------------------------------- /docs/support.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | Commercial customers of the Keysight Elastic Network Generator can obtain support through the [Keysight Support Center](https://www.keysight.com/us/en/support.html), using the link to Network Test (Layer 2/3) and Visibility Support (Ixia). Please be ready to provide the KENG License activation code and a clear problem description. 4 | 5 | Support for the free version of Ixia-c can be obtained over Slack. You can join the Slack workspace ixia-c.slack.com using [this invite](https://join.slack.com/t/ixia-c/shared_invite/zt-1inkw2zr4-Jd6uynnxxhvhV6WC0MCtLQ). We also encourage you to open issues & enhancements in the [Ixia-c](https://github.com/open-traffic-generator/ixia-c/issues) repository. 6 | -------------------------------------------------------------------------------- /docs/usecases.md: -------------------------------------------------------------------------------- 1 | # Use Cases 2 | 3 | This page has a listing of all use-cases where Ixia-c is being used. 4 | 5 | - Chris Sommers' [demo](https://youtu.be/Db7Cx1hngVY) at [2021 P4 Workshop](https://opennetworking.org/2021-p4-workshop-3-0/) using snappi and Ixia-c to test a P4 application. You can find Chris' repo [here](https://github.com/chrispsommers/p4-guide/tree/snappi-tests2). 6 | 7 | - [when Packets go BRRRRRRRRRRRRR](https://zero.bs/when-packets-go-brrrrrrrrrrrrr.html) Ixia-c used as a traffic generator to replace [scapy](https://scapy.readthedocs.io/en/latest/) under the hood for [DDoS Stresstest](https://zero.bs/ddos-stresstest.en.html), a DDoS Assessment tool. 8 | 9 | Reach out to us on [Slack](support.md) to add your use-cases to this page. 10 | -------------------------------------------------------------------------------- /deployments/raw-one-arm.yml: -------------------------------------------------------------------------------- 1 | version: '3.9' 2 | services: 3 | controller: 4 | image: ghcr.io/open-traffic-generator/keng-controller:${CONTROLLER_VERSION:-latest} 5 | command: --accept-eula 6 | network_mode: "host" 7 | restart: always 8 | traffic_engine: 9 | image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:${TRAFFIC_ENGINE_VERSION:-latest} 10 | network_mode: "host" 11 | restart: always 12 | privileged: true 13 | cpuset: ${CPU_CORES_IFC1:-"0,1,2"} 14 | environment: 15 | - OPT_LISTEN_PORT=${TCP_PORT_IFC1:-5555} 16 | - ARG_IFACE_LIST=virtual@af_packet,${IFC1} 17 | - OPT_NO_HUGEPAGES=Yes 18 | aur: 19 | image: ghcr.io/open-traffic-generator/keng-app-usage-reporter:${AUR_VERSION:-latest} 20 | network_mode: "host" 21 | restart: always 22 | -------------------------------------------------------------------------------- /deployments/k8s/kind.yaml: -------------------------------------------------------------------------------- 1 | kind: Cluster 2 | apiVersion: kind.x-k8s.io/v1alpha4 3 | networking: 4 | # WARNING: It is _strongly_ recommended that you keep this the default 5 | # (127.0.0.1) for security reasons. However it is possible to change this. 6 | # Change to 0.0.0.0 to access kind cluster from outside 7 | apiServerAddress: 127.0.0.1 8 | # By default the API server listens on a random open port. 9 | # You may choose a specific port but probably don't need to in most cases. 10 | # Using a random port makes it easier to spin up multiple clusters. 11 | apiServerPort: 6443 12 | nodes: 13 | # configure single-node cluster 14 | - role: control-plane 15 | # map TCP ports exposed by pods to host 16 | extraPortMappings: 17 | - containerPort: 30443 18 | hostPort: 8443 19 | - containerPort: 30451 20 | hostPort: 40051 21 | - containerPort: 30551 22 | hostPort: 50051 23 | # replicate following for multi-node cluster with intended number of worker nodes 24 | # - role: workers -------------------------------------------------------------------------------- /deployments/k8s/network-emulation/kind.yaml: -------------------------------------------------------------------------------- 1 | kind: Cluster 2 | apiVersion: kind.x-k8s.io/v1alpha4 3 | networking: 4 | # WARNING: It is _strongly_ recommended that you keep this the default 5 | # (127.0.0.1) for security reasons. However it is possible to change this. 6 | # Change to 0.0.0.0 to access kind cluster from outside 7 | apiServerAddress: 127.0.0.1 8 | # By default the API server listens on a random open port. 9 | # You may choose a specific port but probably don't need to in most cases. 10 | # Using a random port makes it easier to spin up multiple clusters. 11 | apiServerPort: 6443 12 | nodes: 13 | # configure single-node cluster 14 | - role: control-plane 15 | # map TCP ports exposed by pods to host 16 | extraPortMappings: 17 | - containerPort: 30443 18 | hostPort: 8443 19 | - containerPort: 30451 20 | hostPort: 40051 21 | - containerPort: 30551 22 | hostPort: 50051 23 | # replicate following for multi-node cluster with intended number of worker nodes 24 | # - role: workers -------------------------------------------------------------------------------- /deployments/k8s/network-emulation/links.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networkop.co.uk/v1beta1 2 | kind: Topology 3 | metadata: 4 | name: ixia-c-port1 5 | namespace: ixia-c 6 | spec: 7 | links: 8 | - uid: 1 9 | peer_pod: dut 10 | local_intf: eth1 11 | local_ip: 1.1.1.1/24 12 | peer_intf: eth1 13 | peer_ip: 1.1.1.2/24 14 | 15 | --- 16 | 17 | apiVersion: networkop.co.uk/v1beta1 18 | kind: Topology 19 | metadata: 20 | name: ixia-c-port2 21 | namespace: ixia-c 22 | spec: 23 | links: 24 | - uid: 1 25 | peer_pod: dut 26 | local_intf: eth2 27 | local_ip: 2.2.2.1/24 28 | peer_intf: eth2 29 | peer_ip: 2.2.2.2/24 30 | 31 | --- 32 | 33 | apiVersion: networkop.co.uk/v1beta1 34 | kind: Topology 35 | metadata: 36 | name: dut 37 | namespace: ixia-c 38 | spec: 39 | links: 40 | - uid: 1 41 | peer_pod: ixia-c-port1 42 | local_intf: eth1 43 | local_ip: 1.1.1.2/24 44 | peer_intf: eth1 45 | peer_ip: 1.1.1.1/24 46 | - uid: 2 47 | peer_pod: ixia-c-port2 48 | local_intf: eth2 49 | local_ip: 2.2.2.2/24 50 | peer_intf: eth2 51 | peer_ip: 2.2.2.1/24 52 | -------------------------------------------------------------------------------- /deployments/k8s/bases/otg-traffic-port/pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | labels: 5 | app: ixia-c 6 | role: otg-port 7 | name: otg-port 8 | namespace: ixia-c 9 | spec: 10 | containers: 11 | - env: 12 | - name: OPT_LISTEN_PORT 13 | value: "5555" 14 | - name: OPT_NO_PINNING 15 | value: "Yes" 16 | - name: ARG_IFACE_LIST 17 | value: virtual@af_packet,eth0 18 | - name: OPT_NO_HUGEPAGES 19 | value: "Yes" 20 | - name: WAIT_FOR_IFACE 21 | value: "Yes" 22 | image: ixia-c-traffic-engine:latest 23 | imagePullPolicy: IfNotPresent 24 | name: ixia-c-traffic-engine 25 | ports: 26 | - containerPort: 5555 27 | name: zeromq-port 28 | protocol: TCP 29 | livenessProbe: 30 | tcpSocket: 31 | port: zeromq-port 32 | periodSeconds: 5 33 | startupProbe: 34 | tcpSocket: 35 | port: zeromq-port 36 | periodSeconds: 5 37 | failureThreshold: 12 38 | securityContext: 39 | privileged: true 40 | restartPolicy: Always -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Keysight Technologies, Inc. 2021, 2022, 2023 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /deployments/raw-two-arm.yml: -------------------------------------------------------------------------------- 1 | version: '3.9' 2 | services: 3 | controller: 4 | image: ghcr.io/open-traffic-generator/keng-controller:${CONTROLLER_VERSION:-latest} 5 | command: --accept-eula 6 | network_mode: "host" 7 | restart: always 8 | traffic_engine_1: 9 | image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:${TRAFFIC_ENGINE_VERSION:-latest} 10 | network_mode: "host" 11 | restart: always 12 | privileged: true 13 | cpuset: ${CPU_CORES_IFC1:-"0,1,2"} 14 | environment: 15 | - OPT_LISTEN_PORT=${TCP_PORT_IFC1:-5555} 16 | - ARG_IFACE_LIST=virtual@af_packet,${IFC1} 17 | - OPT_NO_HUGEPAGES=Yes 18 | traffic_engine_2: 19 | image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:${TRAFFIC_ENGINE_VERSION:-latest} 20 | network_mode: "host" 21 | restart: always 22 | privileged: true 23 | cpuset: ${CPU_CORES_IFC2:-"0,3,4"} 24 | environment: 25 | - OPT_LISTEN_PORT=${TCP_PORT_IFC2:-5556} 26 | - ARG_IFACE_LIST=virtual@af_packet,${IFC2} 27 | - OPT_NO_HUGEPAGES=Yes 28 | aur: 29 | image: ghcr.io/open-traffic-generator/keng-app-usage-reporter:${AUR_VERSION:-latest} 30 | network_mode: "host" 31 | restart: always 32 | -------------------------------------------------------------------------------- /deployments/k8s/network-emulation/services.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: service-keng-controller 5 | namespace: ixia-c 6 | spec: 7 | ports: 8 | - name: https 9 | port: 8443 10 | protocol: TCP 11 | targetPort: 8443 12 | nodePort: 30443 13 | - name: grpc 14 | port: 40051 15 | protocol: TCP 16 | targetPort: 40051 17 | nodePort: 30451 18 | selector: 19 | role: controller 20 | type: NodePort 21 | 22 | --- 23 | 24 | apiVersion: v1 25 | kind: Service 26 | metadata: 27 | name: service-ixia-c-port1 28 | namespace: ixia-c 29 | spec: 30 | ports: 31 | - name: port-5555 32 | port: 5555 33 | protocol: TCP 34 | targetPort: 5555 35 | - name: port-50071 36 | port: 50071 37 | protocol: TCP 38 | targetPort: 50071 39 | selector: 40 | role: port1 41 | 42 | --- 43 | 44 | apiVersion: v1 45 | kind: Service 46 | metadata: 47 | name: service-ixia-c-port2 48 | namespace: ixia-c 49 | spec: 50 | ports: 51 | - name: port-5555 52 | port: 5555 53 | protocol: TCP 54 | targetPort: 5555 55 | - name: port-50071 56 | port: 50071 57 | protocol: TCP 58 | targetPort: 50071 59 | selector: 60 | role: port2 61 | -------------------------------------------------------------------------------- /docs/resources.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | 3 | 1. [Product page](https://www.keysight.com/us/en/products/network-test/protocol-load-test/keysight-elastic-network-generator.html) 4 | 2. [Data Sheet](https://www.keysight.com/in/en/assets/3122-1455/data-sheets/Elastic-Network-Generator.pdf) 5 | 3. [Documentation](https://ixia-c.dev) 6 | * [Quick Start](https://ixia-c.dev/quick-start/introduction/) 7 | * [User Guide](https://ixia-c.dev/user-guide-introduction/) 8 | * [Developer Guide](https://ixia-c.dev/developer/snappi-constructs/) 9 | * [Reference Guide](https://ixia-c.dev/reference/capabilities/) 10 | * [Releases](https://ixia-c.dev/releases/) 11 | 4. [Open Traffic Generator](https://otg.dev) 12 | * [Model Browser](https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/open-traffic-generator/models/master/artifacts/openapi.yaml&nocors) 13 | * [Clients](https://otg.dev/clients/) 14 | * [Examples](https://otg.dev/examples/otg-examples/) 15 | 5. [OpenConfig](https://openconfig.net/) 16 | * [KNE IxiaTG Controller](https://github.com/openconfig/kne/blob/main/docs/create_topology.md#ixiatg-controller) 17 | * [FeatureProfiles Test Suite](https://github.com/openconfig/featureprofiles) 18 | 6. [Containerlab Ixia-c-one](https://containerlab.dev/manual/kinds/keysight_ixia-c-one/) 19 | -------------------------------------------------------------------------------- /docs/limitations.md: -------------------------------------------------------------------------------- 1 | # Limitations 2 | 3 | * Supported protocol headers are `ethernet`, `ipv4`, `ipv6`, `vlan`, `tcp`, `udp`, `gtpv1`, `gtpv2`, `arp`, `icmp` and `custom`. 4 | * `fixed_packets`, `fixed_seconds`,`continuous` and `burst` are supported for flow duration (fixed number of `burst` is not supported). 5 | * Size of the packet must be a value greater than or equal to 64 bytes. 6 | * Setting random frame size is not supported. 7 | * Only `value`, `values`,`increment` and `decrement` patterns are supported for Protocol Header fields. 8 | * A maximum of `4` increment, decrement and values patterns are supported per flow. 9 | * A maximum of `500K` list entries are supported per list pattern, per flow. 10 | * A maximum of `256 flows` for a given tx-rx port pair is supported. 11 | * Statistics based on `ingress_result_name` is not supported. 12 | * Tx statistics for flow results is not supported. 13 | * Starting or stopping transmit on selected flows is not supported. Pausing flows is not supported. 14 | * `lags`, `devices` and `options` in `Config` are not supported. 15 | * Only `speed`, `promiscuous` and `mtu` settings are supported in `Layer1`. 16 | * In Centos 7+, with Python 2.7+, virtualenv creation fails due to a known limitation 17 | (https://github.com/pypa/virtualenv/issues/1609). It can be avoided by upgrading pip and then 18 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make, via issue or email (open-traffic-generator@googlegroups.com), with the owners of this repository. 4 | 5 | Please note we have a [code of conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions with the project. 6 | 7 | ## Steps to Contribute 8 | 9 | This repo uses GitHub to manage reviews of [pull requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests). 10 | 11 | Should you wish to work on an issue, please claim it first by commenting on the GitHub issue that you want to work on it. This is to prevent duplicated efforts from contributors on the same issue. 12 | 13 | If you have a trivial fix or improvement, go ahead and create a pull request, and submit it for review. 14 | 15 | ## Pull Request Checklist 16 | 17 | * Branch from the main branch and, if needed, rebase to the current main branch before submitting your pull request. If it doesn't merge cleanly with main you may be asked to rebase your changes. 18 | 19 | * Commits should be as small as possible, while ensuring that each commit is correct independently (i.e., each commit should compile and pass tests). 20 | 21 | * If your patch is not getting reviewed or you need a specific person to review it, you can @-reply a reviewer asking for a review in the pull request or a comment. You can also send a message to open-traffic-generator@googlegroups.com. 22 | 23 | * Add tests relevant to the fixed bug or new feature. 24 | -------------------------------------------------------------------------------- /deployments/raw-three-arm-mesh.yml: -------------------------------------------------------------------------------- 1 | version: '3.9' 2 | services: 3 | controller: 4 | image: ghcr.io/open-traffic-generator/keng-controller:${CONTROLLER_VERSION:-latest} 5 | command: --accept-eula 6 | network_mode: "host" 7 | restart: always 8 | traffic_engine_1: 9 | image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:${TRAFFIC_ENGINE_VERSION:-latest} 10 | restart: always 11 | privileged: true 12 | ports: 13 | - "${TCP_PORT_IFC1:-5555}:5555" 14 | cpuset: ${CPU_CORES_IFC1:-"0,1,2"} 15 | environment: 16 | - OPT_LISTEN_PORT=5555 17 | - ARG_IFACE_LIST=virtual@af_packet,eth0 18 | - OPT_NO_HUGEPAGES=Yes 19 | traffic_engine_2: 20 | image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:${TRAFFIC_ENGINE_VERSION:-latest} 21 | restart: always 22 | privileged: true 23 | ports: 24 | - "${TCP_PORT_IFC2:-5556}:5555" 25 | cpuset: ${CPU_CORES_IFC2:-"0,3,4"} 26 | environment: 27 | - OPT_LISTEN_PORT=5555 28 | - ARG_IFACE_LIST=virtual@af_packet,eth0 29 | - OPT_NO_HUGEPAGES=Yes 30 | traffic_engine_3: 31 | image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:${TRAFFIC_ENGINE_VERSION:-latest} 32 | restart: always 33 | privileged: true 34 | ports: 35 | - "${TCP_PORT_IFC3:-5557}:5555" 36 | cpuset: ${CPU_CORES_IFC3:-"0,5,6"} 37 | environment: 38 | - OPT_LISTEN_PORT=5555 39 | - ARG_IFACE_LIST=virtual@af_packet,eth0 40 | - OPT_NO_HUGEPAGES=Yes 41 | aur: 42 | image: ghcr.io/open-traffic-generator/keng-app-usage-reporter:${AUR_VERSION:-latest} 43 | network_mode: "host" 44 | restart: always 45 | -------------------------------------------------------------------------------- /deployments/k8s/bases/otg-controller/pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | labels: 5 | app: ixia-c 6 | role: otg-controller 7 | name: otg-controller 8 | namespace: ixia-c 9 | spec: 10 | containers: 11 | - args: 12 | - --accept-eula 13 | - --debug 14 | image: keng-controller:latest 15 | imagePullPolicy: IfNotPresent 16 | name: keng-controller 17 | ports: 18 | - containerPort: 8443 19 | name: https-port 20 | protocol: TCP 21 | - containerPort: 40051 22 | name: grpc-port 23 | protocol: TCP 24 | livenessProbe: 25 | tcpSocket: 26 | port: https-port 27 | periodSeconds: 5 28 | startupProbe: 29 | tcpSocket: 30 | port: https-port 31 | periodSeconds: 5 32 | failureThreshold: 12 33 | volumeMounts: 34 | - mountPath: /home/ixia-c/controller/config 35 | name: config 36 | readOnly: true 37 | - args: 38 | - -http-server 39 | - https://localhost:8443 40 | - --debug 41 | image: otg-gnmi-server:latest 42 | imagePullPolicy: IfNotPresent 43 | name: otg-gnmi-server 44 | ports: 45 | - containerPort: 50051 46 | name: gnmi-port 47 | protocol: TCP 48 | livenessProbe: 49 | tcpSocket: 50 | port: gnmi-port 51 | periodSeconds: 5 52 | startupProbe: 53 | tcpSocket: 54 | port: gnmi-port 55 | periodSeconds: 5 56 | failureThreshold: 12 57 | restartPolicy: Always 58 | volumes: 59 | - configMap: 60 | defaultMode: 420 61 | name: controller-config 62 | name: config -------------------------------------------------------------------------------- /deployments/k8s/network-emulation/go.mod: -------------------------------------------------------------------------------- 1 | module ipfwd 2 | 3 | go 1.25.0 4 | 5 | require github.com/open-traffic-generator/snappi/gosnappi v1.42.0 6 | 7 | require ( 8 | github.com/Masterminds/semver/v3 v3.4.0 // indirect 9 | github.com/cenkalti/backoff/v5 v5.0.3 // indirect 10 | github.com/felixge/httpsnoop v1.0.4 // indirect 11 | github.com/ghodss/yaml v1.0.0 // indirect 12 | github.com/go-logr/logr v1.4.3 // indirect 13 | github.com/go-logr/stdr v1.2.2 // indirect 14 | github.com/google/uuid v1.6.0 // indirect 15 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect 16 | go.opentelemetry.io/auto/sdk v1.2.1 // indirect 17 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect 18 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect 19 | go.opentelemetry.io/otel v1.38.0 // indirect 20 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect 21 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect 22 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect 23 | go.opentelemetry.io/otel/metric v1.38.0 // indirect 24 | go.opentelemetry.io/otel/sdk v1.38.0 // indirect 25 | go.opentelemetry.io/otel/trace v1.38.0 // indirect 26 | go.opentelemetry.io/proto/otlp v1.7.1 // indirect 27 | golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect 28 | golang.org/x/sys v0.37.0 // indirect 29 | golang.org/x/text v0.30.0 // indirect 30 | google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect 31 | google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect 32 | google.golang.org/grpc v1.77.0 // indirect 33 | google.golang.org/protobuf v1.36.10 // indirect 34 | gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect 35 | gopkg.in/yaml.v2 v2.4.0 // indirect 36 | ) 37 | -------------------------------------------------------------------------------- /mkdocs.md: -------------------------------------------------------------------------------- 1 | # MkDocs How To 2 | 3 | This repo contains the content for the [Ixia-c.dev](https://ixia-c.dev/) web-site. It is built using the [Material](https://squidfunk.github.io/mkdocs-material/getting-started/) theme for [MkDocs](https://www.mkdocs.org/). 4 | 5 | ## Prerequisites 6 | 7 | * Python 3.10+. In the commands below we assume use have `python3` executable. If you have a different name, change accordingly. 8 | 9 | * PIP 10 | 11 | ```Shell 12 | curl -sL https://bootstrap.pypa.io/get-pip.py | python3 - 13 | ``` 14 | 15 | * Virtualenv (recommended) 16 | 17 | ```Shell 18 | pip install virtualenv 19 | ``` 20 | 21 | ## How to install 22 | 23 | 1. Clone this repository and create Python virtual environment 24 | 25 | ```Shell 26 | git clone https://github.com/open-traffic-generator/ixia-c.git --recursive 27 | cd ixia-c 28 | git checkout -b __NEW_BRANCH_NAME__ 29 | python3.10 -m venv venv 30 | source venv/bin/activate 31 | ``` 32 | 33 | 2. Install required modules 34 | 35 | ```Shell 36 | pip3 install -r requirements.txt 37 | ``` 38 | 39 | Update contents in the `docs` directory and verify locally prior to pushing to main branch of this repo on GitHub. Site will automatically update. 40 | 41 | ## How to verify contents locally 42 | 43 | 1. Run the following command to render the content in real-time via a local web server: 44 | 45 | ```sh 46 | mkdocs serve 47 | ``` 48 | 49 | 2. Alternatively, you can render all static html content in the `site` directory: 50 | 51 | ```sh 52 | mkdocs build 53 | ``` 54 | 55 | You can point your browser to `index.html` in the `site` directory to view it. 56 | 57 | ## Submodules 58 | 59 | Parts of the `docs` hierarchy are coming from submodules. To update content of the submodules to the most recent one, use: 60 | 61 | ```Shell 62 | git submodule update --remote 63 | ``` -------------------------------------------------------------------------------- /deployments/k8s/overlays/two-traffic-ports-eth0/gen-test-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | TEST_CONFIG_PATH=test-config.yaml 4 | if [ ! -z ${1} ] 5 | then 6 | TEST_CONFIG_PATH=${1} 7 | fi 8 | 9 | gen_test_const() { 10 | # get pod IPs to be used as source and destination IP in packets 11 | txIp=$(kubectl get pod -n ixia-c otg-port1 -o 'jsonpath={.status.podIP}') 12 | rxIp=$(kubectl get pod -n ixia-c otg-port2 -o 'jsonpath={.status.podIP}') 13 | # send ping to flood arp table and extract gateway MAC 14 | kubectl exec -n ixia-c otg-port1 -c ixia-c-traffic-engine -- ping -c 1 ${rxIp} 15 | gatewayMac=$(kubectl exec -n ixia-c otg-port1 -c ixia-c-traffic-engine -- arp -a | head -n 1 | cut -d\ -f4) 16 | txMac=$(kubectl exec -n ixia-c otg-port1 -c ixia-c-traffic-engine -- ifconfig eth0 | grep ether | sed 's/ */_/g' | cut -d_ -f3) 17 | rxMac=$(kubectl exec -n ixia-c otg-port2 -c ixia-c-traffic-engine -- ifconfig eth0 | grep ether | sed 's/ */_/g' | cut -d_ -f3) 18 | 19 | yml="otg_test_const: 20 | txMac: ${txMac} 21 | rxMac: ${rxMac} 22 | gatewayMac: ${gatewayMac} 23 | txIp: ${txIp} 24 | rxIp: ${rxIp} 25 | " 26 | echo -n "$yml" | sed "s/^ //g" | tee -a ${TEST_CONFIG_PATH} > /dev/null 27 | } 28 | 29 | gen_config_common() { 30 | yml="otg_speed: speed_1_gbps 31 | otg_capture_check: true 32 | otg_iterations: 100 33 | otg_grpc_transport: false 34 | " 35 | echo -n "$yml" | sed "s/^ //g" | tee -a ${TEST_CONFIG_PATH} > /dev/null 36 | } 37 | 38 | gen_test_config() { 39 | yml="otg_host: https://localhost:8443 40 | otg_ports: 41 | - port1 42 | - port2 43 | " 44 | echo -n "$yml" | sed "s/^ //g" | tee ${TEST_CONFIG_PATH} > /dev/null 45 | 46 | gen_config_common 47 | 48 | gen_test_const 49 | } 50 | 51 | gen_test_config -------------------------------------------------------------------------------- /docs/deployments-containerlab.md: -------------------------------------------------------------------------------- 1 | 2 | # Deploy Ixia-c-one using containerlab 3 | 4 | Ixia-c-one is deployed as single-container application by using [containerlab](https://containerlab.dev/quickstart/) that consists of the following services: 5 | 6 | * **containerlab**: Containerlab provides a CLI for orchestrating and managing container-based networking labs. It starts the containers, builds a virtual wiring between them to create lab topologies depending on a user's choice, and manages the labs lifecycle. 7 | * **Ixia-c-one**: Keysight Ixia-c-one is a single-container distribution of Ixia-c, which in turn is Keysight's reference implementation of Open Traffic Generator API. 8 | 9 | Meet the [keysight_ixia-c-one](https://containerlab.dev/manual/kinds/keysight_ixia-c-one) kind! It is available from containerlab [release 0.26](https://containerlab.dev/rn/0.26/#keysight-ixia-c). 10 | * **srl linux**: Nokia SR Linux is a truly open network operating system (NOS), that makes your data center switching infrastructure more scalable, more flexible, and simpler to operate. 11 | 12 | ![ixia-c-one](res/ixia-c-one-aur.drawio.svg) 13 | 14 | ## Install containerlab 15 | 16 | ```sh 17 | # download and install the latest release (may require sudo) 18 | bash -c "$(curl -sL https://get.containerlab.dev)" 19 | ``` 20 | 21 | ## Deploy the topology 22 | 23 | * You can find a sample topology definition in , which consists of Nokia SR Linux and Ixia-c-one nodes that are connected to one-another. 24 | * This consists of a Keysight ixia-c-one node with 2 ports connected to 2 ports on an srl linux node via two point-to-point ethernet links. Both nodes are also connected with their management interfaces to the containerlab docker network. 25 | 26 | ```sh 27 | # After downloading the sample topology file 28 | containerlab deploy --topo ixiac01.clab.yml 29 | ``` 30 | 31 | - After deployment, you are now ready to run a test using the topology. 32 | 33 | ## Run a test 34 | 35 | * Follow this [link](https://containerlab.dev/lab-examples/ixiacone-srl/#execution) to run a test. 36 | 37 | ## Destroy/Remove the topology 38 | 39 | ```sh 40 | # delete a particular topology 41 | containerlab destroy --topo ixiac01.clab.yml 42 | ``` 43 | -------------------------------------------------------------------------------- /docs/tests-uhd400.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | The UHD400T is a high performance, ultra-high density, and highly flexible software defined Tester, for all your next 4 | generation testing needs. It works seamlessly with diverse testbeds like a single Device Under Test, or a network 5 | with multiple devices. 6 | 7 | The UHD400T comes as a 1U rack mount appliance with 16 400GE QSFP-DD ports that provide up to 6.4Tbps 8 | composite throughput. 9 | 10 | The UHD400T is configurable via the Keysight Elastic Network Generator. During the setup phase, the physical ports 11 | on the UHD400T can be configured through a REST API. 12 | 13 | ![UHD](res/UHD400T_front_view.png "UHD400T front view") 14 | 15 | ## VLAN-Port Mapping 16 | 17 | The UHD400T fabric is preconfigured to route the traffic between the trunk port (port 32) and the traffic ports (1-16). 18 | Ports 17-31 are not available for use in the current release. 19 | When the packets arrive at a traffic port, they are encapsulated in a VLAN corresponding to the front panel (see mapping table below) and routed to the trunk port. The process is reversed, when the packets arrive at the trunk port. 20 | 21 | The packets that are encapsulated in a VLAN, are routed to the front panel port corresponding to the VLAN. 22 | The trunk packets that are not VLAN-encapsulated or have a VLAN that is not listed in the following mapping table, will be dropped. 23 | 24 | ![UHD400T](res/system-with-UHD400T.drawio.svg "Example System with UHD400T") 25 | 26 | ### Mapping Table 27 | 28 | | UHD Port | VLAN ID | UHD Port | VLAN ID | 29 | |:--- |:--- |:--- |:--- | 30 | | 1 | 136 | 9 | 320 | 31 | | 2 | 144 | 10 | 312 | 32 | | 3 | 152 | 11 | 304 | 33 | | 4 | 160 | 12 | 296 | 34 | | 5 | 168 | 13 | 288 | 35 | | 6 | 176 | 14 | 280 | 36 | | 7 | 184 | 15 | 272 | 37 | | 8 | 192 | 16 | 264 | 38 | 39 | >Note: 40 | The VLAN tagged interfaces can be created by using the following linux command: 41 | 42 | ```bash 43 | ip link add link name . type vlan id 44 | ``` 45 | For more information, see [UHD400T Getting Started Guide](https://downloads.ixiacom.com/support/downloads_and_updates/public/UHD400T/1.0/1.0.20/UHD400T%20Getting%20Started%20Guide.pdf). 46 | -------------------------------------------------------------------------------- /docs/quick-start/deployment.md: -------------------------------------------------------------------------------- 1 | # Deployment 2 | 3 | Ixia-c is distributed and deployed as a multi-container application that consists of the following services: 4 | 5 | * **controller**: Serves API request from the clients and manages workflow across one or more traffic engines. 6 | * **traffic-engine**: Generates, captures, and processes traffic from one or more network interfaces (on linux-based OS). 7 | * **app-usage-reporter**: (Optional) Collects anonymous usage report from the controller and uploads it to the Keysight Cloud, with minimal impact on the host resources. 8 | 9 | All these services are available as docker images on the [GitHub Open-Traffic-Generator repository](https://github.com/orgs/open-traffic-generator/packages). To use specific versions of these images, see [Ixia-c Releases](../releases.md) . 10 | 11 | ![ixia-c-aur](../res/ixia-c-aur.drawio.svg "ixia-c-aur") 12 | 13 | > Once the services are deployed, [conformance](https://github.com/open-traffic-generator/conformance/blob/main/readme.md) (a collection of [snappi](https://pypi.org/project/snappi/) test scripts and configurations) can be setup to run against Ixia-c. 14 | 15 | ## Deploy Ixia-c using docker-compose 16 | 17 | Deploying multiple services manually (along with the required parameters) is not always applicable in some scenarios. For convenience, the [deployments](../deployments) directory consists of the following `docker-compose` files: 18 | 19 | - `*.yml`: Describes the services for a given scenario and the deployment parameters that are required to start them. 20 | - `.env`: Holds the default parameters, that are used across all `*.yml` files. For example, the name of the interface, the version of docker images, and etc. 21 | 22 | If a concerned `.yml` file does not include certain variables from `.env`, those can then safely be ignored. 23 | Follwoing is the example of a usual workflow, by using `docker-compose`. 24 | 25 | ```sh 26 | # change default parameters if needed; e.g. interface name, image version, etc. 27 | vi deployments/.env 28 | # deploy and start services for community users 29 | docker-compose -f deployments/.yml up -d 30 | # stop and remove services deployed 31 | docker-compose -f deployments/.yml down 32 | ``` 33 | 34 | On most of the systems, `docker-compose` needs to be installed separately even if the docker is already installed. Before you start, ensure that the [docker prerequisites](../prerequisites.md#docker) are met. 35 | 36 | For more information on deployment, see [Deployment Guide](../deployments.md). 37 | -------------------------------------------------------------------------------- /docs/prerequisites.md: -------------------------------------------------------------------------------- 1 | # Ixia-c Prerequisites 2 | 3 | ## System Prerequisites 4 | 5 | ### CPU and RAM 6 | 7 | The minimum memory and cpu requirements for a basic use-case are as follows: 8 | 9 | * `keng-controller`: Each instance requires at least 10m CPU core and 25Mi RAM. 10 | * `ixia-c-traffic-engine`: Each instance requires 200m CPU core per test port, plus one shared CPU core and 60Mi RAM. Generic formula for CPU cores is `1 + 2 * number_of_ports`. 11 | * `ixia-c-protocol-engine`: Each instance requires 200m CPU core and 350Mi RAM per port. 12 | 13 | For more granularity on resource requirements for advanced deployments, see [Resource requirements](reference/resource-requirements.md). 14 | 15 | ### OS and Software 16 | 17 | * x86_64 Linux Distribution (Centos 7+ or Ubuntu 18+ have been tested) 18 | * Docker 19+ (as distributed by ) 19 | * For test-environment, 20 | * Python 3.6+ (with `pip`) or 21 | * Go 1.17+ 22 | 23 | ## Software Prerequisites 24 | 25 | ### Docker 26 | 27 | * Docker Engine (Community Edition) 28 | 29 | ### Python 30 | 31 | * **Ensure that you have `python` and `pip` installed on your system.** 32 | 33 | You may have to use `python3` or `absolute path to python executable` depending on the Python Installation on your system. 34 | 35 | ```sh 36 | python -m pip --help 37 | ``` 38 | 39 | If you do not see a help message, see [pip installation guide](https://pip.pypa.io/en/stable/installing/), . 40 | 41 | * **It is recommended that you use a python virtual environment for development.** 42 | 43 | ```sh 44 | python -m pip install --upgrade virtualenv 45 | # create virtual environment inside `env/` and activate it. 46 | python -m virtualenv env 47 | # on linux 48 | source env/bin/activate 49 | # on windows 50 | env\Scripts\activate on Windows 51 | ``` 52 | 53 | > If you do not want to activate the virtual env, use `env/bin/python` (or `env\scripts\python` on Windows) instead of `python`. 54 | 55 | ## Network Interface Prerequisites 56 | 57 | In order for `ixia-c-traffic-engine` to function, several settings need to be tuned on the host system. They are as follows: 58 | 59 | 1. Ensure that all the existing network interfaces are `Up` and have `Promiscuous` mode enabled. 60 | 61 | * The following example illustrates a sample configured interface `eth1` 62 | 63 | ```sh 64 | # check interface details 65 | ip addr 66 | # configure as required 67 | ip link set eth1 up 68 | ip link set eth1 promisc on 69 | ``` 70 | 71 | 2. (Optional) You need to create the `veth` interface pairs, to deploy the `ixia-c-traffic-engine` against them. 72 | 73 | ```sh 74 | # create veth pair veth1 and veth2 75 | ip link add veth1 type veth peer name veth2 76 | ip link set veth1 up 77 | ip link set veth2 up 78 | ``` 79 | -------------------------------------------------------------------------------- /docs/reference/capabilities.md: -------------------------------------------------------------------------------- 1 | # Supported capabilities 2 | 3 | ## Protocol emulation 4 | 5 | | Feature | OTG model specification | Ixia-c software | IxOS hardware | UHD400T system | Comments | 6 | |---|---|---|---|---|---| 7 | | **BGP(v4/v6)** | Y | Y | Y | Y | | 8 | | v4/v6 Routes | Y | Y | Y | Y | | 9 | | Route Withdraw/Re-advertise | Y | Y | Y | Y | | 10 | | Md5 Authentication | Y | Y | Y | Y | | 11 | | Learned Routes Retrieval | Y | Y | Y | Y | | 12 | | Extended Community | Y | Y | Y | Y | | 13 | | Graceful Restart (Helper and Restarting) | Y | Y | Y | Y | | 14 | | **Static LAG** | Y | Y | Y | N | | 15 | | **LAG with LACP** | Y | Y | Y | N | | 16 | | Protocols/Data over LAG with traffic switch | Y | Y | N | N | | 17 | | **ISIS** | Y | Y | Y | Y | | 18 | | v4/v6 Routes | Y | Y | Y | Y | | 19 | | Learned Routes Retrieval | Y | Y | Y | Y | | 20 | | Simulated Topology | Y | Y | Y | Y | | 21 | | Segment Routing | Y | Y | Y | Y | | 22 | | Multiple ports/adjacencies | Y | N | N | N | | 23 | | **RSVP p2p LSPs (Ingress or Egress)** | Y | Y | Y | N | | 24 | | Srefresh and Bundle extensions | Y | Y | Y | N | | 25 | | **LLDP** | Y | Y | N | Y | | 26 | | Per Port | Y | Y | N | Y | | 27 | | Learned LLDP Neighbors | Y | Y | N | Y | | 28 | | Per LAG member Port | Y | Y | N | N | | 29 | 30 | ## Traffic generation 31 | 32 | | Feature | OTG model specification | Ixia-c software | IxOS hardware | UHD400T system | Comments | 33 | |---|---|---|---|---|---| 34 | | Egress Tracking | Y | Y | Y | N | | 35 | | Imix | Y | Y | Y | N | | 36 | | Dynamic ARP Resolution | Y | Y | Y | Y | | 37 | | Dynamic Frame Size control | Y | Y | Y | N | | 38 | | Dynamic Rate Control | Y | Y | N | N | | 39 | | Multiple Rx Ports and drilldown | Y | Y | Y| N | | 40 | | **Packet headers** | | | | | | 41 | | Vlan | Y | Y | Y | Y | | 42 | | IPv4 | Y | Y | Y | Y | | 43 | | IPv6 | Y | Y | Y | Y | | 44 | | TCP | Y | Y | Y | Y | | 45 | | UDP | Y | Y | Y | Y | | 46 | | MPLS | Y | Y | Y | N | | 47 | | ARP | Y | Y | Y | Y | | 48 | | PPP | Y | Y | Y | N | | 49 | | GRE| Y | Y | Y | N | | 50 | |IGMPv1 | Y | Y | Y | N | | 51 | | ICMP | Y | Y | Y |N | | 52 | | ICMPv6 | Y | Y | Y | N | | 53 | | ETHERNETPAUSE | Y | Y | Y | N | | 54 | | VXLAN | Y | Y | Y | N | | 55 | | PFCPAUSE | Y | N | Y | N | | 56 | | CUSTOM | Y | Y | Y | N | | 57 | 58 | ## Infrastructure 59 | 60 | | Feature | OTG model specification | Ixia-c software | IxOS hardware | UHD400T system | Comments | 61 | |---|---|---|---|---|---| 62 | | Capture (Rx only) | Y | Y | Y | N | | 63 | | Link Down/Up | Y | Y | Y | N | | 64 | | MTU greater than 1500 | Y | Y | Y | N | | 65 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 |

Ixia-c & Elastic Network Generator

2 |

Agile and composable network test system designed for continuous integration

3 | 4 |
5 |
6 |
7 | 8 |
9 |
10 | 19 |
20 |
21 |
22 | 23 | ## Community Edition 24 | 25 | First in its class [Ixia-c Community Edition](quick-start/introduction.md) of the Elastic Network Generator with **BGP emulation and full set traffic capabilities** [limited by scale and performance](licensing.md) is available to anyone without registration and at no cost. 26 | 27 | ## OTG Examples 28 | 29 | Explore [otg-examples](https://otg.dev/examples/otg-examples/) library to get hands-on experience with using Open Traffic Generator and Ixia-c. With a minimum Linux host or VM you can be running your first network data and control plane validation scenarios in minutes. 30 | 31 | ## Key Features 32 | 33 | * Software multi-container application: 34 | * runs on Linux x86 compute, 35 | * includes software traffic generation and protocol emulation capabilities, 36 | * built using DPDK to generate high traffic rates on a single CPU core, 37 | * can control Keysight network test hardware. 38 | * Easily integrates into CI/CD pipelines like GitHub, GitLab, Jenkins. 39 | * Supports test frameworks like Pytest or Golang test. 40 | * Emulates key data center protocols with high scale of sessions and routes: 41 | * capable of leveraging 3rd party libraries to add unsupported packet formats, 42 | * provides patterns to modify common packet header fields to generate millions of unique packets. 43 | * Supports: 44 | * configurable frame sizes, 45 | * rate specification in pps (packets per second) or % line-rate, 46 | * ability to send traffic bursts. 47 | * Statistics: 48 | * per port and per flow, 49 | * tracks flows based on common packet header fields, 50 | * one way latency measurements (min, max, average) on a per flow basis, 51 | * capture packets and write to PCAP or analyze in the test logic. 52 | 53 | ## Copyright notice 54 | 55 | © Copyright Keysight Technologies, Inc. 2021, 2022, 2023 -------------------------------------------------------------------------------- /deployments/k8s/readme.md: -------------------------------------------------------------------------------- 1 | # Deploy Ixia-C in Kubernetes 2 | 3 | This section hosts [kustomize](https://kustomize.io/) manifests for deploying various Ixia-C topologies in Kubernetes cluster. 4 | 5 | ### Prerequisites 6 | 7 | - At least **2 x86 CPU cores**, **7GB RAM** and **30GB Free Hard Disk Space** 8 | - Recommended OS is **Ubuntu 22.04 LTS** release. 9 | - Go **1.20+** 10 | - **Docker Engine** (Community Edition) - Needed when using kind for setting up K8S cluster 11 | 12 | > Please make sure that current working directory is `deployments/k8s`. 13 | 14 | ### Initial Steps 15 | 16 | 1. Clone repository 17 | 18 | ```bash 19 | git clone --recurse-submodules https://github.com/open-traffic-generator/ixia-c.git 20 | cd ixia-c/deployments/k8s 21 | ``` 22 | 23 | 2. Setup a Kubernetes cluster using [kind](https://kind.sigs.k8s.io/) 24 | 25 | ```bash 26 | # install kind 27 | go install sigs.k8s.io/kind@v0.20.0 28 | # create cluster with custom configuration 29 | kind create cluster --config=kind.yaml --wait 30s 30 | # install compatible kubectl 31 | sudo docker cp kind-control-plane:/usr/bin/kubectl /usr/local/bin/kubectl 32 | sudo chmod 0755 /usr/local/bin/kubectl 33 | # ensure all pods are ready 34 | kubectl wait --for=condition=Ready pods --all --all-namespaces 35 | ``` 36 | 37 | 3. (Optional) Load container images to cluster if offline images are preferred 38 | 39 | Images to be used are specified in `components/images/kustomization.yaml`. 40 | 41 | ```bash 42 | yml=components/images/kustomization.yaml 43 | for i in $(seq $(grep -c newName ${yml})) 44 | do 45 | cap=$(grep -A1 -m${i} newName ${yml} | tail -n 2) 46 | img=$(grep -A1 -m${i} newName ${yml} | tail -n 2 | grep newName | cut -d: -f2 | cut -d\ -f2) 47 | img=${img}:$(grep -A1 -m${i} newName ${yml} | tail -n 2 | grep newTag | cut -d\" -f2) 48 | docker pull "${img}" && kind load docker-image "${img}" 49 | done 50 | ``` 51 | 52 | ### Deploy Topology and Run Tests (Stateless traffic on eth0) 53 | 54 | 1. Deploy topology consisting of two Ixia-c port pods and one KENG controller pod 55 | 56 | Topology manifests are kept inside `overlays/two-traffic-ports-eth0` which specifies `port1` and `port2`. 57 | * iptables rule is configured on both ports to drop UDP/TCP packets destined for ports 7000-8000 58 | * number of ports can be increased by adding new port dirs similar to `port1` and using it in rest of the files 59 | 60 | ```bash 61 | # deploy Ixia-c with two ports that only support stateless traffic over eth0 62 | kubectl apply -k overlays/two-traffic-ports-eth0 63 | # ensure all Ixia-c pods are ready 64 | kubectl wait --for=condition=Ready pods --all -n ixia-c 65 | ``` 66 | 67 | 2. Generate test pre-requisites 68 | 69 | The sample test requires `conformance/test-config.yaml` which is auto-generated: 70 | * KENG controller / port endpoints 71 | * common port / flow properties 72 | * values like port pod IPs, gateway MAC on tx port, etc. 73 | 74 | ```bash 75 | overlays/two-traffic-ports-eth0/gen-test-config.sh ../../conformance/test-config.yaml 76 | # check contents 77 | cat ../../conformance/test-config.yaml 78 | ``` 79 | 80 | 3. Run sample test 81 | 82 | The test being run for this specific topology is `conformance/feature/b2b/packet/udp/udp_port_value_eth0_test.go` 83 | 84 | ```bash 85 | cd ../../conformance 86 | CGO_ENABLED=0 go test -v -count=1 -p=1 -timeout 3600s -tags="all" -run="^TestUdpPortValueEth0$" ./... 87 | ``` 88 | -------------------------------------------------------------------------------- /docs/reference/resource-requirements.md: -------------------------------------------------------------------------------- 1 | # Resource requirement 2 | 3 | The minimum memory and cpu requirements for each Ixia-c components are captured in the following table. Kubernetes metrics server has been used to collect the resource usage data. 4 | 5 | The memory represents the minimum working set of memory required. For protocol and traffic engines, it varies depending on the number of co-located ports. For example, multiple ports are added to a 'group' for LAG use-cases, when a single test container has more than one test NIC connected to the DUT. The figures are in Mi or MB per container and do not include shared or cached memory across multiple containers/pods in a system. 6 | 7 | | Component |1 Port (Default)| 2 Port | 4 Port | 6 Port |8 Port| 8 | |:--- |:--- |:--- |:--- |:--- |:--- | 9 | | Protocol Engine | 350 | 420 | 440 | 460 | 480 | 10 | | Traffic Engine | 60 | 70 | 90 | 110 | 130 | 11 | | Controller | 25* | | | | | 12 | | gNMI | 15* | | | | | 13 | 14 | >Note: Controller and gNMI have a fixed minimum memory requirement and is currently not dependent on number of test ports for the topology. 15 | 16 | The cpu resource figures are in millicores. 17 | 18 | | |Protocol | Traffic Engine | Controller Engine | gNMI | 19 | | :--- | :--- | :--- | :--- | :--- | 20 | | Min CPU | 200 | 200 | 10 | 10 | 21 | 22 | ## Minimum and maximum resource usage based on various test configurations 23 | 24 | Depending on the nature of the test run, the memory and cpu resource requirements may vary across all Ixia-c components. The following table captures the memory usage for LAG scenarios with varying numbers of member ports. The minimum value represents the initial memory on topology deployment and the maximum value indicates the peak memory usage during the test run. The values are in Mi or MB. 25 | 26 | | Component | Min/Max | 1 Port | 2 Port | 4 Port | 6 Port | 8 Port | 27 | |:--- |:--- |:--- |:--- |:--- |:--- |:--- | 28 | |Protocol Engine| Max
Min |348
323|423
360|455
360|464
360|492
360| 29 | |Traffic Engine | Max
Min |58
47 | 68
49| 90
49|111
49 |134
49 | 30 | | Controller | Max
Min |21
13 | 21
13 | 23
13 | 24
13 |25
13 | 31 | | gNMI | Max
Min |14
7 | 14
7 | 14
7 | 14
7 | 14
7 | 32 | 33 | Following is the memory usage variation with scaling in the control plane. The variation is on the number of BGP sessions (1K, 5K, and 10K), in a back to back setup. The values are in Mi or MB. 34 | 35 | | Component | Min/Max | 1K | 5K | 10K | 36 | | :---------- | :------- | :------ | :------ | :----- | 37 | | Protocol Engine| Max
Min |516
323|906
323|1367
323| 38 | | Controller | Max
Min |53
12 |149
12 |259
12 | 39 | | gNMI | Max
Min | 7
7 | 7
7 | 7
7 | 40 | 41 | Following is the memory usage variation with scaling in data plane. The variation is on the number of MPLS flows (10, 1K, and 4K), in a back to back setup with labels provided by the RSVP-TE control plane. The values are in Mi or MB. 42 | 43 | | Component | Min/Max | 10 | 1K | 4K | 44 | | :---------- | :------- | :------| :------| :------ | 45 | | Traffic Engine | Max
Min |58
47|59
47|95
47 | 46 | | Controller | Max
Min |18
12|46
12|120
12| 47 | | gNMI | Max
Min |10
7 |17
7 |28
7 | 48 | -------------------------------------------------------------------------------- /deployments/k8s/network-emulation/pods.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | labels: 5 | app: ixia-c 6 | name: controller-config 7 | namespace: ixia-c 8 | data: 9 | config.yaml: | 10 | location_map: 11 | - location: eth1 12 | endpoint: service-ixia-c-port1.ixia-c.svc.cluster.local:5555+service-ixia-c-port1.ixia-c.svc.cluster.local:50071 13 | - location: eth2 14 | endpoint: service-ixia-c-port2.ixia-c.svc.cluster.local:5555+service-ixia-c-port2.ixia-c.svc.cluster.local:50071 15 | 16 | --- 17 | 18 | apiVersion: v1 19 | kind: Pod 20 | metadata: 21 | labels: 22 | app: ixia-c 23 | role: controller 24 | name: keng-controller 25 | namespace: ixia-c 26 | spec: 27 | containers: 28 | - args: 29 | - --accept-eula 30 | - --debug 31 | image: ghcr.io/open-traffic-generator/keng-controller:1.42.0-4 32 | imagePullPolicy: IfNotPresent 33 | name: keng-controller 34 | volumeMounts: 35 | - mountPath: /home/ixia-c/controller/config 36 | name: config 37 | readOnly: true 38 | restartPolicy: Always 39 | volumes: 40 | - configMap: 41 | defaultMode: 420 42 | name: controller-config 43 | name: config 44 | 45 | --- 46 | 47 | apiVersion: v1 48 | kind: Pod 49 | metadata: 50 | labels: 51 | app: ixia-c 52 | role: port1 53 | name: ixia-c-port1 54 | namespace: ixia-c 55 | spec: 56 | containers: 57 | - env: 58 | - name: ARG_IFACE_LIST 59 | value: virtual@af_packet,eth1 60 | - name: OPT_NO_HUGEPAGES 61 | value: "Yes" 62 | - name: OPT_LISTEN_PORT 63 | value: "5555" 64 | - name: ARG_CORE_LIST 65 | value: 1 1 1 66 | image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.8.0.245 67 | imagePullPolicy: IfNotPresent 68 | name: ixia-c-port1-traffic-engine 69 | securityContext: 70 | privileged: true 71 | - env: 72 | - name: INTF_LIST 73 | value: eth1 74 | image: ghcr.io/open-traffic-generator/ixia-c-protocol-engine:1.00.0.488 75 | imagePullPolicy: IfNotPresent 76 | name: ixia-c-port1-protocol-engine 77 | securityContext: 78 | privileged: true 79 | restartPolicy: Always 80 | 81 | --- 82 | 83 | apiVersion: v1 84 | kind: Pod 85 | metadata: 86 | labels: 87 | app: ixia-c 88 | role: port2 89 | name: ixia-c-port2 90 | namespace: ixia-c 91 | spec: 92 | containers: 93 | - env: 94 | - name: ARG_IFACE_LIST 95 | value: virtual@af_packet,eth2 96 | - name: OPT_NO_HUGEPAGES 97 | value: "Yes" 98 | - name: OPT_LISTEN_PORT 99 | value: "5555" 100 | - name: ARG_CORE_LIST 101 | value: 1 1 1 102 | image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.8.0.245 103 | imagePullPolicy: IfNotPresent 104 | name: ixia-c-port2-traffic-engine 105 | securityContext: 106 | privileged: true 107 | - env: 108 | - name: INTF_LIST 109 | value: eth2 110 | image: ghcr.io/open-traffic-generator/ixia-c-protocol-engine:1.00.0.488 111 | imagePullPolicy: IfNotPresent 112 | name: ixia-c-port2-protocol-engine 113 | securityContext: 114 | privileged: true 115 | restartPolicy: Always 116 | 117 | --- 118 | 119 | apiVersion: v1 120 | kind: Pod 121 | metadata: 122 | labels: 123 | app: ixia-c 124 | role: dut 125 | name: dut 126 | namespace: ixia-c 127 | spec: 128 | containers: 129 | - image: ubuntu:22.04 130 | imagePullPolicy: IfNotPresent 131 | name: dut-ubuntu 132 | command: 133 | - "sleep" 134 | - "infinity" 135 | restartPolicy: Always 136 | -------------------------------------------------------------------------------- /docs/quick-start/introduction.md: -------------------------------------------------------------------------------- 1 | ## What is Ixia-c ? 2 | 3 | - A modern, powerful and **API-driven** traffic generator designed to cater to the needs of hyper-scalers, network hardware vendors and hobbyists alike. 4 | 5 | - **Free for basic use-cases** and distributed / deployed as a multi-container application consisting primarily of a [controller](https://github.com/orgs/open-traffic-generator/packages/container/package/keng-controller), a [traffic-engine](https://github.com/orgs/open-traffic-generator/packages/container/package/Ixia-c-traffic-engine) and a [protocol-engine](https://github.com/orgs/open-traffic-generator/packages/container/package/Ixia-c-protocol-engine). 6 | 7 | - As a reference implementation of [Open Traffic Generator API](https://github.com/open-traffic-generator/models), supports client SDKs in various languages, most prevalent being [snappi](https://github.com/open-traffic-generator/snappi) (Python SDK) and [gosnappi](https://github.com/open-traffic-generator/snappi/tree/main/gosnappi). 8 | 9 |

10 | Ixia-c deployment for two-arm test with DUT 11 |

12 | 13 | ## Quick Start 14 | 15 | Please ensure that following prerequisites are met by the setup: 16 | 17 | * At least **2 x86_64 CPU cores** and **7GB RAM**, preferably running **Ubuntu 22.04 LTS** OS 18 | * **Python 3.8+** (and **pip**) or **Go 1.19+** 19 | * **Docker Engine** (Community Edition) 20 | 21 | 22 | ### 1. Deploy Ixia-c 23 | 24 | ```bash 25 | # clone this repository 26 | git clone --recurse-submodules https://github.com/open-traffic-generator/Ixia-c.git && cd Ixia-c 27 | 28 | # create a veth pair and deploy Ixia-c containers where one traffic-engine is bound 29 | # to each interface in the pair, and controller is configured to figure out how to 30 | # talk to those traffic-engine containers 31 | cd conformance && ./do.sh topo new dp 32 | ``` 33 | 34 | ### 2. Setup and run standalone test using [snappi](https://github.com/open-traffic-generator/snappi) or [gosnappi](https://github.com/open-traffic-generator/snappi/tree/main/gosnappi) 35 | 36 | ```bash 37 | # change dir to conformance if you haven't already 38 | cd conformance 39 | 40 | # setup python virtual environment and install dependencies 41 | ./do.sh prepytest 42 | 43 | # run standalone snappi test that configures and sends UDP traffic 44 | # upon successful run, flow metrics shall be printed on console 45 | ./do.sh pytest examples/test_quickstart.py 46 | 47 | # optionally, go equivalent of the test can be run like so 48 | ./do.sh gotest examples/quickstart_test.go 49 | ``` 50 | 51 | > Checkout the contents of [test_quickstart.py](https://github.com/open-traffic-generator/conformance/blob/22563e20fe512ef13baf44c1bc69bc59f87f6c25/examples/test_quickstart.py) and equivalent [quickstart_test.go](https://github.com/open-traffic-generator/conformance/blob/22563e20fe512ef13baf44c1bc69bc59f87f6c25/examples/quickstart_test.go) for quick explanation on test steps 52 | 53 | ### 3. Optionally, run test using [curl](https://curl.se/) 54 | 55 | We can also pass equivalent **JSON configuration** directly to **controller**, just by using **curl**. 56 | The description of each node in the configuration is detailed in self-updating [online documentation](https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/open-traffic-generator/models/v0.13.0/artifacts/openapi.yaml). 57 | 58 | 59 | ```bash 60 | # push traffic configuration 61 | curl -skL https://localhost:8443/config -H "Content-Type: application/json" -d @conformance/examples/quickstart_config.json 62 | 63 | # start transmitting configured flows 64 | curl -skL https://localhost:8443/control/state -H "Content-Type: application/json" -d @conformance/examples/quickstart_control.json 65 | 66 | # fetch flow metrics 67 | curl -skL https://localhost:8443/monitor/metrics -H "Content-Type: application/json" -d @conformance/examples/quickstart_metrics.json 68 | ``` 69 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Ixia-c & Elastic Network Generator Documentation 2 | repo_url: https://github.com/open-traffic-generator/ixia-c 3 | repo_name: ixia-c 4 | edit_uri: "" 5 | theme: 6 | name: material 7 | logo: assets/logo.png 8 | favicon: assets/favicon.png 9 | font: 10 | text: Arial 11 | palette: 12 | # Palette toggle for light mode 13 | - scheme: ks-light 14 | media: "(prefers-color-scheme: light)" 15 | toggle: 16 | icon: material/toggle-switch 17 | name: Switch to dark mode 18 | 19 | # Palette toggle for dark mode 20 | - scheme: ks-dark 21 | media: "(prefers-color-scheme: dark)" 22 | toggle: 23 | icon: material/toggle-switch-off-outline 24 | name: Switch to light mode 25 | features: 26 | - navigation.tabs 27 | - navigation.tabs.sticky 28 | - navigation.instant 29 | - navigation.tracking 30 | - navigation.top 31 | extra_css: 32 | - stylesheets/extra.css 33 | markdown_extensions: 34 | - attr_list 35 | - tables 36 | - admonition 37 | - pymdownx.details 38 | - pymdownx.highlight: 39 | anchor_linenums: true 40 | - pymdownx.inlinehilite 41 | - pymdownx.snippets 42 | - pymdownx.superfences 43 | extra: 44 | analytics: 45 | provider: google 46 | property: G-L42048L6R5 47 | social: 48 | - icon: fontawesome/brands/github 49 | link: https://github.com/open-traffic-generator 50 | - icon: fontawesome/brands/slack 51 | link: https://ixia-c.slack.com 52 | # Page tree 53 | nav: 54 | - Home: 55 | - Overview: index.md # Needs re-writing as a landing page 56 | # - FAQ: faq.md # Review if there are any valuable items left 57 | - Resources: resources.md 58 | - EULA: eula.md # Updated to use www.keysight.com/find/sweula 59 | - Quick Start: 60 | - Introduction: quick-start/introduction.md # Now goes as Ixia-c Quick Start. Add a paragraph why 61 | # - Deployment: quick-start/deployment.md # Link to deployment dir is broken. Need a compose file in text. Need to move to docker compose later 62 | # - Sample test: quick-start/sample-test.md # Empty - otgen example or hello snappi?. See "clients" in UG Intro 63 | - First script: developer/hello-snappi.md # Took from Developer Guide 64 | - User Guide: 65 | - Introduction: user-guide-introduction.md # Update images. Ixia-c link leads to empty page 66 | - Prerequisites: prerequisites.md # Make clear when you need Python. Network Int Prereqs - do we need this at all? 67 | - Deployment: 68 | - Ixia-c: deployments.md # All deployments are via links, easy to miss. Do we make this top-level for Ixia-c/UHD/HW? 69 | - UHD400T: tests-uhd400.md # This is UHD400 intro. Not deployment, not scripts. Need to align with HW 70 | - IxOS Hardware: tests-chassis-app.md # This this HW deployment, there is no scripts (and likely should not be) 71 | # - Use cases: usecases.md # Remove for now, rethink what is this later 72 | - Integrations: integrated-environments.md # A strange mix of otg-examples and clab/kne. Move Clab/KNE deployments here 73 | - Limitations: limitations.md # Align with the DS, clarify if this is for Ixia-c/UHD/HW 74 | - Troubleshooting: troubleshooting.md # Move how to see logs from Deployment here 75 | - Licensing: licensing.md # Update from otg-examples 76 | - Developer Guide: # This section is not ready yet for publishing 77 | # - Introduction: developer/introduction.md # Take from otg.dev? 78 | - Python with snappi: developer/snappi-constructs.md # Cleanup TBD at the end 79 | - Go with gosnappi: developer/snappi-install.md # Split into python and go. Rename as sample scripts? 80 | - Contributing: contribute.md # Move to Developer guide 81 | - Reference Guide: 82 | - Capabilities: reference/capabilities.md 83 | - Resource requirements: reference/resource-requirements.md 84 | - Licensing: reference/licensing.md 85 | - Releases: 86 | - Releases: releases.md 87 | - Announcements: news.md # Check if autogenerated. If yes, see how to merge with releases 88 | - Support: support.md 89 | -------------------------------------------------------------------------------- /docs/user-guide-introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | [Keysight Elastic Network Generator](https://www.keysight.com/us/en/products/network-test/protocol-load-test/keysight-elastic-network-generator.html) is an agile, lightweight, and composable network test software designed for Continuous Integration. It supports vendor neutral Open Traffic Generator models and APIs, integrates with several network emulation platforms, and drives a range of Keysight’s Network Infrastructure Test software products, hardware load modules and appliances. 3 | 4 | The Elastic Network Generator software runs in Docker-based containerized environments and emulates key data center control plane protocols while also sending data plane traffic. It has a modern architecture based on micro-services and open-source interfaces and is designed for very fast automated test scenario execution. All of these characteristics enable robust validation of data center networks to deliver top quality of experience. 5 | 6 | ## Components 7 | 8 | Keysight Elastic Network Generator provides an abstraction over various test port implementations – 9 | Ixia-c software, UHD400T white-box and purpose-built IxOS hardware. A test program written in Open Traffic Generator API can be run using any of the supported test port types without modifications. 10 | 11 | ![Test Port Abstraction via OTG](res/otg-keng-labels-on-white.drawio.svg) 12 | 13 | The main components of KENG are: 14 | 15 | | Component | Description | 16 | | ------------- | ------------- | 17 | | [Test program](https://otg.dev/clients/) | Script or other executable that contains the code that defines the test processes. | 18 | | [OTG](https://otg.dev) | Open Traffic Generator, an evolving API specification that defines the components of a traffic generator such as: test ports (virtual or physical), emulated devices, traffic flows, and statistics and capture capability. | 19 | | [Elastic Network Generator](https://www.keysight.com/us/en/products/network-test/protocol-load-test/keysight-elastic-network-generator.html) | Controller that manages the flow of commands from the test program to the traffic generation device (virtual or physical) and the flow of results from the device to the test program. | 20 | | [Ixia-c](tests-ixia-c.md) | Containerized software traffic generator. | 21 | | [UHD400T](tests-uhd400.md) | Composable test ports based on line-rate white-box switch hardware traffic generator and Ixia-c protocol emulation software. | 22 | | [IxOS Hardware](tests-chassis-app.md) | Keysight Novus or AresONE high-performance network test hardware running IxOS. | 23 | 24 | ## Clients 25 | 26 | To successfully use an OTG-based Traffic Generator, you need to be able to execute the following tasks over the OTG API: 27 | 28 | * Prepare a Configuration and apply it to a Traffic Generator 29 | * Control states of the configured objects like Protocols or Traffic Flows 30 | * Collect and analyze Metrics reported by the Traffic Generator 31 | 32 | It is a job of an OTG Client to perform these tasks by communicating with a Traffic Generator via the OTG API. There are different types of such clients, and the choice between them depends on how and where you want to use a Traffic Generator. 33 | 34 | There are multiple ways to communicate with KENG through the OTG API: 35 | 36 | | Method | Description | 37 | | ------------- | ------------- | 38 | | otgen | A command-line tool that is an easy way to get started | 39 | | snappi | A library that makes it easy create test programs in Python or Go | 40 | | direct REST or gRPC calls | An alternative to using snappi | 41 | | custom OTG client | Custom OTG client applications | 42 | 43 | 44 | ## OTG Examples 45 | 46 | [OTG examples](https://github.com/open-traffic-generator/otg-examples) repository is a great way to get started with [Open Traffic Generator API](https://otg.dev/). It features a collection of software-only network labs ranging from very simple to more complex. To setup the network labs in software, use the containerized or virtualized NOS images. 47 | 48 | -------------------------------------------------------------------------------- /docs/troubleshooting.md: -------------------------------------------------------------------------------- 1 | # Troubleshooting 2 | 3 | This section explains the troubleshooting scenarios for different environments. 4 | 5 | ## OTG hardware environment 6 | 7 | **The test fails while it is configuring OTG ports**: This situation may arise for various reasons. For example, the port ownership is not cleared properly by the previous test, the OTG port went to a bad state, and etc. The course of action in such scenarios can be as follows: 8 | 9 | * Manually clear the ownership of the port. 10 | * Reboot the chassis ports. 11 | * Restart the docker containers. 12 | * Use `docker compose` or `docker-compose` to turn the containers down and up. 13 | * Execute the following commands from the directory where you have kept the docker-compose.yaml file. 14 | 15 | ```sh 16 | docker-compose down 17 | ``` 18 | 19 | ```sh 20 | docker-compose up -d 21 | ``` 22 | 23 | **Configuration is failing port-speed mismatch**: In this scenario, the OTG port configuration will also fail due to the speed mismatch between the DUT port and the chassis port. 24 | To fix this error, do the following: 25 | 26 | * Adjust the DUT port speed to the default port speed of the chassis port. 27 | * Reboot the chassis ports. 28 | * Execute the test. 29 | 30 | **Test failed to take port ownership**: This error is often obvious from the message that is displayed on the console "Failed to take ownership of the following ports". This situation may occur if the previous test did not clear the ownership or someone else is already owning the port. You can go to the chassis UI and clear the port ownership manually by force. 31 | 32 | ![clearOwnership](res/clearOwnership.PNG "Clear port ownership") 33 | 34 | Execute the actions in the following order: 35 | 36 | * Clear ownership 37 | * Reboot ports 38 | 39 | **Error while starting the protocols**: This error can occur if the ports are in a bad state or if you have ignored some errors that have occurred earlier, when you started the protocol engine. 40 | The error messages may look like: 41 | 42 | * Error occurred while starting protocol on the protocol ports: 43 | Unable to find type: 44 | `Ixia.Aptixia.Cpf.pcpu.IsisSRGBRangeSubObjectsPCPU` 45 | 46 | * Error occurred while starting protocol on the protocol ports: `GetPortSession()` is NULL. 47 | 48 | In this situation, a quick solution is to reboot the ports and restart the docker containers, by following the steps that are described earlier. 49 | 50 | >Note: 51 | In summary, clearing the ownership, rebooting the ports, and restarting the containers may resolve many of your problems regarding the ATE port configuration error. 52 | 53 | **OTG API call failed similarly like the start protocol, due to "context deadline exceeded" error**: You can increase the timeout deadline by changing the value of the **timeout** parameter of the ATE in the binding file. The default value is 30 (in seconds). You can increase it as per your setup. 54 | 55 | ```sh 56 | # This option specific to OTG over Ixia-HW. 57 | otg { 58 | target: "127.0.0.1:40051" # Change this to the Ixia-c-grpc server endpoint. 59 | insecure: true 60 | timeout: 120 61 | } 62 | ``` 63 | 64 | >Note: 65 | After this change, do not forget to restart the containers and reboot the hardware ports. 66 | 67 | ## KNE environment 68 | 69 | **Topology creation failures for Ixia-C pods**: This error can occur for multiple reasons: 70 | 71 | * A mismatch in the Ixia-c build versions and the older Operator that is in use. To deploy the correct versions as per the releases, see "". 72 | * The minimum resource requirement is not met. 73 | * An older version of KNE is being used in the client. To update KNE to a newer release, see "" and deploy the topology. 74 | 75 | **Test fails due to timeout**: This error occurs when the test has faced a timeout. By default, the timeout is 10m. You can increase this limit to "-timeout 20m" or can ensure that all the services are reachable for the test to connect and run. 76 | 77 | **Test fails at set config**: This error occurs if the configuration is not proper. For example, mistake in the flow configuration, BGP LI flag is not enabled but `GetStates` is called, and etc. You can correct the configuration and run the test again. 78 | 79 | ## UHD environment 80 | 81 | **Test may not run**: This error can occur for multiple reasons: 82 | 83 | * A mismatch in the version of the rustic containers and the controller that is in use. Ensure that they are compatible. 84 | * The Rustic containers (that are deployed) may not be reachable. There are rare cases when you observe that even if the container is running, the exposed port may have gone corrupt. In such scenarios, the only solution is to redeploy the docker containers. 85 | * The UHD ports may not be responsive. When the rustic container is ready, ensure that the UHD ports are up. For this, refer to the port-api-service that is provided in the [UHD docs](tests-uhd400.md#vlan-port-mapping). 86 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | env: 4 | PYTHON_VERSION: "3.8" 5 | GO_VERSION: "1.23" 6 | 7 | on: 8 | push: 9 | 10 | jobs: 11 | examples_curl: 12 | runs-on: ubuntu-22.04 13 | steps: 14 | - name: Checkout source 15 | uses: actions/checkout@v3 16 | with: 17 | submodules: true 18 | - name: Setup docker 19 | uses: docker-practice/actions-setup-docker@master 20 | - name: Deploy Ixia-C 21 | run: | 22 | sed -n '58,61p' readme.md > deploy.sh 23 | sh deploy.sh 24 | - name: Setup and run tests 25 | run: | 26 | sed -n '90,97p' readme.md > test.sh 27 | sh test.sh 28 | - name: Get container logs 29 | if: always() 30 | run: | 31 | cd conformance && ./do.sh topo logs 32 | - name: Archive logs 33 | if: always() 34 | uses: actions/upload-artifact@v4 35 | with: 36 | name: examples_curl 37 | path: | 38 | conformance/logs 39 | 40 | examples_go_py: 41 | runs-on: ubuntu-22.04 42 | steps: 43 | - name: Checkout source 44 | uses: actions/checkout@v3 45 | with: 46 | submodules: true 47 | - name: Setup docker 48 | uses: docker-practice/actions-setup-docker@master 49 | - name: Deploy Ixia-C 50 | run: | 51 | sed -n '58,61p' readme.md > deploy.sh 52 | sh deploy.sh 53 | - name: Setup Python 54 | uses: actions/setup-python@v4 55 | with: 56 | python-version: ${{ env.PYTHON_VERSION }} 57 | - name: Setup Go 58 | uses: actions/setup-go@v3 59 | with: 60 | go-version: ${{ env.GO_VERSION }} 61 | - name: Setup and run tests 62 | run: | 63 | sed -n '67,78p' readme.md > test.sh 64 | sh test.sh 65 | - name: Get container logs 66 | if: always() 67 | run: | 68 | cd conformance && ./do.sh topo logs 69 | - name: Archive logs 70 | if: always() 71 | uses: actions/upload-artifact@v4 72 | with: 73 | name: examples_go_py 74 | path: | 75 | conformance/logs 76 | 77 | deployments_k8s: 78 | runs-on: ubuntu-22.04 79 | steps: 80 | - name: Checkout source 81 | uses: actions/checkout@v3 82 | with: 83 | submodules: true 84 | - name: Setup docker 85 | uses: docker-practice/actions-setup-docker@master 86 | - name: Setup Go 87 | uses: actions/setup-go@v3 88 | with: 89 | go-version: ${{ env.GO_VERSION }} 90 | - name: Setup Cluster 91 | run: | 92 | cd deployments/k8s 93 | sed -n '26,34p' readme.md > setup-cluster.sh 94 | sh setup-cluster.sh 95 | - name: Download images 96 | run: | 97 | cd deployments/k8s 98 | sed -n '42,49p' readme.md > download-images.sh 99 | sh download-images.sh 100 | - name: Setup Pods and Services 101 | run: | 102 | cd deployments/k8s 103 | sed -n '61,64p' readme.md > setup-pods-services.sh 104 | sh setup-pods-services.sh 105 | - name: Setup tests 106 | run: | 107 | cd deployments/k8s 108 | sed -n '75,77p' readme.md > setup-tests.sh 109 | sh setup-tests.sh 110 | - name: Run tests 111 | run: | 112 | cd deployments/k8s 113 | sed -n '85,86p' readme.md > run-tests.sh 114 | sh run-tests.sh 115 | 116 | deployments_k8s_network_emulation: 117 | runs-on: ubuntu-22.04 118 | steps: 119 | - name: Checkout source 120 | uses: actions/checkout@v3 121 | with: 122 | submodules: true 123 | - name: Setup docker 124 | uses: docker-practice/actions-setup-docker@master 125 | - name: Setup Go 126 | uses: actions/setup-go@v3 127 | with: 128 | go-version: ${{ env.GO_VERSION }} 129 | - name: Setup Cluster 130 | run: | 131 | sed -n '49,60p' deployments/k8s/network-emulation/readme.md > setup-cluster.sh 132 | sh setup-cluster.sh 133 | - name: Download images 134 | run: | 135 | sed -n '66,91p' deployments/k8s/network-emulation/readme.md > download-images.sh 136 | sh download-images.sh 137 | - name: Setup Meshnet 138 | run: | 139 | sed -n '97,105p' deployments/k8s/network-emulation/readme.md > setup-meshnet.sh 140 | sh setup-meshnet.sh 141 | - name: Setup Interfaces 142 | run: | 143 | sed -n '113,118p' deployments/k8s/network-emulation/readme.md > setup-interfaces.sh 144 | sh setup-interfaces.sh 145 | - name: Setup Pods and Services 146 | run: | 147 | sed -n '124,131p' deployments/k8s/network-emulation/readme.md > setup-pods-services.sh 148 | sh setup-pods-services.sh 149 | - name: Setup and run tests 150 | run: | 151 | sed -n '141,143p' deployments/k8s/network-emulation/readme.md > test.sh 152 | sh test.sh 153 | - name: Cleanup 154 | run: | 155 | sed -n '153,157p' deployments/k8s/network-emulation/readme.md > cleanup.sh 156 | sh cleanup.sh -------------------------------------------------------------------------------- /notes.md: -------------------------------------------------------------------------------- 1 | ### Build Details 2 | 3 | | Component | Version | 4 | |-------------------------------|---------------| 5 | | Open Traffic Generator API | [1.42.0](https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/open-traffic-generator/models/v1.42.0/artifacts/openapi.yaml) | 6 | | snappi | [1.42.0](https://pypi.org/project/snappi/1.42.0) | 7 | | gosnappi | [1.42.0](https://pkg.go.dev/github.com/open-traffic-generator/snappi/gosnappi@v1.42.0) | 8 | | keng-controller | [1.42.0-4](https://github.com/orgs/open-traffic-generator/packages/container/package/keng-controller) | 9 | | ixia-c-traffic-engine | [1.8.0.245](https://github.com/orgs/open-traffic-generator/packages/container/package/ixia-c-traffic-engine) | 10 | | keng-app-usage-reporter | [0.0.1-52](https://github.com/orgs/open-traffic-generator/packages/container/package/keng-app-usage-reporter) | 11 | | ixia-c-protocol-engine | [1.00.0.488](https://github.com/orgs/open-traffic-generator/packages/container/package/ixia-c-protocol-engine) | 12 | | keng-layer23-hw-server | [1.42.0-4](https://github.com/orgs/open-traffic-generator/packages/container/package/keng-layer23-hw-server) | 13 | | keng-operator | [0.3.34](https://github.com/orgs/open-traffic-generator/packages/container/package/keng-operator) | 14 | | otg-gnmi-server | [1.42.4](https://github.com/orgs/open-traffic-generator/packages/container/package/otg-gnmi-server) | 15 | | ixia-c-one | [1.42.0-4](https://github.com/orgs/open-traffic-generator/packages/container/package/ixia-c-one/) | 16 | | UHD400 | [1.5.10](https://downloads.ixiacom.com/support/downloads_and_updates/public/UHD400/1.5/1.5.10/artifacts.tar) | 17 | 18 | 19 | ### Release Feature(s): 20 | * Ixia-C, UHD400 & Ixia Chassis & Appliances(Novus, AresOne): Support added for BGP Monitoring Protocol (BMP). [details](https://github.com/open-traffic-generator/models/pull/427) 21 | ```go 22 | p1 := config.Ports().Add().SetName("p1").SetLocation("...") 23 | device := config.Devices().Add().SetName("p1.dev1") 24 | ... 25 | bmpIntf := device.Bmp().Ipv4Interfaces().Add() 26 | bmpIntf.SetIpv4Name("p1.dev1.eth1.ipv4") 27 | 28 | bmpServer := bmpIntf.Servers().Add() 29 | bmpServer.SetName(device.Name()+".bmp") 30 | bmpServer.SetClientIp("1.1.1.1") 31 | // To control which TCP port on which to accept requests from DUT BMP Client. 32 | bmpServer.Connection().Passive().SetListenPort(10123) 33 | 34 | //To store all routes 35 | //bmpServer.PrefixStorage().Ipv4Unicast().Store() 36 | 37 | //Store specifically needed routes 38 | discard := bmpServer.PrefixStorage().Ipv4Unicast().Discard() 39 | discard.Exceptions().Add(). 40 | SetIpv4Prefix("172.16.0.0"). 41 | SetPrefixLength(16) 42 | 43 | //Store all IPv6 prefixes 44 | // bmpServer.PrefixStorage().Ipv6Unicast().Store() 45 | 46 | //Store subset of IPv6 prefixes 47 | v6discard := bmpServer.PrefixStorage().Ipv6Unicast().Discard() 48 | v6discard.Exceptions().Add(). 49 | SetIpv6Prefix("172:16:0:1::"). 50 | SetPrefixLength(64) 51 | 52 | //To get BMP Metrics: 53 | reqMetrics := gosnappi.NewMetricsRequest() 54 | reqMetrics.BmpServer() 55 | bmpMetrics, err := client.Api().GetMetrics(reqMetrics) 56 | ... 57 | 58 | // To get BMP State info ( the per peer stats/prefixes information sent by BMP Client) 59 | reqStates := gosnappi.NewStatesRequest() 60 | reqStates.BmpServers() 61 | bmpState, err := client.Api().GetStates(reqStates) 62 | ``` 63 | - gNMI support added to fetch metics and states of BGP Monitoring Protocol (BMP) [models-yang](https://github.com/open-traffic-generator/models-yang/blob/main/artifacts/open-traffic-generator-bmp-server.txt). 64 | 65 | ```gNMI 66 | // metrics 67 | bmp-servers/bmp-server[name=*]/state/counters 68 | 69 | // states 70 | bmp-servers/bmp-server[name=*]/state/peer-state-database/peers 71 | ``` 72 | 73 | ### Known Issues 74 | * Ixia Chassis & Appliances(Novus, AresOne): If `keng-layer23-hw-server` version is upgraded/downgraded, the ports which will be used from this container must be rebooted once before running the tests. 75 | * Ixia Chassis & Appliances(Novus, AresOne): `StartProtocols`/`set_control_state.protocol.all.start` can get stuck till the time all DHPCv4/v6 clients receive the leased IPv4/v6 addresses from the DHCPv4/v6 server/relay agent. This may result in getting `"context deadline exceeded"` error in the test program. 76 | * UHD400: Packets will not be transmitted if `flows[i].rate.pps` is less than 50. 77 | * UHD400: `values` for fields in flow packet headers can be created with maximum length of 1000 values. If larger set of values are required for a field which are random, please use `random` instead of `values`. 78 | * Ixia-C: Flow Tx is incremented for flow with tx endpoints as LAG, even if no packets are sent on the wire when all active links of the LAG are down. 79 | * Ixia-C: The metric `loss` in flow metrics is currently not supported. 80 | * Ixia-C: When flow transmit is started, transmission will be restarted on any existing flows already transmitting packets. -------------------------------------------------------------------------------- /docs/tests-chassis-app.md: -------------------------------------------------------------------------------- 1 | # Ixia Chassis/Appliances 2 | This section describes how to use KENG with Keysight's Ixia hardware chassis. 3 | 4 | **Prerequisites** 5 | 6 | To run KENG tests with Ixia hardware, the following pre-requisites must be satisfied: 7 | 8 | - You must have access to Keysight Elastic Network Generator (KENG) images and a valid KENG license. 9 | - For information on how to deploy and activate a KENG license, see the Licensing section of the User Guide. 10 | - The test hardware must be Keysight Ixia Novus or AresOne [Network Test Hardware](https://www.keysight.com/us/en/products/network-test/network-test-hardware.html) with [IxOS](https://support.ixiacom.com/ixos-software-downloads-documentation) 9.20 Patch 4 or higher. 11 | **NOTE:** Currently, only Linux-based IxOS platforms are supported with KENG. 12 | - There must be physical link connectivity between the test ports on the Keysight Ixia Chassis and the devices under test (DUTs). 13 | - You must have a Linux host or virtual machine (VM) with sudo permissions and Docker support. 14 | 15 | Below is an example of deploying an Ubuntu VM otg using [multipass](https://multipass.run/). You can deploy using the means that you are most familiar with. 16 | 17 | `multipass launch 22.04 -n otg -c4 -m8G -d32G` 18 | 19 | `multipass shell otg` 20 | 21 | - [Docker](https://docs.docker.com/engine/install/ubuntu/). Depending on your Linux distribution, follow the steps outlined at one of the following URLs: 22 | - [Ubuntu](https://docs.docker.com/engine/install/ubuntu/) 23 | - [Debian](https://docs.docker.com/engine/install/debian/) 24 | - [CentOS](https://docs.docker.com/engine/install/centos/) 25 | 26 | After docker is installed, add the current user to the docker group: 27 | 28 | `sudo usermod -aG docker $USER` 29 | 30 | - Python3 (version 3.9 or higher), pip and virtualenv 31 | 32 | Use the following command to install Python, pip, and virtualenv: 33 | 34 | `sudo apt install python3 python3-pip python3.10-venv -y` 35 | 36 | - [Go](https://go.dev/dl/) version 1.19 or later, if gRPC or gNMI API access is needed. 37 | 38 | Use the following command to install Go: 39 | 40 | `sudo snap install go --channel=1.19/stable --classic` 41 | 42 | - git and envsubst commands (typically installed by default) 43 | 44 | Use the following command to install git and envsubst if they are not already installed: 45 | 46 | `sudo apt install git gettext-base -y` 47 | 48 | **Deployment Layout** 49 | 50 | The image below shows a complete topology of a KENG test environment. 51 | 52 | To run tests with KENG, the tests must be written using the OpenTrafficGenerator (OTG) API. 53 | 54 | Telemetry is also supported using gNMI APIs. 55 | 56 | If KENG is deployed successfully, the services shown in the block labeled 'Keysight Elastic Network Generator' will be running. 57 | 58 | KENG services interact with the Keysight Ixia hardware chassis to configure protocols and data traffic. 59 | 60 | ![ ](res/hw-server.drawio.svg) 61 | 62 | **Deploying KENG** 63 | 64 | The Docker Compose tool provides a convenient way to deploy KENG services. 65 | 66 | Tests cannot be run until KENG services are deployed and running. 67 | 68 | The following procedure shows an example of how to deploy using Docker Compose. 69 | 70 | 71 | 1. Copy the contents shown below into a `compose.yaml` file. 72 | 73 | 74 | 75 | ``` 76 | services: 77 | keng-controller: 78 | image: ghcr.io/open-traffic-generator/keng-controller:1.42.0-4 79 | restart: always 80 | depends_on: 81 | keng-layer23-hw-server: 82 | condition: service_started 83 | command: 84 | - "--accept-eula" 85 | - "--debug" 86 | - "--keng-layer23-hw-server" 87 | - "keng-layer23-hw-server:5001" 88 | ports: 89 | - "40051:40051" 90 | logging: 91 | driver: "local" 92 | options: 93 | max-size: "100m" 94 | max-file: "10" 95 | mode: "non-blocking" 96 | keng-layer23-hw-server: 97 | image: ghcr.io/open-traffic-generator/keng-layer23-hw-server:1.42.0-4 98 | restart: always 99 | command: 100 | - "dotnet" 101 | - "otg-ixhw.dll" 102 | - "--trace" 103 | - "--log-level" 104 | - "trace" 105 | logging: 106 | driver: "local" 107 | options: 108 | max-size: "100m" 109 | max-file: "10" 110 | mode: "non-blocking" 111 | otg-gnmi-server: 112 | image: ghcr.io/open-traffic-generator/otg-gnmi-server:1.42.4 113 | restart: always 114 | depends_on: 115 | keng-controller: 116 | condition: service_started 117 | command: 118 | - "-http-server" 119 | - "https://keng-controller:8443" 120 | - "--debug" 121 | ports: 122 | - "50051:50051" 123 | logging: 124 | driver: "local" 125 | options: 126 | max-size: "100m" 127 | max-file: "10" 128 | mode: "non-blocking" 129 | ``` 130 | 131 | 2. Start the Compose tool: 132 | 133 | `docker compose up -d` 134 | 135 | 136 | 3. Use the `docker ps` command to verify that KENG services are running: 137 | 138 | `docker ps` 139 | 140 | The list of containers should include: 141 | - `keng-controller` 142 | - `keng-layer23-hw-server` 143 | - `otg-gnmi-server` (optional if gNMI access is needed) 144 | 145 | When the controller and ixhw-server services are running, the deployment is ready to run a test. 146 | 147 | **Test port references** 148 | 149 | KENG uses '/config.ports.locations' parameter to determine the test ports involved in the test. 150 | 151 | The ‘/config.ports.locations’ parameter needs to be set to reference a test port. 152 | 153 | This parameter is to be specified in a ‘chassis ip;card;port’ format. 154 | 155 | -------------------------------------------------------------------------------- /docs/deployments-docker-compose.md: -------------------------------------------------------------------------------- 1 | # Deploy Ixia-c using docker-compose 2 | 3 | Deploying multiple services manually (along with the required parameters) is not always applicable in some scenarios. For convenience, the [deployments](../deployments) directory consists of the following `docker-compose` files: 4 | 5 | - `*.yml`: Describes the services for a given scenario and the deployment parameters that are required to start them. 6 | - `.env`: Holds the default parameters, that are used across all `*.yml` files. For example, the name of the interface, the version of docker images, and etc. 7 | 8 | If a concerned `.yml` file does not include certain variables from `.env`, those can then safely be ignored. 9 | Follwoing is the example of a usual workflow, by using `docker-compose`. 10 | 11 | ```sh 12 | # change default parameters if needed; e.g. interface name, image version, etc. 13 | vi deployments/.env 14 | # deploy and start services for community users 15 | docker-compose -f deployments/.yml up -d 16 | # stop and remove services deployed 17 | docker-compose -f deployments/.yml down 18 | ``` 19 | 20 | On most of the systems, `docker-compose` needs to be installed separately even if the docker is already installed. For more information, see [docker prerequisites](prerequisites.md#docker) . 21 | 22 | >All the scenarios that are mentioned in the following sections, describe both manual and automated (requiring docker-compose) steps. 23 | 24 | ## Deployment Parameters 25 | 26 | ### Controller 27 | 28 | | Controller Parameters | Optional | Default | Description | 29 | |-----------------------------|-----------|-------------------------|-----------------------------------------------------------------| 30 | | --debug | Yes | false | Enables high volume logs with debug info for better diagnostics.| 31 | | --disable-app-usage-reporter| Yes | false | Disables sending of usage data to the app-usage-reporter. | 32 | | --http-port | Yes | 8443 | TCP port for HTTP server. | 33 | | --aur-host | Yes | https://localhost:5600 | Overrides the location of the app-usage-reporter. | 34 | | --accept-eula | No | NA | Indicates that the user has accepted EULA, otherwise the controller will not boot up. | 35 | | --license-servers | No | NA | Indicates the ip address of license servers for commercial users. | 36 | 37 | Docker Parameters: 38 | 39 | - `--net=host`: It is recommended to allow the use of the host network stack, in order to address the traffic-engine containers using `localhost` instead of `container-ip`, when deployed on the same host. 40 | - `-d`: This starts the container in background. 41 | 42 | Example: 43 | 44 | ```bash 45 | # For community users 46 | docker run --net=host -d ghcr.io/open-traffic-generator/keng-controller --accept-eula --debug --http-port 5050 47 | 48 | # For commercial users 49 | docker run --net=host -d ghcr.io/open-traffic-generator/keng-controller --accept-eula --debug --http-port 5050 --license-servers="ip/hostname of license server" 50 | ``` 51 | 52 | ### Traffic Engine 53 | 54 | | Environment Variables | Optional | Default | Description | 55 | |-----------------------------|-----------|-------------------------|-----------------------------------------------------------------| 56 | | ARG_IFACE_LIST | No | NA | Name of the network interface to bind to. It must be visible to the traffic-engine's network namespace. For example, `virtual@af_packet,eth1` where `eth1` is the interface name and `virtual@af_packet` indicates that the interface is managed by the host kernel's network stack.| 57 | | OPT_LISTEN_PORT | Yes | "5555" | TCP port on which the controller can establish connection with the traffic-engine.| 58 | | OPT_NO_HUGEPAGES | Yes | "No" | If set to `Yes`, it disables hugepages in the OS. The hugepages needs to be disabled when the network interfaces are managed by the host kernel's stack.| 59 | 60 | Docker Parameters: 61 | 62 | - `--net=host`: This is required if the traffic-engine needs to bind to a network interface that is visible in the host network stack but not inside the docker's network. 63 | - `--privileged`: This is required because the traffic-engine needs to exercise capabilities that require elevated privileges. 64 | - `--cpuset-cpus`: The traffic-engine usually requires 1 shared CPU core for management activities and 2 exclusive CPU cores, each for the transmit engine and receive engine. The shared CPU core can be shared across multiple traffic-engines. For example, `--cpuset-cpus="0,1,2"` which indicates that cpu0 is shared, cpu1 is used for transmit and cpu2 is used for receive. If CPU cores are not specified, any arbitrary CPU cores will be chosen. 65 | > If enough CPU cores are not provided, the available CPU cores may be shared among management, transmit, and the receive engines, that can occasionally result in lower performance. 66 | - `-d`: This starts the container in background. 67 | 68 | Example: 69 | 70 | ```bash 71 | docker run --net=host --privileged -d \ 72 | -e OPT_LISTEN_PORT="5555" \ 73 | -e ARG_IFACE_LIST="virtual@af_packet,eth1" \ 74 | -e OPT_NO_HUGEPAGES="Yes" \ 75 | --cpuset-cpus="0,1,2" \ 76 | ghcr.io/open-traffic-generator/ixia-c-traffic-engine 77 | ``` 78 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, caste, color, religion, or sexual 11 | identity and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the overall 27 | community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or advances of 32 | any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email address, 36 | without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at 64 | open-traffic-generator@googlegroups.com. 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series of 87 | actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or permanent 94 | ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within the 114 | community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.1, available at 120 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 121 | 122 | Community Impact Guidelines were inspired by 123 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 127 | [https://www.contributor-covenant.org/translations][translations]. 128 | 129 | [homepage]: https://www.contributor-covenant.org 130 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 131 | [Mozilla CoC]: https://github.com/mozilla/diversity 132 | [FAQ]: https://www.contributor-covenant.org/faq 133 | [translations]: https://www.contributor-covenant.org/translations 134 | 135 | -------------------------------------------------------------------------------- /deployments/k8s/network-emulation/ipfwd.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "time" 6 | 7 | "github.com/open-traffic-generator/snappi/gosnappi" 8 | ) 9 | 10 | func main() { 11 | 12 | // This test configures one IPv4 interface on tx and rx test port each 13 | // and sends IPv4 packets with src IP address of interface on tx port 14 | // and dst IP address of interface on rx port. The packets are sent only 15 | // after ARP entries have been learned from corresponding DUT interfaces 16 | // and flow metrics is used to validate tx and rx counters. 17 | 18 | testConst := map[string]interface{}{ 19 | "apiLocation": "https://localhost:8443", 20 | "txPortLocation": "eth1", 21 | "rxPortLocation": "eth2", 22 | "speed": "speed_1_gbps", 23 | "pktRate": uint64(50), 24 | "pktCount": uint32(100), 25 | "pktSize": uint32(128), 26 | "txMac": "00:00:01:01:01:01", 27 | "txIp": "1.1.1.1", 28 | "txGateway": "1.1.1.2", 29 | "txPrefix": uint32(24), 30 | "rxMac": "00:00:01:01:01:02", 31 | "rxIp": "2.2.2.1", 32 | "rxGateway": "2.2.2.2", 33 | "rxPrefix": uint32(24), 34 | } 35 | 36 | api := gosnappi.NewApi() 37 | api.NewHttpTransport().SetLocation(testConst["apiLocation"].(string)).SetVerify(false) 38 | 39 | log.Println("Constructing OTG configuration ...") 40 | c := otgConfig(testConst) 41 | 42 | log.Println("Pushing OTG configuration ...") 43 | if wrn, err := api.SetConfig(c); err != nil { 44 | log.Fatal(err) 45 | } else { 46 | for _, w := range wrn.Warnings() { 47 | log.Println("WARNING:", w) 48 | } 49 | } 50 | 51 | log.Println("Waiting for ARP entries for configured interfaces ...") 52 | for start := time.Now(); !ipNeighborsOk(api, testConst); time.Sleep(time.Millisecond * 500) { 53 | if time.Second*30 < time.Until(start) { 54 | log.Fatal("Timed out waiting for ARP entries") 55 | } 56 | } 57 | 58 | log.Println("Starting flow transmission ...") 59 | cs := gosnappi.NewControlState() 60 | cs.Traffic().FlowTransmit().SetState(gosnappi.StateTrafficFlowTransmitState.START) 61 | if wrn, err := api.SetControlState(cs); err != nil { 62 | log.Fatal(err) 63 | } else { 64 | for _, w := range wrn.Warnings() { 65 | log.Println("WARNING:", w) 66 | } 67 | } 68 | 69 | log.Println("Waiting for flow metrics ...") 70 | for start := time.Now(); !flowMetricsOk(api, testConst); time.Sleep(time.Millisecond * 500) { 71 | if time.Second*30 < time.Until(start) { 72 | log.Fatal("Timed out waiting for ARP entries") 73 | } 74 | } 75 | } 76 | 77 | func otgConfig(tc map[string]interface{}) gosnappi.Config { 78 | c := gosnappi.NewConfig() 79 | 80 | ptx := c.Ports().Add().SetName("ptx").SetLocation(tc["txPortLocation"].(string)) 81 | prx := c.Ports().Add().SetName("prx").SetLocation(tc["rxPortLocation"].(string)) 82 | 83 | c.Layer1().Add(). 84 | SetName("ly"). 85 | SetPortNames([]string{ptx.Name(), prx.Name()}). 86 | SetSpeed(gosnappi.Layer1SpeedEnum(tc["speed"].(string))) 87 | 88 | dtx := c.Devices().Add().SetName("dtx") 89 | drx := c.Devices().Add().SetName("drx") 90 | 91 | dtxEth := dtx.Ethernets(). 92 | Add(). 93 | SetName("dtxEth"). 94 | SetMac(tc["txMac"].(string)). 95 | SetMtu(1500) 96 | 97 | dtxEth.Connection().SetPortName(ptx.Name()) 98 | 99 | dtxIp := dtxEth. 100 | Ipv4Addresses(). 101 | Add(). 102 | SetName("dtxIp"). 103 | SetAddress(tc["txIp"].(string)). 104 | SetGateway(tc["txGateway"].(string)). 105 | SetPrefix(tc["txPrefix"].(uint32)) 106 | 107 | drxEth := drx.Ethernets(). 108 | Add(). 109 | SetName("drxEth"). 110 | SetMac(tc["rxMac"].(string)). 111 | SetMtu(1500) 112 | 113 | drxEth.Connection().SetPortName(prx.Name()) 114 | 115 | drxIp := drxEth. 116 | Ipv4Addresses(). 117 | Add(). 118 | SetName("drxIp"). 119 | SetAddress(tc["rxIp"].(string)). 120 | SetGateway(tc["rxGateway"].(string)). 121 | SetPrefix(tc["rxPrefix"].(uint32)) 122 | 123 | flow := c.Flows().Add() 124 | flow.SetName("ftxV4") 125 | flow.Duration().FixedPackets().SetPackets(tc["pktCount"].(uint32)) 126 | flow.Rate().SetPps(tc["pktRate"].(uint64)) 127 | flow.Size().SetFixed(tc["pktSize"].(uint32)) 128 | flow.Metrics().SetEnable(true) 129 | 130 | flow.TxRx().Device(). 131 | SetTxNames([]string{dtxIp.Name()}). 132 | SetRxNames([]string{drxIp.Name()}) 133 | 134 | ftxV4Eth := flow.Packet().Add().Ethernet() 135 | ftxV4Eth.Src().SetValue(dtxEth.Mac()) 136 | 137 | ftxV4Ip := flow.Packet().Add().Ipv4() 138 | ftxV4Ip.Src().SetValue(tc["txIp"].(string)) 139 | ftxV4Ip.Dst().SetValue(tc["rxIp"].(string)) 140 | 141 | log.Printf("Config:\n%v\n", c) 142 | return c 143 | } 144 | 145 | func ipNeighborsOk(api gosnappi.Api, tc map[string]interface{}) bool { 146 | count := 0 147 | 148 | log.Println("Getting IPv4 neighbors ...") 149 | req := gosnappi.NewStatesRequest() 150 | // query to fetch states for all configured IPv4 interfaces 151 | req.Ipv4Neighbors() 152 | states, err := api.GetStates(req) 153 | if err != nil { 154 | log.Fatal(err) 155 | } 156 | 157 | log.Printf("IPv4 Neighbors Metrics:\n%v\n", states) 158 | for _, n := range states.Ipv4Neighbors().Items() { 159 | if n.HasLinkLayerAddress() { 160 | for _, key := range []string{"txGateway", "rxGateway"} { 161 | if n.Ipv4Address() == tc[key].(string) { 162 | count += 1 163 | } 164 | } 165 | } 166 | } 167 | 168 | return count == 2 169 | } 170 | 171 | func flowMetricsOk(api gosnappi.Api, tc map[string]interface{}) bool { 172 | pktCount := uint64(tc["pktCount"].(uint32)) 173 | 174 | log.Println("Getting flow metrics ...") 175 | req := gosnappi.NewMetricsRequest() 176 | // query to fetch metrics for all configured flows 177 | req.Flow() 178 | metrics, err := api.GetMetrics(req) 179 | if err != nil { 180 | log.Fatal(err) 181 | } 182 | 183 | log.Printf("Flow Metrics:\n%v\n", metrics) 184 | for _, m := range metrics.FlowMetrics().Items() { 185 | if m.Transmit() != gosnappi.FlowMetricTransmit.STOPPED || 186 | m.FramesTx() != pktCount || 187 | m.FramesRx() != pktCount { 188 | return false 189 | } 190 | 191 | } 192 | 193 | return true 194 | } 195 | -------------------------------------------------------------------------------- /docs/res/hw-server.drawio: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /docs/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | [data-md-color-scheme="ks-light"] { 2 | --ks-color-black: #000000; 3 | --ks-color-dark-red: #871518; 4 | --ks-color-red: #E90029; 5 | --ks-color-dark-gray: #373A36; 6 | --ks-color-medium-gray: #97999B; 7 | --ks-color-gray: #D9D9D6; 8 | --ks-color-light-gray: #EBEBEB; 9 | --ks-color-white: #FFFFFF; 10 | 11 | --ks-color-dark-blue: #071D49; 12 | --ks-color-blue: #426DA9; 13 | --ks-color-teal: #63B1BC; 14 | 15 | --gh-color-code-bg-color: rgb(246,248,250); 16 | --gh-color-code-fg-color: rgb(36,41,47); 17 | --gh-color-code-comment-color: rgb(110,119,129); 18 | --gh-color-code-string-color: rgb(10,48,105); 19 | --gh-color-code-keyword-color: rgb(207,34,46); 20 | --gh-color-code-pretty-color: rgb(130,80,223); 21 | 22 | --md-primary-fg-color: var(--ks-color-black); 23 | --md-primary-fg-color--light: var(--ks-color-light-gray); 24 | --md-primary-fg-color--dark: var(--ks-color-dark-gray); 25 | --md-primary-bg-color: var(--ks-color-white); 26 | 27 | --md-default-bg-color: var(--ks-color-white); 28 | --md-default-fg-color--light: var(--ks-color-dark-gray); 29 | --md-default-fg-color: var(--ks-color-black); 30 | --md-default-fg-color--dark: var(--ks-color-black); 31 | 32 | --md-typeset-color: var(--ks-color-dark-gray); 33 | --md-typeset-a-color: var(--ks-color-red); 34 | 35 | --md-code-bg-color: var(--gh-color-code-bg-color); 36 | --md-code-fg-color: var(--gh-color-code-fg-color); 37 | --md-code-hl-comment-color: var(--gh-color-code-comment-color); 38 | --md-code-hl-variable-color: var(--gh-color-code-pretty-color); 39 | --md-code-hl-name-color: var(--gh-color-code-pretty-color); 40 | --md-code-hl-number-color: var(--gh-color-code-string-color); 41 | --md-code-hl-string-color: var(--gh-color-code-string-color); 42 | --md-code-hl-special-color: var(--gh-color-code-fg-color); 43 | --md-code-hl-operator-color: var(--gh-color-code-string-color); 44 | --md-code-hl-punctuation-color: var(--gh-color-code-fg-color); 45 | --md-code-hl-keyword-color: var(--gh-color-code-keyword-color); 46 | --md-code-hl-function-color: var(--gh-color-code-pretty-color); 47 | --md-code-hl-constant-color: var(--gh-color-code-pretty-color); 48 | 49 | --md-admonition-bg-color: var(--gh-color-code-bg-color); 50 | --md-admonition-fg-color: var(--md-default-fg-color--light); 51 | } 52 | [data-md-color-scheme="ks-dark"] { 53 | --ks-color-black: #000000; 54 | --ks-color-dark-red: #871518; 55 | --ks-color-red: #E90029; 56 | --ks-color-dark-gray: #373A36; 57 | --ks-color-medium-gray: #97999B; 58 | --ks-color-gray: #D9D9D6; 59 | --ks-color-light-gray: #EBEBEB; 60 | --ks-color-white: #FFFFFF; 61 | 62 | --ks-color-dark-blue: #071D49; 63 | --ks-color-blue: #426DA9; 64 | --ks-color-teal: #63B1BC; 65 | 66 | --gh-color-code-bg-color: rgb(22,27,24); 67 | --gh-color-code-fg-color: rgb(201,209,207); 68 | --gh-color-code-comment-color: rgb(139,148,158); 69 | --gh-color-code-string-color: rgb(165,214,255); 70 | --gh-color-code-keyword-color: rgb(255,123,114); 71 | --gh-color-code-pretty-color: rgb(210,168,255); 72 | 73 | --md-primary-fg-color: var(--ks-color-black); 74 | --md-primary-fg-color--dark: var(--ks-color-dark-gray); 75 | --md-primary-fg-color--light: var(--ks-color-medium-gray); 76 | --md-primary-bg-color: var(--ks-color-white); 77 | --md-primary-bg-color--light: var(--ks-color-light-gray); 78 | 79 | --md-default-bg-color--light: var(--ks-color-white); 80 | --md-default-bg-color--lighter: var(--ks-color-white); 81 | --md-default-bg-color--lightest: var(--ks-color-white); 82 | --md-default-fg-color: var(--ks-color-white); 83 | --md-default-fg-color--lightest: var(--ks-color-blue); 84 | --md-default-fg-color--light: var(--ks-color-light-gray); 85 | --md-default-fg-color--lighter: var(--ks-color-light-gray); 86 | --md-default-fg-color--dark: var(--ks-color-medium-gray); 87 | --md-default-bg-color: var(--ks-color-black); 88 | 89 | --md-typeset-color: var(--ks-color-gray); 90 | --md-typeset-a-color: var(--ks-color-red); 91 | 92 | --md-code-bg-color: var(--gh-color-code-bg-color); 93 | --md-code-fg-color: var(--gh-color-code-fg-color); 94 | --md-code-hl-comment-color: var(--gh-color-code-comment-color); 95 | --md-code-hl-variable-color: var(--gh-color-code-pretty-color); 96 | --md-code-hl-name-color: var(--gh-color-code-pretty-color); 97 | --md-code-hl-number-color: var(--gh-color-code-string-color); 98 | --md-code-hl-string-color: var(--gh-color-code-string-color); 99 | --md-code-hl-special-color: var(--gh-color-code-fg-color); 100 | --md-code-hl-operator-color: var(--gh-color-code-string-color); 101 | --md-code-hl-punctuation-color: var(--gh-color-code-fg-color); 102 | --md-code-hl-keyword-color: var(--gh-color-code-keyword-color); 103 | --md-code-hl-function-color: var(--gh-color-code-pretty-color); 104 | --md-code-hl-constant-color: var(--gh-color-code-pretty-color); 105 | 106 | --md-admonition-bg-color: var(--md-default-bg-color); 107 | --md-admonition-fg-color: var(--md-default-fg-color--light); 108 | 109 | --md-accent-fg-color: var(--ks-color-light-gray); 110 | --md-accent-fg-color--transparent: var(--ks-color-dark-gray); 111 | } 112 | 113 | .md-grid { 114 | max-width: 1440px; 115 | } 116 | 117 | .container { 118 | display: flex; 119 | } 120 | 121 | .column { 122 | flex: 1; 123 | padding: 20px; 124 | } 125 | -------------------------------------------------------------------------------- /docs/developer/snappi-install.md: -------------------------------------------------------------------------------- 1 | # Installing Snappi 2 | 3 | The procedures explained in this section helps to install and configure snappi for an Open Traffic Generator API. 4 | 5 | The test scripts written in **gosnappi**, and the auto-generated Go SDK, can be executed against any traffic generator that conforms to [Open Traffic Generator API](https://github.com/open-traffic-generator/models). 6 | 7 | [Ixia-c](https://github.com/open-traffic-generator/ixia-c) is one of such reference implementations of the Open Traffic Generator API. 8 | 9 | ## To install Snappi for the Go language, do the following: 10 | 11 | ### Setup the client 12 | 13 | ```sh 14 | go get github.com/open-traffic-generator/snappi/gosnappi 15 | ``` 16 | 17 | ### Start Testing 18 | 19 | ```Go 20 | package examples 21 | 22 | import ( 23 | "encoding/hex" 24 | "testing" 25 | "time" 26 | 27 | "github.com/open-traffic-generator/snappi/gosnappi" 28 | ) 29 | 30 | func TestQuickstart(t *testing.T) { 31 | // Create a new API handle to make API calls against OTG 32 | api := gosnappi.NewApi() 33 | 34 | // Set the transport protocol to HTTP 35 | api.NewHttpTransport().SetLocation("https://localhost:8443") 36 | 37 | // Create a new traffic configuration that will be set on OTG 38 | config := gosnappi.NewConfig() 39 | 40 | // Add a test port to the configuration 41 | ptx := config.Ports().Add().SetName("ptx").SetLocation("veth-a") 42 | 43 | // Configure a flow and set previously created test port as one of endpoints 44 | flow := config.Flows().Add().SetName("f1") 45 | flow.TxRx().Port().SetTxName(ptx.Name()) 46 | // and enable tracking flow metrics 47 | flow.Metrics().SetEnable(true) 48 | 49 | // Configure number of packets to transmit for previously configured flow 50 | flow.Duration().FixedPackets().SetPackets(100) 51 | // and fixed byte size of all packets in the flow 52 | flow.Size().SetFixed(128) 53 | 54 | // Configure protocol headers for all packets in the flow 55 | pkt := flow.Packet() 56 | eth := pkt.Add().Ethernet() 57 | ipv4 := pkt.Add().Ipv4() 58 | udp := pkt.Add().Udp() 59 | cus := pkt.Add().Custom() 60 | 61 | eth.Dst().SetValue("00:11:22:33:44:55") 62 | eth.Src().SetValue("00:11:22:33:44:66") 63 | 64 | ipv4.Src().SetValue("10.1.1.1") 65 | ipv4.Dst().SetValue("20.1.1.1") 66 | 67 | // Configure repeating patterns for source and destination UDP ports 68 | udp.SrcPort().SetValues([]int32{5010, 5015, 5020, 5025, 5030}) 69 | udp.DstPort().Increment().SetStart(6010).SetStep(5).SetCount(5) 70 | 71 | // Configure custom bytes (hex string) in payload 72 | cus.SetBytes(hex.EncodeToString([]byte("..QUICKSTART SNAPPI.."))) 73 | 74 | // Optionally, print JSON representation of config 75 | if j, err := config.ToJson(); err != nil { 76 | t.Fatal(err) 77 | } else { 78 | t.Log("Configuration: ", j) 79 | } 80 | 81 | // Push traffic configuration constructed so far to OTG 82 | if _, err := api.SetConfig(config); err != nil { 83 | t.Fatal(err) 84 | } 85 | 86 | // Start transmitting the packets from configured flow 87 | ts := gosnappi.NewTransmitState() 88 | ts.SetState(gosnappi.TransmitStateState.START) 89 | if _, err := api.SetTransmitState(ts); err != nil { 90 | t.Fatal(err) 91 | } 92 | 93 | // Fetch metrics for configured flow 94 | req := gosnappi.NewMetricsRequest() 95 | req.Flow().SetFlowNames([]string{flow.Name()}) 96 | // and keep polling until either expectation is met or deadline exceeds 97 | deadline := time.Now().Add(10 * time.Second) 98 | for { 99 | metrics, err := api.GetMetrics(req) 100 | if err != nil || time.Now().After(deadline) { 101 | t.Fatalf("err = %v || deadline exceeded", err) 102 | } 103 | // print YAML representation of flow metrics 104 | t.Log(metrics) 105 | if metrics.FlowMetrics().Items()[0].Transmit() == gosnappi.FlowMetricTransmit.STOPPED { 106 | break 107 | } 108 | time.Sleep(100 * time.Millisecond) 109 | } 110 | } 111 | ``` 112 | 113 | ## To install Snappi for the Python language, do the following: 114 | 115 | ### Setup the Client 116 | 117 | ```sh 118 | python -m pip install --upgrade snappi 119 | ``` 120 | 121 | ### Start Testing 122 | 123 | ```python 124 | import datetime 125 | import time 126 | import snappi 127 | import pytest 128 | 129 | 130 | @pytest.mark.example 131 | def test_quickstart(): 132 | # Create a new API handle to make API calls against OTG 133 | # with HTTP as default transport protocol 134 | api = snappi.api(location="https://localhost:8443") 135 | 136 | # Create a new traffic configuration that will be set on OTG 137 | config = api.config() 138 | 139 | # Add a test port to the configuration 140 | ptx = config.ports.add(name="ptx", location="veth-a") 141 | 142 | # Configure a flow and set previously created test port as one of endpoints 143 | flow = config.flows.add(name="flow") 144 | flow.tx_rx.port.tx_name = ptx.name 145 | # and enable tracking flow metrics 146 | flow.metrics.enable = True 147 | 148 | # Configure number of packets to transmit for previously configured flow 149 | flow.duration.fixed_packets.packets = 100 150 | # and fixed byte size of all packets in the flow 151 | flow.size.fixed = 128 152 | 153 | # Configure protocol headers for all packets in the flow 154 | eth, ip, udp, cus = flow.packet.ethernet().ipv4().udp().custom() 155 | 156 | eth.src.value = "00:11:22:33:44:55" 157 | eth.dst.value = "00:11:22:33:44:66" 158 | 159 | ip.src.value = "10.1.1.1" 160 | ip.dst.value = "20.1.1.1" 161 | 162 | # Configure repeating patterns for source and destination UDP ports 163 | udp.src_port.values = [5010, 5015, 5020, 5025, 5030] 164 | udp.dst_port.increment.start = 6010 165 | udp.dst_port.increment.step = 5 166 | udp.dst_port.increment.count = 5 167 | 168 | # Configure custom bytes (hex string) in payload 169 | cus.bytes = "".join([hex(c)[2:] for c in b"..QUICKSTART SNAPPI.."]) 170 | 171 | # Optionally, print JSON representation of config 172 | print("Configuration: ", config.serialize(encoding=config.JSON)) 173 | 174 | # Push traffic configuration constructed so far to OTG 175 | api.set_config(config) 176 | 177 | # Start transmitting the packets from configured flow 178 | ts = api.transmit_state() 179 | ts.state = ts.START 180 | api.set_transmit_state(ts) 181 | 182 | # Fetch metrics for configured flow 183 | req = api.metrics_request() 184 | req.flow.flow_names = [flow.name] 185 | # and keep polling until either expectation is met or deadline exceeds 186 | start = datetime.datetime.now() 187 | while True: 188 | metrics = api.get_metrics(req) 189 | if (datetime.datetime.now() - start).seconds > 10: 190 | raise Exception("deadline exceeded") 191 | # print YAML representation of flow metrics 192 | print(metrics) 193 | if metrics.flow_metrics[0].transmit == metrics.flow_metrics[0].STOPPED: 194 | break 195 | time.sleep(0.1) 196 | ``` 197 | -------------------------------------------------------------------------------- /docs/licensing.md: -------------------------------------------------------------------------------- 1 | # Licensing 2 | 3 | ## License Editions 4 | 5 | The following License Editions are available for Keysight Elastic Network Generator: 6 | 7 | | Capability | Community | Developer | Team | System | 8 | |-------------------------------------|----------------------|----------------------|--------------------------------|-------------------------------------| 9 | | Ixia-c Traffic Port Capacity | 4 x 1/10GE | 50GE | 400GE | 800GE | 10 | | Test Concurrency | 1 Seat | 1 Seat | 8 Seats | 16 Seats | 11 | | Protocol Scale | Restricted | Limited | Limited | Unlimited | 12 | | Requires a valid license | N | Y | Y | Y | 13 | | Includes Ixia-c Software Test Ports | Y | Y | Y | Y | 14 | | Works with UHD400T Hardware | N | N | Y | Y | 15 | | Works with IxOS Hardware | N | N | N | Y | 16 | 17 | The **Ixia-c Traffic Port Capacity** is determined as a sum of the configured Ixia-c software test port speeds with the possible values of: 100GE, 50GE, 40GE, 25GE, 10GE, and 1GE. The Maximum data plane performance of an Ixia-c port may be less than the configured port speed, depending on the capabilities of the underlying hardware and software drivers. Doesn't apply to the UHD400T and IxOS hardware. 18 | 19 | The **Test seat concurrency** applies to a number of controller instances that are running with a configuration that exceeds the capabilities of the Community Edition. 20 | 21 | The **Restricted** protocol scale supports the maximum of 4 BGP sessions per test. 22 | 23 | The Capabilities of the **Limited** protocol scale depend on the protocol. For details, contact [Keysight Support](https://support.ixiacom.com/contact/support). 24 | 25 | Keysight Elastic Network Generator can simultaneously consume multiple licenses to increase the capabilities of a test. For example, if the Ixia-c Traffic Port Capacity configured in one test is 100GE, two Developer licenses will be consumed if available. 26 | 27 | If you require capabilities beyond those provided by the Community Edition, use [Keysight Elastic Network Generator](https://www.keysight.com/us/en/products/network-test/protocol-load-test/keysight-elastic-network-generator.html) product page to request an evaluation or a quote. 28 | 29 | ## License Server 30 | 31 | In order to use capabilities of Elastic Network Generator that require a valid license, you need to deploy a Keysight License Server. Keysight uses the license server to manage floating or network shared licenses for its software products. The license server enables licenses to float and not be tied to a specific Elastic Network Generator instance. The Elastic Network Generator controllers must be able to reach the License server. 32 | 33 | ### Deployment 34 | 35 | The license server is a virtual machine and it is distributed as OVA and QCOW2 images (you only need one of them depending on your hypervisor, downloading may need credentials for support website.). 36 | 37 | * [OVA image](https://downloads.ixiacom.com/support/downloads_and_updates/public/KENG-License-Server-VM/4.4.0/4.4.0-202/slum-4.4.0-202.ova), 5.8GB 38 | * [QCOW2 image](https://downloads.ixiacom.com/support/downloads_and_updates/public/KENG-License-Server-VM/4.4.0/4.4.0-202/slum-4.4.0-202.qcow2), 6GB 39 | 40 | To make a decision where to deploy the License Server VM, take into the account the following requirements: 41 | 42 | * For VMware ESXi, use the OVA image 43 | * For Linux-based QEMU or KVM, use the QCOW2 image 44 | * 2 vCPU cores 45 | * 8GB RAM for ESXi, 4GB RAM for QEMU/KVM 46 | * 100GB storage 47 | * 1 vNIC for network connectivity. Note that DHCP is the preferred option, and this is also how the VM is configured to obtain its IP address. 48 | 49 | Network connectivity requirements for the License Server VM 50 | 51 | 1. Internet access from the VM over HTTPS is desirable for online license activation, but not strictly required. Offline activation method is available as well. 52 | 2. Access from a user over HTTPS (TCP/443) for license operations (activation, deactivation, reservation, sync). 53 | 3. Access from any `keng-controller` that needs a license during a test run over gRPC (TCP/7443) for license checkout and check-in. 54 | 55 | Here is an example of how different components communicate with the License Server: 56 | 57 | ![License Server Connectivity](./res/license-server.drawio.svg) 58 | 59 | ### Configuration 60 | 61 | If your network doesn't provide DHCP, you can configure a static IP address for the License Server VM. Access the VM console and go through two-step login process: 62 | 63 | * First prompt: `console` (no password) 64 | * Second promt: `admin`/`admin` 65 | * Run the following commands to configure a static IP address, where `x.x.x.x` is the IP address, `yy` is the prefix length, `z.z.z.z` is the default gateway, `a.a.a.a` and `b.b.b.b` are DNS servers: 66 | 67 | ```Shell 68 | kcos networking ip set mgmt0 x.x.x.x/yy z.z.z.z 69 | kcos networking dns-servers add a.a.a.a b.b.b.b 70 | ``` 71 | 72 | ### Activation 73 | 74 | Now you shall be able to activate licenses and use the License Server with your Elastic Network Generator environments. Go to `https://your-license-server-hostname` to access the application. Enter credentials: `admin`/`admin` to login. 75 | 76 | If you have an activation code, to perform an online activation, click "Activate Licenses", enter the code and click "Activate". For offline mode, choose "Offline Operations" instead. 77 | 78 | You can also use a command-line session, via console or SSH, to perform license operations. Run `kcos licensing --help` to see the list of available commands. 79 | 80 | ## Using Licenses 81 | 82 | To use the licenses with the Elastic Network Generator, provide the location of the license servers to the controller instances using 83 | 84 | ``` 85 | --license-servers="server1 server2 server3 server4" 86 | ``` 87 | 88 | argument when launching the controller. The argument accepts a space-separated list of hostnames or IP addresses of the License Servers, up to four. The controller will try to connect to the License Servers in the order they are specified in the list. If the first License Server is not available, or doesn't have enough available licenses to run the test, the controller will try to connect to the next one in the list. 89 | 90 | An alternative way is to use an environment variable `LICENSE_SERVERS`. 91 | 92 | ## Additional Information 93 | 94 | Please refer to the [Reference Guide](reference/licensing.md) for more information on the license operations. -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 |

2 |
3 | Ixia-C 4 |
5 |

6 | 7 |

8 | Ixia-C - A powerful traffic generator based on Open Traffic Generator API 9 |

10 | 11 |

12 | Release v1.42.0-4 13 | Open Traffic Generator v1.42.0 14 | snappi v1.42.0 15 | news 16 | news 17 | Slack Status 18 |

19 | 20 |

21 | Quick Start  •  22 | Key Features  •  23 | Documentation  •  24 | Use Cases  •  25 | Roadmap  •  26 | FAQ 27 |
28 |

29 | 30 | ### What is Ixia-C ? 31 | 32 | - A modern, powerful and **API-driven** traffic generator designed to cater to the needs of hyper-scalers, network hardware vendors and hobbyists alike. 33 | 34 | - **Free for basic use-cases** and distributed / deployed as a multi-container application consisting primarily of a [controller](https://github.com/orgs/open-traffic-generator/packages/container/package/keng-controller), a [traffic-engine](https://github.com/orgs/open-traffic-generator/packages/container/package/ixia-c-traffic-engine) and a [protocol-engine](https://github.com/orgs/open-traffic-generator/packages/container/package/ixia-c-protocol-engine). 35 | 36 | - As a reference implementation of [Open Traffic Generator API](https://github.com/open-traffic-generator/models), supports client SDKs in various languages, most prevalent being [snappi](https://github.com/open-traffic-generator/snappi) (Python SDK) and [gosnappi](https://github.com/open-traffic-generator/snappi/tree/main/gosnappi). 37 | 38 |

39 | Ixia-C deployment for two-arm test with DUT 40 |

41 | 42 | > [Keysight](https://www.keysight.com) also offers a well supported commercial version, [Keysight Elastic Network Generator (KENG)](https://www.keysight.com/us/en/products/network-test/protocol-load-test/keysight-elastic-network-generator.html), with no restrictions on **performance and scalability**. Scripts written for the community version are **compatible** with this version. 43 | 44 | ### Quick Start 45 | 46 | Please ensure that following prerequisites are met by the setup: 47 | - At least **2 x86_64 CPU cores** and **7GB RAM**, preferably running **Ubuntu 22.04 LTS** OS 48 | - **Python 3.8+** (and **pip**) or **Go 1.19+** 49 | - **Docker Engine** (Community Edition) 50 | 51 | 52 | #### 1. Deploy Ixia-C 53 | 54 | ```bash 55 | # clone this repository 56 | git clone --recurse-submodules https://github.com/open-traffic-generator/ixia-c.git && cd ixia-c 57 | 58 | # create a veth pair and deploy ixia-c containers where one traffic-engine is bound 59 | # to each interface in the pair, and controller is configured to figure out how to 60 | # talk to those traffic-engine containers 61 | cd conformance && ./do.sh topo new dp 62 | ``` 63 | 64 | #### 2. Setup and run standalone test using [snappi](https://github.com/open-traffic-generator/snappi) or [gosnappi](https://github.com/open-traffic-generator/snappi/tree/main/gosnappi) 65 | 66 | ```bash 67 | # change dir to conformance if you haven't already 68 | cd conformance 69 | 70 | # setup python virtual environment and install dependencies 71 | ./do.sh prepytest 72 | 73 | # run standalone snappi test that configures and sends UDP traffic 74 | # upon successful run, flow metrics shall be printed on console 75 | ./do.sh pytest examples/test_quickstart.py 76 | 77 | # optionally, go equivalent of the test can be run like so 78 | ./do.sh gotest examples/quickstart_test.go 79 | ``` 80 | 81 | > Checkout the contents of [test_quickstart.py](https://github.com/open-traffic-generator/conformance/blob/22563e20fe512ef13baf44c1bc69bc59f87f6c25/examples/test_quickstart.py) and equivalent [quickstart_test.go](https://github.com/open-traffic-generator/conformance/blob/22563e20fe512ef13baf44c1bc69bc59f87f6c25/examples/quickstart_test.go) for quick explanation on test steps. 82 | 83 | #### 3. Optionally, run test using [curl](https://curl.se/) 84 | 85 | We can also pass equivalent **JSON configuration** directly to **controller**, just by using **curl**. 86 | The description of each node in the configuration is detailed in self-updating [online documentation](https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/open-traffic-generator/models/v1.42.0/artifacts/openapi.yaml). 87 | 88 | 89 | ```bash 90 | # push traffic configuration 91 | curl -skL https://localhost:8443/config -H "Content-Type: application/json" -d @conformance/examples/quickstart_config.json 92 | 93 | # start transmitting configured flows 94 | curl -skL https://localhost:8443/control/state -H "Content-Type: application/json" -d @conformance/examples/quickstart_control.json 95 | 96 | # fetch flow metrics 97 | curl -skL https://localhost:8443/monitor/metrics -H "Content-Type: application/json" -d @conformance/examples/quickstart_metrics.json 98 | ``` 99 | 100 | ### Key Features 101 | 102 | * High Performance 103 | * Run on servers or Keysight hardware (commercial version only) 104 | * Generate kbps to Tbps of traffic using same script 105 | * 10Gbps @ 64 byte frame size using one Xeon class core (commercial version only) 106 | * Built using [DPDK](https://www.dpdk.org) 107 | * Fast REST API for automation 108 | * Easily integrate with test frameworks like [pytest](https://www.pytest.org) 109 | * Easily integrate into CI/CD pipelines with Jenkins, GitHub, GitLab 110 | * Up to 256 flows per port. Each Flow supports: 111 | * Packet Templates for Ethernet, VLAN, VXLAN, GTPv1, GTPv2, IPv4, IPv6, ICMP, ICMPv6, GRE, UDP, & TCP. More protocols are on the way. 112 | * Ability to use tools like Scapy to add headers for unsupported protocols. 113 | * Manipulation of any field in the packet headers 114 | * Patterns to modify common packet header fields to generate millions of unique packets 115 | * Ability to track flows based on common packet header fields 116 | * Configurable frame size 117 | * Rate specification in pps (packets per second) or % line-rate 118 | * Ability to send bursts 119 | * Statistics 120 | * Per-port and per-flow 121 | * One way latency measurements (min, max, average) on a per flow basis 122 | * Capture 123 | * Packets with filters 124 | * Write to PCAP or redirect to tcpdump 125 | 126 | ## Copyright notice 127 | 128 | © Copyright Keysight Technologies, Inc. 2021, 2022, 2023 129 | 130 | -------------------------------------------------------------------------------- /deployments/k8s/network-emulation/readme.md: -------------------------------------------------------------------------------- 1 | # Ixia-C Kubernetes Deployment For Emulating Network Topology 2 | 3 | Ixia-C is a pure software-based solution for facilitating protocol emulation and traffic generation against containerized DUTs (Device Under Test). 4 | 5 |

6 | Ixia-C K8S Deployment For Emulating Network Topology 7 |

8 | 9 | For deployment, K8S (Kubernetes) as a platform can be exercised using one of following approaches: 10 | - Manually construct K8S deployment files for any given topology 11 | - Use [KNE](https://github.com/openconfig/kne) to automate deployment using an abstract topology definition 12 | 13 | This document discusses the first approach using a minimal Ubuntu container as DUT. 14 | 15 | ### Overview 16 | 17 | Ixia-C is distributed as a multi-container application with following as core components: 18 | 1. `keng-controller`: API Server driving operation on one or more test port based on API requests 19 | 2. `ixia-c-traffic-engine`: Drives data plane operations on test port 20 | 3. `ixia-c-protocol-engine`: Drives control plane operations on test port 21 | 22 | Upon deployment, `ixia-c-traffic-engine` and `ixia-c-protocol-engine` need to share same network namespace and hence constitute an Ixia-C Test Port Pod. A typical deployment consists of one `controller pod` and one or more `test port pod`s. 23 | 24 | To establish any meaningful interaction between Ixia-C test ports and DUT interfaces, following needs to be done: 25 | - A pair of virtual interfaces need to be created, each on an Ixia-C test port pod and DUT pod 26 | - The interface pair then needs to have a P2P (point-to-point) link established among themselves 27 | 28 | To achieve this, we'll be using [Meshnet CNI](https://github.com/networkop/meshnet-cni). 29 | 30 | 31 | ### Prerequisites 32 | 33 | - At least **2 x86 CPU cores**, **7GB RAM** and **30GB Free Hard Disk Space** 34 | - Recommended OS is **Ubuntu 22.04 LTS** release. 35 | - Go **1.20+** 36 | - **Docker Engine** (Community Edition) - Needed when using kind for setting up K8S cluster 37 | 38 | ### Steps 39 | 40 | 1. Clone this repository 41 | 42 | ```bash 43 | git clone --recurse-submodules https://github.com/open-traffic-generator/ixia-c.git && cd ixia-c 44 | ``` 45 | 46 | 2. (Optional) Setup a Kubernetes Cluster using [kind](https://kind.sigs.k8s.io/) 47 | 48 | ```bash 49 | # install kind 50 | go install sigs.k8s.io/kind@v0.20.0 51 | 52 | # create a single-node cluster 53 | kind create cluster --config=deployments/k8s/network-emulation/kind.yaml --wait 30s 54 | 55 | # get compatible kubectl 56 | sudo docker cp kind-control-plane:/usr/bin/kubectl /usr/local/bin/kubectl 57 | sudo chmod 0755 /usr/local/bin/kubectl 58 | 59 | # ensure all pods are ready 60 | kubectl wait --for=condition=Ready pods --all --all-namespaces 61 | ``` 62 | 63 | 3. (Optional) If cluster does not have access to ghcr.io, manually download container images and push them to all nodes in the cluster 64 | 65 | ```bash 66 | # Enter Github user ID and PAT when asked for credentials 67 | docker login ghcr.io 68 | 69 | # download ixia-c images 70 | docker pull ghcr.io/open-traffic-generator/keng-controller:1.42.0-4 71 | docker pull ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.8.0.245 72 | docker pull ghcr.io/open-traffic-generator/ixia-c-protocol-engine:1.00.0.488 73 | 74 | # download DUT image 75 | docker pull ubuntu:22.04 76 | 77 | # download meshnet image 78 | docker pull networkop/meshnet:latest 79 | # download init image 80 | docker pull networkop/init-wait:latest 81 | 82 | # push images to nodes 83 | kind load docker-image ghcr.io/open-traffic-generator/keng-controller:1.42.0-4 84 | kind load docker-image ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.8.0.245 85 | kind load docker-image ghcr.io/open-traffic-generator/ixia-c-protocol-engine:1.00.0.488 86 | kind load docker-image ubuntu:22.04 87 | kind load docker-image networkop/meshnet:latest 88 | kind load docker-image networkop/init-wait:latest 89 | 90 | # make sure all intended images have been pushed correctly 91 | docker exec kind-control-plane crictl images 92 | ``` 93 | 94 | 4. Setup meshnet 95 | 96 | ```bash 97 | # Clone and checkout tested version of meshnet 98 | git clone https://github.com/networkop/meshnet-cni 99 | cd meshnet-cni && git checkout f26c193 && cd - 100 | 101 | # Deploy meshnet 102 | kubectl apply -k meshnet-cni/manifests/base 103 | 104 | # wait for meshnet pods 105 | kubectl wait --for=condition=Ready pods -n meshnet --all 106 | ``` 107 | 108 | 5. Create virtual interfaces and P2P link using meshnet 109 | 110 | The deployment file to be applied specifies name of test port pods and dut pod, interfaces to be created inside each of them and corresponding peer interface to create P2P link with. 111 | 112 | ```bash 113 | # create meshnet CRD 114 | kubectl apply -f deployments/k8s/network-emulation/namespace.yaml 115 | kubectl apply -f deployments/k8s/network-emulation/links.yaml 116 | 117 | # ensure meshnet CRD is successfully created (should list three entries) 118 | kubectl get topologies -A 119 | ``` 120 | 121 | 6. Create Ixia-C / DUT pods and services 122 | 123 | ```bash 124 | # Create pods and services 125 | kubectl apply -f deployments/k8s/network-emulation/pods.yaml 126 | kubectl apply -f deployments/k8s/network-emulation/services.yaml 127 | 128 | # Wait for pods and list pods / services 129 | kubectl wait --for=condition=Ready pods -n ixia-c --all 130 | kubectl get pods -n ixia-c 131 | kubectl get services -n ixia-c 132 | ``` 133 | 134 | 7. Run IPv4 forwarding test using [snappi](https://github.com/open-traffic-generator/snappi/tree/main/gosnappi) which is an auto-generated SDK based on [Open Traffic Generator API](https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/open-traffic-generator/models/master/artifacts/openapi.yaml&nocors) 135 | 136 | The test parameters, e.g. location of KENG controller, name of interfaces, etc. can be modified inside `testConst` map in `ipfwd.go`. 137 | 138 | Check the file for more details on the test. 139 | 140 | ```bash 141 | cd deployments/k8s/network-emulation/ 142 | go run ipfwd.go 143 | cd - 144 | ``` 145 | 146 | 8. (Optional) Cleanup 147 | 148 | ```bash 149 | # remove cluster if deployed using kind 150 | kind delete cluster 151 | sudo rm -rf /usr/local/bin/kubectl 152 | 153 | # remove pods / services / CRDs 154 | kubectl delete -f deployments/k8s/network-emulation/services.yaml 155 | kubectl delete -f deployments/k8s/network-emulation/pods.yaml 156 | kubectl delete -f deployments/k8s/network-emulation/links.yaml 157 | kubectl delete -f deployments/k8s/network-emulation/namespace.yaml 158 | ``` 159 | 160 | ### What's Next ? 161 | 162 | - Checkout Ixia-C Release Page to get compatible client and server builds. 163 | * [All Releases](https://github.com/open-traffic-generator/ixia-c/releases) 164 | * [Latest Release](https://github.com/open-traffic-generator/ixia-c/releases/latest) 165 | - Checkout [OTG Conformance Tests](https://github.com/open-traffic-generator/conformance) for examples on various OTG features written in Go and Python. 166 | - Checkout [OTG Examples](https://github.com/open-traffic-generator/otg-examples) for more comprehensive examples / labs. 167 | -------------------------------------------------------------------------------- /docs/deployments-kne.md: -------------------------------------------------------------------------------- 1 | # Deploy Ixia-c using KNE 2 | 3 | Ixia-c can be deployed in the k8s environment by using the [Kubernetes Network Emulation](https://github.com/openconfig/kne) that consists of the following services: 4 | 5 | * **operator**: Serves API request from the clients and manages workflow across one or more traffic engines. 6 | * **controller**: Serves API request from the clients and manages workflow across one or more traffic engines. 7 | * **traffic-engine**: Generates, captures, and processes the traffic from one or more network interfaces (on linux-based OS). 8 | * **protocol-engine**: Emulates layer3 networks and protocols such as BGP, ISIS, and etc (on linux-based OS). 9 | * **gnmi-server**: Captures statistics from one or more network interfaces (on linux-based OS). 10 | 11 | ## System Prerequisites 12 | 13 | ### CPU and RAM 14 | 15 | Following are the recommended resources for a basic use-case. 16 | 17 | - `keng-operator`: Each instance requires at least 1 CPU core and 2GB RAM. 18 | - `keng-controller`: Each instance requires at least 1 CPU core and 2GB RAM. 19 | - `otg-gnmi-server`: Each instance requires at least 1 CPU core and 2GB RAM. 20 | - `ixia-c-traffic-engine`: Each instance requires 2 dedicated CPU cores and 3GB dedicated RAM. 21 | - `ixia-c-protocol-engine`: Each instance requires 4 dedicated CPU cores and 1GB dedicated RAM per port. 22 | 23 | ### OS and Software Prerequisites 24 | 25 | - x86_64 Linux Distribution (Centos 7+ or Ubuntu 18+ have been tested) 26 | - Docker 19+ (as distributed by https://docs.docker.com/) 27 | - Go 1.17+ 28 | - kind 0.18+ 29 | 30 | ## Install KNE 31 | 32 | * The main use case we are interested in is the ability to bring up arbitrary topologies to represent a production topology. This would require multiple vendors as well as traffic generation and end hosts. 33 | 34 | ```sh 35 | go install github.com/openconfig/kne/kne@latest 36 | ``` 37 | 38 | ## Deploy keng-operator 39 | 40 | * Ixia Operator defines CRD for Ixia network device (IxiaTG) and can be used to build up different network topologies with network devices from other vendors. Network interconnects between the topology nodes can be setup with various container network interface (CNI) plugins for Kubernetes for attaching multiple network interfaces to the nodes. 41 | 42 | ```sh 43 | kubectl apply -f https://github.com/open-traffic-generator/keng-operator/releases/download/v0.3.5/ixiatg-operator.yaml 44 | ``` 45 | 46 | ## Apply configmap 47 | 48 | * The various Ixia component versions to be deployed is derived from the Ixia release version as specified in the IxiaTG config. These component mappings are captured in ixia-configmap.yaml for each Ixia release. The configmap, as shown in the snippet below, comprise of the Ixia release version ("release"), and the list of qualified component versions, for that release. Ixia Operator first tries to access these details from Keysight published releases; if unable to so, it tries to locate them in Kubernetes configmap. This allows users to have the operator load images from private repositories, by updating the configmap entries. Thus, for deployment with custom images, the user is expected to download release specific ixia-configmap.yaml from published releases. Then, in the configmap, update the specific container image "path" / "tag" fields and also update the "release" to some custom name. Start the operator first as specified in the deployment section below, before applying the configmap locally. After this the operator can be used to deploy the containers and services. 49 | 50 | * For community users, 51 | 52 | ```json 53 | apiVersion: v1 54 | kind: ConfigMap 55 | metadata: 56 | name: ixiatg-release-config 57 | namespace: ixiatg-op-system 58 | data: 59 | versions: | 60 | { 61 | "release": "1.42.0-4", 62 | "images": [ 63 | { 64 | "name": "controller", 65 | "path": "ghcr.io/open-traffic-generator/keng-controller", 66 | "tag": "1.42.0-4" 67 | }, 68 | { 69 | "name": "gnmi-server", 70 | "path": "ghcr.io/open-traffic-generator/otg-gnmi-server", 71 | "tag": "1.42.4" 72 | }, 73 | { 74 | "name": "traffic-engine", 75 | "path": "ghcr.io/open-traffic-generator/ixia-c-traffic-engine", 76 | "tag": "1.8.0.245" 77 | }, 78 | { 79 | "name": "protocol-engine", 80 | "path": "ghcr.io/open-traffic-generator/ixia-c-protocol-engine", 81 | "tag": "1.00.0.488" 82 | }, 83 | { 84 | "name": "ixhw-server", 85 | "path": "ghcr.io/open-traffic-generator/keng-layer23-hw-server", 86 | "tag": "1.42.0-4" 87 | } 88 | ] 89 | } 90 | ``` 91 | 92 | * For commercial users, `LICENSE_SERVERS` needs to be specified for `keng-controller` deployment. 93 | 94 | ```json 95 | apiVersion: v1 96 | kind: ConfigMap 97 | metadata: 98 | name: ixiatg-release-config 99 | namespace: ixiatg-op-system 100 | data: 101 | versions: | 102 | { 103 | "release": "1.42.0-4", 104 | "images": [ 105 | { 106 | "name": "controller", 107 | "path": "ghcr.io/open-traffic-generator/keng-controller", 108 | "tag": "1.42.0-4", 109 | "env": { 110 | "LICENSE_SERVERS": "ip/hostname of license server" 111 | } 112 | }, 113 | { 114 | "name": "gnmi-server", 115 | "path": "ghcr.io/open-traffic-generator/otg-gnmi-server", 116 | "tag": "1.42.4" 117 | }, 118 | { 119 | "name": "traffic-engine", 120 | "path": "ghcr.io/open-traffic-generator/ixia-c-traffic-engine", 121 | "tag": "1.8.0.245" 122 | }, 123 | { 124 | "name": "protocol-engine", 125 | "path": "ghcr.io/open-traffic-generator/ixia-c-protocol-engine", 126 | "tag": "1.00.0.488" 127 | }, 128 | { 129 | "name": "ixhw-server", 130 | "path": "ghcr.io/open-traffic-generator/keng-layer23-hw-server", 131 | "tag": "1.42.0-4" 132 | } 133 | ] 134 | } 135 | ``` 136 | 137 | ```sh 138 | # After saving the configmap snippet in a yaml file 139 | kubectl apply -f ixiatg-configmap.yaml 140 | ``` 141 | 142 | ## Deploy the topology 143 | 144 | * The following snippet shows a simple KNE b2b topology. 145 | 146 | ```yaml 147 | name: ixia-c 148 | nodes: 149 | - name: otg 150 | vendor: KEYSIGHT 151 | version: 1.42.0-4 152 | services: 153 | 8443: 154 | name: https 155 | inside: 8443 156 | 40051: 157 | name: grpc 158 | inside: 40051 159 | 50051: 160 | name: gnmi 161 | inside: 50051 162 | links: 163 | - a_node: otg 164 | a_int: eth1 165 | z_node: otg 166 | z_int: eth2 167 | ``` 168 | 169 | ```sh 170 | # After saving the topology snippet in a yaml file 171 | kne create topology.yaml 172 | ``` 173 | 174 | * After deployment, you are now ready to run a test using this topology. 175 | 176 | ## Destroy/Remove the topology 177 | 178 | ```sh 179 | # delete a particular topology 180 | kne delete topology.yaml 181 | ``` 182 | -------------------------------------------------------------------------------- /deployments/k8s/network-emulation/go.sum: -------------------------------------------------------------------------------- 1 | github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= 2 | github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= 3 | github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= 4 | github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= 5 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= 6 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 7 | github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= 8 | github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= 9 | github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= 10 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 11 | github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 12 | github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= 13 | github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 14 | github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= 15 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= 16 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 17 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 18 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 19 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 20 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 21 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 22 | github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= 23 | github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= 24 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= 25 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= 26 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 27 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 28 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 29 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 30 | github.com/open-traffic-generator/snappi/gosnappi v1.42.0 h1:T31pf1OCrIgBp2kR1j3xJzznLJxb2EQlR0M9vGyR+EY= 31 | github.com/open-traffic-generator/snappi/gosnappi v1.42.0/go.mod h1:sEsjIwvO/XpaL79kpU47mKZoxPc3M5ljm5MXySU9xs0= 32 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= 33 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 34 | github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= 35 | github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= 36 | github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= 37 | github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= 38 | go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= 39 | go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= 40 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= 41 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= 42 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= 43 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= 44 | go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= 45 | go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= 46 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= 47 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= 48 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= 49 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= 50 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= 51 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= 52 | go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= 53 | go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= 54 | go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= 55 | go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= 56 | go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= 57 | go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= 58 | go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= 59 | go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= 60 | go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= 61 | go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= 62 | go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= 63 | go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= 64 | golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= 65 | golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= 66 | golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= 67 | golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 68 | golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= 69 | golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= 70 | gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= 71 | gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= 72 | google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= 73 | google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= 74 | google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= 75 | google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= 76 | google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= 77 | google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= 78 | google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= 79 | google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= 80 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 81 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 82 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 83 | gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= 84 | gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= 85 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 86 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 87 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 88 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 89 | -------------------------------------------------------------------------------- /docs/deployments.md: -------------------------------------------------------------------------------- 1 | # Deployment 2 | 3 | ## Overview 4 | 5 | Ixia-c is distributed and deployed as a multi-container application that consists of the following services: 6 | 7 | * **controller**: Serves API request from the clients and manages workflow across one or more traffic engines. 8 | * **traffic-engine**: Generates, captures, and processes traffic from one or more network interfaces (on linux-based OS). 9 | * **app-usage-reporter**: (Optional) Collects anonymous usage report from the controller and uploads it to the Keysight Cloud, with minimal impact on the host resources. 10 | 11 | All these services are available as docker images on the [GitHub Open-Traffic-Generator repository](https://github.com/orgs/open-traffic-generator/packages). To use specific versions of these images, see [Ixia-c Releases](releases.md) . 12 | 13 | ![ixia-c-aur](res/ixia-c-aur.drawio.svg "ixia-c-aur") 14 | 15 | > Once the services are deployed, [conformance](https://github.com/open-traffic-generator/conformance/tree/main) (a collection of [snappi](https://pypi.org/project/snappi/) & [gosnappi](https://otg.dev/clients/gosnappi/) test scripts and configurations) can be setup to run against Ixia-c. 16 | 17 | ## Bootstrap 18 | 19 | The Ixia-c services can either all be deployed on the same host or each on separate hosts (as long as they are mutually reachable over the network). There is no boot-time dependency between them, which allows **horizontal scalability** without interrupting the existing services. 20 | 21 | You can establish a connectivity between the services in two ways. The options are as follows: 22 | 23 | - **controller & traffic-engine**: The client pushes a traffic configuration to the controller, containing the `location` of the traffic engine. 24 | - **controller & app-usage-reporter**: The Controller periodically tries to establish connectivity with the `app-usage-reporter` on a `location`, which can be overridden by using the controller's deployment parameters. 25 | 26 | >The **location** (network address) of the traffic-engine and the app-usage-reporter must be reachable from the controller, even if they are not reachable from the client scripts. 27 | 28 | ## Deployment types 29 | 30 | * [Using docker-compose](deployments-docker-compose.md) 31 | 32 | * [Using containerlab](deployments-containerlab.md) 33 | 34 | * [Using KNE](deployments-kne.md) 35 | 36 | ## Diagnostics 37 | 38 | Check and download controller logs: 39 | 40 | ```sh 41 | docker exec cat logs/controller.log 42 | # follow logs 43 | docker exec tail -f logs/controller.log 44 | # check stdout output 45 | docker logs 46 | # download logs 47 | docker cp :$(docker exec readlink -f logs/controller.log) ./ 48 | ``` 49 | 50 | Check and download traffic-engine logs: 51 | 52 | ```sh 53 | docker exec cat /var/log/usstream/usstream.log 54 | # follow logs 55 | docker exec tail -f /var/log/usstream/usstream.log 56 | # check stdout output 57 | docker logs 58 | # download logs 59 | docker cp :/var/log/usstream/usstream.log ./ 60 | ``` 61 | 62 | ## Test Suite 63 | 64 | ## One-arm Scenario 65 | 66 | > TODO: diagram 67 | 68 | * Automated 69 | 70 | ```bash 71 | docker-compose -f deployments/raw-one-arm.yml up -d # community users 72 | # optionally stop and remove services deployed 73 | docker-compose -f deployments/raw-one-arm.yml down # community users 74 | ``` 75 | 76 | * Manual 77 | 78 | ```bash 79 | # start controller and app usage reporter 80 | 81 | # community users 82 | docker run --net=host -d ghcr.io/open-traffic-generator/keng-controller --accept-eula 83 | # commercial users 84 | docker run --net=host -d ghcr.io/open-traffic-generator/keng-controller --accept-eula --license-servers="ip/hostname of license server" 85 | docker run --net=host -d ghcr.io/open-traffic-generator/keng-app-usage-reporter 86 | 87 | # start traffic engine on network interface eth1, TCP port 5555 and cpu cores 0, 1, 2 88 | docker run --net=host --privileged -d \ 89 | -e OPT_LISTEN_PORT="5555" \ 90 | -e ARG_IFACE_LIST="virtual@af_packet,eth1" \ 91 | -e OPT_NO_HUGEPAGES="Yes" \ 92 | --cpuset-cpus="0,1,2" \ 93 | ghcr.io/open-traffic-generator/ixia-c-traffic-engine 94 | ``` 95 | 96 | ## Two-arm Scenario 97 | 98 | > TODO: diagram 99 | 100 | * Automated 101 | 102 | ```bash 103 | docker-compose -f deployments/raw-two-arm.yml up -d # community users 104 | # optionally stop and remove services deployed 105 | docker-compose -f deployments/raw-two-arm.yml down # community users 106 | ``` 107 | 108 | * Manual 109 | 110 | ```bash 111 | # start controller and app usage reporter 112 | # community users 113 | docker run --net=host -d ghcr.io/open-traffic-generator/keng-controller --accept-eula 114 | # commercial users 115 | docker run --net=host -d ghcr.io/open-traffic-generator/keng-controller --accept-eula --license-servers="ip/hostname of license server" 116 | docker run --net=host -d ghcr.io/open-traffic-generator/keng-app-usage-reporter 117 | 118 | # start traffic engine on network interface eth1, TCP port 5555 and cpu cores 0, 1, 2 119 | docker run --net=host --privileged -d \ 120 | -e OPT_LISTEN_PORT="5555" \ 121 | -e ARG_IFACE_LIST="virtual@af_packet,eth1" \ 122 | -e OPT_NO_HUGEPAGES="Yes" \ 123 | --cpuset-cpus="0,1,2" \ 124 | ghcr.io/open-traffic-generator/ixia-c-traffic-engine 125 | 126 | # start traffic engine on network interface eth2, TCP port 5556 and cpu cores 0, 3, 4 127 | docker run --net=host --privileged -d \ 128 | -e OPT_LISTEN_PORT="5556" \ 129 | -e ARG_IFACE_LIST="virtual@af_packet,eth2" \ 130 | -e OPT_NO_HUGEPAGES="Yes" \ 131 | --cpuset-cpus="0,3,4" \ 132 | ghcr.io/open-traffic-generator/ixia-c-traffic-engine 133 | ``` 134 | 135 | ## Three-arm Mesh Scenario 136 | 137 | This scenario binds traffic engine to the management network interface, that belongs to the container which in turn is a part of the docker0 network. 138 | 139 | > TODO: diagram 140 | 141 | * Automated 142 | 143 | ```bash 144 | docker-compose -f deployments/raw-three-arm-mesh.yml up -d # community users 145 | # optionally stop and remove services deployed 146 | docker-compose -f deployments/raw-three-arm-mesh.yml down # community users 147 | ``` 148 | 149 | * Manual 150 | 151 | ```bash 152 | # start controller and app usage reporter 153 | # community users 154 | docker run --net=host -d ghcr.io/open-traffic-generator/keng-controller --accept-eula 155 | # commercial users 156 | docker run --net=host -d ghcr.io/open-traffic-generator/keng-controller --accept-eula --license-servers="ip/hostname of license server" 157 | docker run --net=host -d ghcr.io/open-traffic-generator/keng-app-usage-reporter 158 | 159 | # start traffic engine on network interface eth0, TCP port 5555 and cpu cores 0, 1, 2 160 | docker run --privileged -d \ 161 | -e OPT_LISTEN_PORT="5555" \ 162 | -e ARG_IFACE_LIST="virtual@af_packet,eth0" \ 163 | -e OPT_NO_HUGEPAGES="Yes" \ 164 | -p 5555:5555 \ 165 | --cpuset-cpus="0,1,2" \ 166 | ghcr.io/open-traffic-generator/ixia-c-traffic-engine 167 | 168 | # start traffic engine on network interface eth0, TCP port 5556 and cpu cores 0, 3, 4 169 | docker run --privileged -d \ 170 | -e OPT_LISTEN_PORT="5555" \ 171 | -e ARG_IFACE_LIST="virtual@af_packet,eth0" \ 172 | -e OPT_NO_HUGEPAGES="Yes" \ 173 | -p 5556:5555 \ 174 | --cpuset-cpus="0,3,4" \ 175 | ghcr.io/open-traffic-generator/ixia-c-traffic-engine 176 | 177 | # start traffic engine on network interface eth0, TCP port 5557 and cpu cores 0, 5, 6 178 | docker run --privileged -d \ 179 | -e OPT_LISTEN_PORT="5555" \ 180 | -e ARG_IFACE_LIST="virtual@af_packet,eth0" \ 181 | -e OPT_NO_HUGEPAGES="Yes" \ 182 | -p 5557:5555 \ 183 | --cpuset-cpus="0,5,6" \ 184 | ghcr.io/open-traffic-generator/ixia-c-traffic-engine 185 | ``` 186 | 187 | ### TODO: Multi-port per TE container 188 | 189 | ## Tests 190 | 191 | Please follow [readme](https://github.com/open-traffic-generator/conformance/blob/main/readme.md) to run sample go/python tests. 192 | -------------------------------------------------------------------------------- /docs/faq.md: -------------------------------------------------------------------------------- 1 | # FAQ 2 | 3 | - [Table of Contents](readme.md) 4 | - FAQ 5 | - [Ixia-c, Open Traffic Generator and snappi](#ixia-c-open-traffic-generator-and-snappi) 6 | - [Diagnostics](#diagnostics) 7 | - [Packets](#packets) 8 | - [Application Usage Reporter](#application-usage-reporter) 9 | - [Ixia-c Free Version](#Ixia-c-free-version) 10 | - [Troubleshooting](#troubleshooting) 11 | - [Support](#support) 12 | 13 | ## Ixia-c, Open Traffic Generator and snappi 14 | 15 |
16 | 17 | What is the relationship between Open Traffic Generator data models, snappi and Ixia-c? 18 | 19 |
20 | 21 | The [Open Traffic Generator](https://github.com/open-traffic-generator/models) data models describe a vendor neutral data models and APIs for test traffic generation. The models are based on OpenAPI v3. Ixia-c is a traffic generator that complies with these APIs. [snappi](https://github.com/open-traffic-generator/snappi) is a *Pythonic* client library that can be used to write tests that run against Ixia-c. 22 | 23 | The following two diagrams illustrate this relationship. 24 | 25 |
26 |
27 | 28 |
29 |
30 |
31 |
32 | 33 |
34 |
35 |
36 | 37 |
38 | 39 | Where can I find a tutorial on snappi? 40 | 41 |
42 | 43 | The [Hello snappi](hello-snappi.md) tutorial is a good starting point to get familiar with `snappi`. 44 |
45 | 46 |
47 | 48 | How to use other non-Python clients? 49 | 50 |
51 | 52 | TODO: Fill in details here. 53 |
54 | 55 |
56 | 57 | Can I use curl to control Ixia-c? 58 | 59 |
60 | 61 | Yes. Refer to the [Quick Start](../readme.md##quick-start) on the Ixia-c home page. 62 |
63 | 64 | ## Diagnostics 65 | 66 |
67 | 68 | What version of the Open Traffic Generator spec does Ixia-c implement? 69 | 70 |
71 | 72 | Ixia-c implements version **[v0.12.5](https://github.com/open-traffic-generator/models/releases/tag/v0.12.5)** of the Open Traffic Generator Data Model. You can view the model [here](https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/open-traffic-generator/models/v0.12.5/artifacts/openapi.yaml). 73 | 74 |
75 | 76 |
77 | 78 | How to find version of Open Traffic Generator spec implemented by Ixia-c? 79 | 80 |
81 | 82 | Open Traffic Generator Data Model can be accessed from any browser by pointing it to (https://\/docs/openapi.json). The `info` section contains the `version` of the Open Traffic Generator Data Model implemented by the KENG controller. 83 | 84 |
85 | 86 | ## Packets 87 | 88 |
89 | 90 | What do packets look like? 91 | 92 |
93 | 94 | Ixia packet testers utilize a proprietary flow-tracking technique which involves inserting a special *instrumentation header* into the packet. It is inserted after the last valid protocol header ie, in the payload. 95 | 96 |
97 |
98 | 99 |
100 |
101 | 102 | The fields in this header are: 103 | 104 | - a *signature* which servers as marker to indicate start of header 105 | - a *PGID* or *port group id* field to distinguish between different flows 106 | - a 32 bit *sequence number* that can be used to detect packet re-ordering 107 | - a 32 bit timestamp that can be used to measure one-way latency 108 | 109 |
110 | 111 |
112 | 113 | How do I disable packet instrumentation? 114 | 115 |
116 | 117 | According to the Open Traffic Generator data model packet instrumentation is enabled by default on all the flows. It is not possible to disable it at the moment. An update to the data model that allows the end user to disable instrumentation is in the process of being merged into the *main* branch and will be submitted in the coming weeks. Ixia-c will implement it at that point. 118 | 119 |
120 | 121 |
122 | 123 | Does Ixia-c calculate packet checksums? If so, which ones? 124 | 125 |
126 | 127 | Yes, the Ixia-c traffic-engine automatically calculates the Ethernet FCS, IPv4, TCP and UDP checksums. The traffic-engine is capable of calculating *four* checksums (in each packet). TODO: verify. 128 |
129 | 130 |
131 | 132 | What layer1 settings does Ixia-c utilize? 133 | 134 |
135 | 136 | The only `layer1` setting that is used by the Ixia-c traffic engine is `speed`. This setting is used to help convert flow rate specified as *percentage line-rate* into packets/second (pps) and to ensure that proper inter-packet-gaps are used. 137 |
138 | 139 |
140 | 141 | What is the purpose of the layer1 setting speed? 142 | 143 |
144 | 145 | To calculate packets/second (pps) when the flow rate is specified as *percentage line-rate* and to ensure proper inter-packet-gaps. 146 |
147 | 148 | ## Application Usage Reporter 149 | 150 |
151 | 152 | What is Application Usage Reporter? 153 | 154 |
155 | 156 | The `app-usage-reporter` container collects and uploads to the Keysight cloud some basic telemetry information from the KENG controller. This information helps Keysight improve the controller by focusing on the features that are being used by end users. 157 |
158 | 159 |
160 | 161 | What information does Application Usage Reporter collect? 162 | 163 |
164 | 165 | The *Application Usage Reporter* collects configuration related information like the number of ports in a test, number of flows configured, number of values used in a pattern. TODO: Need to give an exhaustive list. 166 |
167 | 168 |
169 | 170 | Does Application Usage Reporter collect any personally identifiable information? 171 | 172 |
173 | 174 | No. The *Application Usage Reporter* does NOT collect any personally identifiable information like username, hostname, email address, etc. 175 |
176 | 177 |
178 | 179 | Does Application Usage Reporter save my IP address? 180 | 181 |
182 | No. 183 |
184 | 185 |
186 | 187 | Can I disable Application Usage Reporter? If so, how? 188 | 189 |
190 | 191 | Yes, the *Application Usage Reporter* can be disabled. Refer to the [Deployment Parameters](deployments.md#deployment-parameters) section in the Deployment Guide. 192 |
193 | 194 | ## Ixia-c Free Version 195 | 196 |
197 | 198 | What are the limitations of the free version of Ixia-c? 199 | 200 |
201 | 202 | The free version of KENG controller supports up to 4 ports in one session and the Ixia-c traffic-engine is limited to running over `raw` sockets. 203 |
204 | 205 |
206 | 207 | What are the differences between the commercial and the free version of Ixia-c? 208 | 209 |
210 | The following table highlights the differences between the commercial and the free version of Ixia-c. 211 | 212 | | Capability | Ixia-c Free | Ixia-c Commercial | 213 | -------------| ------------| ------------------| 214 | | # of Ports | 4 | Unlimited | 215 | | Traffic Engine - Raw | Supported | Supported | 216 | | Traffic Engine - DPDK PCI | Not Supported | Supported | 217 | | Support | Slack Channel | Keysight Support | 218 | 219 |
220 | 221 |
222 | 223 | How do I purchase the commercial version of Ixia-c? 224 | 225 |
226 | 227 | Contact your Keysight Sales Rep or reach out to us [here](https://www.keysight.com/us/en/contact.html). 228 |
229 | 230 | ## Troubleshooting 231 | 232 |
233 | 234 | How do I view KENG controller logs? 235 | 236 |
237 | 238 | Use `docker logs` to view the controller log. 239 |
240 | 241 |
242 | 243 | What is the message "App usage reporting service is down" in KENG controller log? 244 | 245 |
246 | 247 | This message indicates that the `app-usage-reporter` container is not reachable from the KENG controller. This does NOT affect KENG controller's normal operation. Refer to [Deployment Parameters](deployments.md#deployment-parameters) for more details on how to override the default location for the app-usage-reporter or how to disable it all together. 248 |
249 | 250 | ## Support 251 | 252 |
253 | 254 | Where do I get support for the free version of Ixia-c? 255 | 256 |
257 | 258 | Reach out to us on [Slack](support.md) for support. 259 |
260 | -------------------------------------------------------------------------------- /deployments/docker/readme.md: -------------------------------------------------------------------------------- 1 | # Ixia-C Docker Deployment over Raw Socket 2 | 3 | ## Manual Steps 4 | 5 | 1. (Optional) Cleanup all existing containers and images. 6 | 7 | ```sh 8 | docker stop $(docker ps -aq) && docker rm $(docker ps -aq) 9 | docker rmi $(docker images -q) 10 | ``` 11 | 12 | 2. Start an instance of `controller`. 13 | 14 | ```sh 15 | # implicitly listens on TCP port 8443 and 40051 16 | # --accept-eula option is confirmation that user has accepted the Ixia-C End-User License Agreement (EULA) 17 | # located at https://github.com/open-traffic-generator/ixia-c/blob/main/docs/eula.md 18 | docker run -d \ 19 | --name=keng-controller \ 20 | --publish 0.0.0.0:8443:8443 \ 21 | --publish 0.0.0.0:40051:40051 \ 22 | ghcr.io/open-traffic-generator/keng-controller:1.42.0-4 \ 23 | --accept-eula \ 24 | --trace \ 25 | --disable-app-usage-reporter 26 | ``` 27 | 28 | 29 | 3. Start one or more instances of `traffic-engine`. 30 | 31 | - For `traffic-engine` over raw socket: 32 | 33 | ```sh 34 | # for network interface eth1 35 | docker run --privileged -d \ 36 | --name=ixia-c-traffic-engine-eth1 \ 37 | -e OPT_LISTEN_PORT="5555" \ 38 | -e ARG_IFACE_LIST="virtual@af_packet,eth1" \ 39 | -e OPT_NO_HUGEPAGES="Yes" \ 40 | -e OPT_NO_PINNING="Yes" \ 41 | -e WAIT_FOR_IFACE="Yes" \ 42 | -e OPT_ADAPTIVE_CPU_USAGE="Yes" \ 43 | ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.8.0.245 44 | 45 | # for network interface eth2 46 | docker run --privileged -d \ 47 | --name=ixia-c-traffic-engine-eth2 \ 48 | -e OPT_LISTEN_PORT="5555" \ 49 | -e ARG_IFACE_LIST="virtual@af_packet,eth2" \ 50 | -e OPT_NO_HUGEPAGES="Yes" \ 51 | -e OPT_NO_PINNING="Yes" \ 52 | -e WAIT_FOR_IFACE="Yes" \ 53 | -e OPT_ADAPTIVE_CPU_USAGE="Yes" \ 54 | ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.8.0.245 55 | ``` 56 | 57 | 4. Start one or more instances of `protocol-engine`. 58 | 59 | - For `protocol-engine` over raw socket: 60 | 61 | ```sh 62 | # for network interface eth1 63 | docker run --privileged -d \ 64 | --net=container:ixia-c-traffic-engine-eth1 \ 65 | --name=ixia-c-protocol-engine-eth1 \ 66 | -e INTF_LIST="eth1" \ 67 | ghcr.io/open-traffic-generator/ixia-c-protocol-engine:1.00.0.488 \ 68 | 69 | # for network interface eth2 70 | docker run --privileged -d \ 71 | --net=container:ixia-c-traffic-engine-eth2 \ 72 | --name=ixia-c-protocol-engine-eth2 \ 73 | -e INTF_LIST="eth2" \ 74 | ghcr.io/open-traffic-generator/ixia-c-protocol-engine:1.00.0.488 75 | ``` 76 | 77 | 5. Ensure existing network interfaces are `Up` and have `Promiscuous` mode enabled. 78 | 79 | ```sh 80 | # check interface details 81 | sudo ip addr 82 | # configure as required 83 | sudo ip link set eth1 up 84 | sudo ip link set eth1 promisc on 85 | sudo ip link set eth2 up 86 | sudo ip link set eth2 promisc on 87 | ``` 88 | 89 | 6. Push interface to the containers. 90 | - It takes a host NIC (say eth1) and injects it into a container’s network namespace so the container can directly use that NIC (bypassing Docker’s default bridge). 91 | It symlinks the container’s netns into /var/run/netns, then moves and configures the interface inside that namespace. 92 | 93 | ```sh 94 | 95 | # For Traffic Engine 1 96 | # Resolve container metadata 97 | cid=$(docker inspect --format="{{json .Id}}" ixia-c-traffic-engine-eth1 | cut -d\" -f 2) 98 | cpid=$(docker inspect --format="{{json .State.Pid}}" ixia-c-traffic-engine-eth1 | cut -d\" -f 2) 99 | 100 | # Prepare namespace paths 101 | orgPath=/proc/${cpid}/ns/net 102 | newPath=/var/run/netns/${cid} 103 | 104 | # Make namespace accessible to ip netns 105 | sudo mkdir -p /var/run/netns 106 | sudo ln -s ${orgPath} ${newPath} 107 | # Move interface into the container’s netns 108 | sudo ip link set eth1 netns ${cid} 109 | # Rename and configure inside the container 110 | sudo ip netns exec ${cid} ip link set eth1 name eth1 111 | sudo ip netns exec ${cid} ip -4 addr add 0/0 dev eth1 112 | sudo ip netns exec ${cid} ip -4 link set eth1 up 113 | 114 | # For Traffic Engine 2 115 | # Resolve container metadata 116 | cid=$(docker inspect --format="{{json .Id}}" ixia-c-traffic-engine-eth2 | cut -d\" -f 2) 117 | cpid=$(docker inspect --format="{{json .State.Pid}}" ixia-c-traffic-engine-eth2 | cut -d\" -f 2) 118 | 119 | # Prepare namespace paths 120 | orgPath=/proc/${cpid}/ns/net 121 | newPath=/var/run/netns/${cid} 122 | 123 | # Make namespace accessible to ip netns 124 | sudo mkdir -p /var/run/netns 125 | sudo ln -s ${orgPath} ${newPath} 126 | # Move interface into the container’s netns 127 | sudo ip link set eth2 netns ${cid} 128 | # Rename and configure inside the container 129 | sudo ip netns exec ${cid} ip link set eth2 name eth2 130 | sudo ip netns exec ${cid} ip -4 addr add 0/0 dev eth2 131 | sudo ip netns exec ${cid} ip -4 link set eth2 up 132 | ``` 133 | 134 | 6. Create interface-port config-map inside `keng-controller`. 135 | ```sh 136 | configDir=/home/ixia-c/controller/config 137 | OTG_PORTA=$(docker inspect --format="{{json .NetworkSettings.IPAddress}}" ixia-c-traffic-engine-eth1 | cut -d\" -f 2) 138 | OTG_PORTZ=$(docker inspect --format="{{json .NetworkSettings.IPAddress}}" ixia-c-traffic-engine-eth2 | cut -d\" -f 2) 139 | 140 | yml="location_map: 141 | - location: ${ETH_A} 142 | endpoint: \"${OTG_PORTA}:5555+${OTG_PORTA}:50071\" 143 | - location: ${ETH_Z} 144 | endpoint: \"${OTG_PORTZ}:5555+${OTG_PORTZ}:50071\" 145 | " 146 | echo -n "$yml" | sed "s/^ //g" | tee ./config.yaml > /dev/null \ 147 | && docker exec keng-controller mkdir -p ${configDir} \ 148 | && docker cp ./config.yaml keng-controller:${configDir}/ \ 149 | && rm -rf ./config.yaml 150 | ``` 151 | 152 | ## Automated Steps 153 | ```sh 154 | git clone --recurse-submodule https://github.com/open-traffic-generator/ixia-c.git 155 | cd ixia-c/deployments/docker 156 | chmod u+x ./deployment.sh 157 | 158 | # deploy control & data plane 159 | ./deployment.sh eth1 eth2 topo new 160 | 161 | # teardown control & data plane 162 | ./deployment.sh eth1 eth2 topo rm 163 | 164 | # deploy data plane only 165 | DATA_PLANE_ONLY=true ./deployment.sh eth1 eth2 topo new 166 | 167 | # teardown data plane only 168 | DATA_PLANE_ONLY=true ./deployment.sh eth1 eth2 topo rm 169 | 170 | #create veth pair [ if needed ] 171 | ./deployment.sh veth1 veth2 create 172 | ``` 173 | 174 | 175 | ## Sample go snippet to use after deployment for testing 176 | ```go 177 | // Create a new API handle to make API calls against OTG 178 | api := gosnappi.NewApi() 179 | 180 | // Set the transport protocol to HTTP 181 | api.NewHttpTransport().SetLocation("https://localhost:8443") 182 | 183 | // Create a new traffic configuration that will be set on OTG 184 | config := gosnappi.NewConfig() 185 | 186 | // Add a test port to the configuration 187 | ptx := config.Ports().Add().SetName("ptx").SetLocation("eth1") 188 | prx := config.Ports().Add().SetName("prx").SetLocation("eth2") 189 | ``` 190 | 191 | ## Example Go test 192 | - Setup 193 | ```bash 194 | git clone --recurse-submodule https://github.com/open-traffic-generator/conformance.git 195 | cd conformance 196 | go mod tidy 197 | go mod download 198 | ``` 199 | - Test for control & data plane 200 | ```bash 201 | go test -tags=all ./examples -run TestQuickstartB2BCpDp -args -portA=eth1 -portZ=eth2 202 | ``` 203 | - Test for data plane only 204 | ```bash 205 | go test -tags=all ./examples -run TestQuickstartB2BDp -args -portA=eth1 -portZ=eth2 206 | ``` 207 | 208 | 209 | 210 | 211 | 212 | 213 | -------------------------------------------------------------------------------- /deployments/docker/deployment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | 5 | VERSIONS_YAML_LOC="https://github.com/open-traffic-generator/ixia-c/releases/download/v1.42.0-4/versions.yaml" 6 | VERSIONS_YAML="versions.yaml" 7 | CTRL_IMAGE="ghcr.io/open-traffic-generator/keng-controller" 8 | TE_IMAGE="ghcr.io/open-traffic-generator/ixia-c-traffic-engine" 9 | PE_IMAGE="ghcr.io/open-traffic-generator/ixia-c-protocol-engine" 10 | 11 | if [ -n "$AUTH_TOKEN" ]; then 12 | curl -lO -H "Authorization: Bearer $AUTH_TOKEN" $VERSIONS_YAML_LOC 13 | else 14 | curl -kLO $VERSIONS_YAML_LOC 15 | fi 16 | 17 | TIMEOUT_SECONDS=300 18 | 19 | # --- Argument parsing for ETH_A and ETH_Z --- 20 | if [ -z "$1" ] || [ -z "$2" ]; then 21 | echo "usage: $0 [args...]" 22 | exit 1 23 | fi 24 | 25 | ETH_A=$1 26 | ETH_Z=$2 27 | shift 2 28 | 29 | set_docker_permission() { 30 | if ! groups $USER | grep -q '\bdocker\b'; then 31 | echo "Adding $USER to docker group (relogin required to take effect)." 32 | sudo usermod -aG docker $USER 33 | fi 34 | docker ps -a 35 | } 36 | 37 | set_docker_permission 38 | 39 | configq() { 40 | # echo is needed to further evaluate the 41 | # contents extracted from configuration 42 | eval echo $(yq "${@}" versions.yaml) 43 | } 44 | 45 | push_ifc_to_container() { 46 | # It takes a host NIC (say eth1) and injects it into a container’s 47 | # network namespace so the container can directly use that NIC (bypassing Docker’s default bridge). 48 | # It symlinks the container’s netns into /var/run/netns, 49 | # then moves and configures the interface inside that namespace. 50 | if [ -z "${1}" ] || [ -z "${2}" ] 51 | then 52 | echo "usage: ${0} push_ifc_to_container " 53 | exit 1 54 | fi 55 | 56 | # Resolve container metadata 57 | cid=$(container_id ${2}) 58 | cpid=$(container_pid ${2}) 59 | 60 | echo "Changing namespace of ifc ${1} to container ID ${cid} pid ${cpid}" 61 | 62 | # Prepare namespace paths 63 | orgPath=/proc/${cpid}/ns/net 64 | newPath=/var/run/netns/${cid} 65 | 66 | # Make namespace accessible to ip netns 67 | # Move interface into the container’s netns 68 | # Rename and configure inside the container 69 | sudo mkdir -p /var/run/netns 70 | echo "Creating symlink ${orgPath} -> ${newPath}" 71 | sudo ln -s ${orgPath} ${newPath} \ 72 | && sudo ip link set ${1} netns ${cid} \ 73 | && sudo ip netns exec ${cid} ip link set ${1} name ${1} \ 74 | && sudo ip netns exec ${cid} ip -4 addr add 0/0 dev ${1} \ 75 | && sudo ip netns exec ${cid} ip -4 link set ${1} up \ 76 | && echo "Successfully changed namespace of ifc ${1}" 77 | 78 | sudo rm -rf ${newPath} 79 | } 80 | 81 | container_id() { 82 | docker inspect --format="{{json .Id}}" ${1} | cut -d\" -f 2 83 | } 84 | 85 | container_pid() { 86 | docker inspect --format="{{json .State.Pid}}" ${1} | cut -d\" -f 2 87 | } 88 | 89 | container_ip() { 90 | docker inspect --format="{{json .NetworkSettings.IPAddress}}" ${1} | cut -d\" -f 2 91 | } 92 | 93 | ixia_c_img_tag() { 94 | tag=$(grep ${1} ${VERSIONS_YAML} | cut -d: -f2 | cut -d\ -f2) 95 | echo "${tag}" 96 | } 97 | 98 | ixia_c_traffic_engine_img() { 99 | echo "${TE_IMAGE}:$(ixia_c_img_tag ixia-c-traffic-engine)" 100 | } 101 | 102 | ixia_c_protocol_engine_img() { 103 | echo "${PE_IMAGE}:$(ixia_c_img_tag ixia-c-protocol-engine)" 104 | } 105 | 106 | keng_controller_img() { 107 | echo "${CTRL_IMAGE}:$(ixia_c_img_tag keng-controller)" 108 | } 109 | 110 | gen_controller_config_b2b_cpdp() { 111 | configdir=/home/ixia-c/controller/config 112 | OTG_PORTA=$(container_ip ixia-c-traffic-engine-${ETH_A}) 113 | OTG_PORTZ=$(container_ip ixia-c-traffic-engine-${ETH_Z}) 114 | 115 | wait_for_sock ${OTG_PORTA} 5555 116 | wait_for_sock ${OTG_PORTA} 50071 117 | wait_for_sock ${OTG_PORTZ} 5555 118 | wait_for_sock ${OTG_PORTZ} 50071 119 | 120 | yml="location_map: 121 | - location: ${ETH_A} 122 | endpoint: \"${OTG_PORTA}:5555+${OTG_PORTA}:50071\" 123 | - location: ${ETH_Z} 124 | endpoint: \"${OTG_PORTZ}:5555+${OTG_PORTZ}:50071\" 125 | " 126 | echo -n "$yml" | sed "s/^ //g" | tee ./config.yaml > /dev/null \ 127 | && docker exec keng-controller mkdir -p ${configdir} \ 128 | && docker cp ./config.yaml keng-controller:${configdir}/ \ 129 | && rm -rf ./config.yaml 130 | } 131 | 132 | gen_controller_config_b2b_dp() { 133 | configdir=/home/ixia-c/controller/config 134 | OTG_PORTA=$(container_ip ixia-c-traffic-engine-${ETH_A}) 135 | OTG_PORTZ=$(container_ip ixia-c-traffic-engine-${ETH_Z}) 136 | 137 | wait_for_sock ${OTG_PORTA} 5555 138 | wait_for_sock ${OTG_PORTZ} 5555 139 | 140 | yml="location_map: 141 | - location: ${ETH_A} 142 | endpoint: \"${OTG_PORTA}:5555\" 143 | - location: ${ETH_Z} 144 | endpoint: \"${OTG_PORTZ}:5555\" 145 | " 146 | echo -n "$yml" | sed "s/^ //g" | tee ./config.yaml > /dev/null \ 147 | && docker exec keng-controller mkdir -p ${configdir} \ 148 | && docker cp ./config.yaml keng-controller:${configdir}/ \ 149 | && rm -rf ./config.yaml 150 | } 151 | 152 | wait_for_sock() { 153 | TIMEOUT_SECONDS=30 154 | if [ ! -z "${3}" ] 155 | then 156 | TIMEOUT_SECONDS=${3} 157 | fi 158 | echo "Waiting for ${1}:${2} to be ready (timeout=${TIMEOUT_SECONDS}s)..." 159 | elapsed=0 160 | TIMEOUT_SECONDS=$(($TIMEOUT_SECONDS * 10)) 161 | while true 162 | do 163 | nc -z -v ${1} ${2} && return 0 164 | 165 | elapsed=$(($elapsed+1)) 166 | # echo "Timeout: $TIMEOUT_SECONDS" 167 | # echo "elapsed time: $elapsed" 168 | 169 | if [ $elapsed -gt ${TIMEOUT_SECONDS} ] 170 | then 171 | echo "${1}:${2} to be ready after ${TIMEOUT_SECONDS}" 172 | exit 1 173 | fi 174 | sleep 0.1 175 | done 176 | 177 | } 178 | 179 | prepare_eth_pair() { 180 | if [ -z "${1}" ] || [ -z "${2}" ] 181 | then 182 | echo "usage: ${0} create_veth_pair " 183 | exit 1 184 | fi 185 | 186 | sudo ip link set ${1} up \ 187 | && sudo ip link set ${1} promisc on \ 188 | && sudo ip link set ${2} up \ 189 | && sudo ip link set ${2} promisc on 190 | } 191 | 192 | create_ixia_c_b2b_cpdp() { 193 | docker ps -a 194 | echo "Setting up back-to-back with CP/DP distribution of ixia-c ..." 195 | docker run -d \ 196 | --name=keng-controller \ 197 | --publish 0.0.0.0:8443:8443 \ 198 | --publish 0.0.0.0:40051:40051 \ 199 | $(keng_controller_img) \ 200 | --accept-eula \ 201 | --trace \ 202 | --disable-app-usage-reporter 203 | docker run --privileged -d \ 204 | --name=ixia-c-traffic-engine-${ETH_A} \ 205 | -e OPT_LISTEN_PORT="5555" \ 206 | -e ARG_IFACE_LIST="virtual@af_packet,${ETH_A}" \ 207 | -e OPT_NO_HUGEPAGES="Yes" \ 208 | -e OPT_NO_PINNING="Yes" \ 209 | -e WAIT_FOR_IFACE="Yes" \ 210 | -e OPT_ADAPTIVE_CPU_USAGE="Yes" \ 211 | $(ixia_c_traffic_engine_img) 212 | if [ -z "${DATA_PLANE_ONLY}" ] 213 | then 214 | docker run --privileged -d \ 215 | --net=container:ixia-c-traffic-engine-${ETH_A} \ 216 | --name=ixia-c-protocol-engine-${ETH_A} \ 217 | -e INTF_LIST="${ETH_A}" \ 218 | $(ixia_c_protocol_engine_img) 219 | fi 220 | docker run --privileged -d \ 221 | --name=ixia-c-traffic-engine-${ETH_Z} \ 222 | -e OPT_LISTEN_PORT="5555" \ 223 | -e ARG_IFACE_LIST="virtual@af_packet,${ETH_Z}" \ 224 | -e OPT_NO_HUGEPAGES="Yes" \ 225 | -e OPT_NO_PINNING="Yes" \ 226 | -e WAIT_FOR_IFACE="Yes" \ 227 | -e OPT_ADAPTIVE_CPU_USAGE="Yes" \ 228 | $(ixia_c_traffic_engine_img) 229 | if [ -z "${DATA_PLANE_ONLY}" ] 230 | then 231 | docker run --privileged -d \ 232 | --net=container:ixia-c-traffic-engine-${ETH_Z} \ 233 | --name=ixia-c-protocol-engine-${ETH_Z} \ 234 | -e INTF_LIST="${ETH_Z}" \ 235 | $(ixia_c_protocol_engine_img) 236 | fi 237 | docker ps -a \ 238 | && prepare_eth_pair ${ETH_A} ${ETH_Z} \ 239 | && push_ifc_to_container ${ETH_A} ixia-c-traffic-engine-${ETH_A} \ 240 | && push_ifc_to_container ${ETH_Z} ixia-c-traffic-engine-${ETH_Z} 241 | if [ -z "${DATA_PLANE_ONLY}" ] 242 | then 243 | gen_controller_config_b2b_cpdp $1 244 | else 245 | gen_controller_config_b2b_dp $1 246 | fi 247 | docker ps -a 248 | echo "Successfully deployed !" 249 | } 250 | 251 | rm_ixia_c_b2b_cpdp() { 252 | docker ps -a 253 | echo "Tearing down back-to-back with CP/DP distribution of ixia-c ..." 254 | docker stop keng-controller && docker rm keng-controller 255 | 256 | docker stop ixia-c-traffic-engine-${ETH_A} 257 | docker rm ixia-c-traffic-engine-${ETH_A} 258 | docker stop ixia-c-traffic-engine-${ETH_Z} 259 | docker rm ixia-c-traffic-engine-${ETH_Z} 260 | 261 | if [ -z "${DATA_PLANE_ONLY}" ] 262 | then 263 | docker stop ixia-c-protocol-engine-${ETH_A} 264 | docker rm ixia-c-protocol-engine-${ETH_A} 265 | docker stop ixia-c-protocol-engine-${ETH_Z} 266 | docker rm ixia-c-protocol-engine-${ETH_Z} 267 | fi 268 | docker ps -a 269 | } 270 | 271 | create() { 272 | sudo ip link add $ETH_A type veth peer name $ETH_Z 273 | sudo ip link set $ETH_A up 274 | sudo ip link set $ETH_Z up 275 | } 276 | 277 | topo() { 278 | case $1 in 279 | new ) 280 | create_ixia_c_b2b_cpdp 281 | ;; 282 | rm ) 283 | rm_ixia_c_b2b_cpdp 284 | ;; 285 | * ) 286 | exit 1 287 | ;; 288 | esac 289 | } 290 | 291 | 292 | help() { 293 | grep "() {" ${0} | cut -d\ -f1 294 | } 295 | 296 | usage() { 297 | echo "usage: $0 [name of any function in script]" 298 | exit 1 299 | } 300 | 301 | case $1 in 302 | * ) 303 | cmd=${1} 304 | echo "Hi" 305 | shift 1 306 | ${cmd} "$@" || usage 307 | ;; 308 | esac 309 | -------------------------------------------------------------------------------- /docs/reference/licensing.md: -------------------------------------------------------------------------------- 1 | # Licensing 2 | 3 | ## License consumption mechanism and feature licenses 4 | 5 | Elastic Network Generator [licenses](../licensing.md) include the following features which depends on the license edition. Details on how the features are consumed are as follows: 6 | 7 | ### Feature Licenses 8 | 9 | | Feature Licenses | Developer | Team | System | 10 | |-------------------------------------|----------------------|-----------------|------------------------| 11 | | KENG-SEAT | 1 | 8 | 16 | 12 | | KENG-SEAT​-UHD | N/A | 8 | 16 | 13 | | KENG-SEAT​-IXHW | N/A | N/A | 16 | 14 | | KENG-DPLU | 50 | 400 | 800 | 15 | | KENG-CPLU | 50 | 400 | 800 | 16 | | KENG-UNLIMITED-CP | N/A | N/A | 16 | 17 | 18 | The exact list of feature licenses that are required by a specific test configuration, is calculated based on the test port type, port speed, protocol, protocol sessions, and etc. Overall, the list of required licenses is referred to as Test Cost. 19 | 20 | ### Test Cost Calculation 21 | 22 | ``` 23 | Test Cost = Seat Cost + CP Cost * KENG-CPLU + DP Cost * KENG-DPLU​ 24 | ``` 25 | 26 | | Port Type | Condition | Seat Cost | CP Cost | DP cost | 27 | |------------------|------------------- |-----------------------------------------------------------------------|------------------------- |--------------- | 28 | | Ixia-c SW | `If CP Cost <= 50` | `1x KENG-SEAT` | `SUM (Protocol Cost)` ​ | `SUM (Speed Cost)` | 29 | | Ixia-c SW | `If CP Cost > 50`3 | `1x KENG-SEAT`
`1x KENG-UNLIMITED-CP` | `50` | `SUM (Speed Cost)` | 30 | | UHD400T | `If CP Cost <= 50`​ | `1x KENG-SEAT`​
`1x KENG-SEAT-UHD`​ | `SUM (Protocol Cost)​` | `0` | 31 | | UHD400T | `If CP Cost > 50`3 | `1x KENG-SEAT`
`1x KENG-SEAT-UHD`
`1x KENG-UNLIMITED-CP` | `50` | `0` | 32 | | IxOS Hardware | | `1x KENG-SEAT`
`1x KENG-SEAT-IXHW`​ | `0` | `0` | 33 | 34 | - **Seat** is the number of the running `keng-controller` instances, with a configuration that exceeds the capabilities of the Community Edition. 35 | - **The Data Plane License Unit** (`KENG-DPLU`) is associated with the traffic port capacity. 36 | The number of required units is determined as a sum of the configured port speeds (1, 10, 25, 40, 50, 100GE). The maximum port performance might be less than the configured port speed. 37 | - **The Control Plane License unit** (`KENG-CPLU`) is associated with the control plane protocol scale. The number of required CP units is determined as a sum of the configured protocol sessions. 38 | - If `KENG-UNLIMITED-CP` is not available, an exact number of `KENG-CPLU` will be consumed. 39 | - See [Control Plane Cost](#control-plane-cost) for the `Protocol Cost` and [Data Plane Cost](#data-plane-cost) for the `Speed Cost`. 40 | 41 | ### Control Plane Cost 42 | 43 | Applies only to the Ixia-c software and UHD400T ports. 44 | 45 | ``` 46 | CP Cost = For each Port: SUM (Protocol Cost) 47 | ``` 48 | 49 | | Protocol | Session Definition | Protocol Cost/Session | Comment | 50 | |------------------------------|----------------------------------------- |-----------------------|----------------------- | 51 | | IP Interface (ARP, ND) | devices:
- ethernets:
- ipv4_addresses:
- ipv6_addresses: | 0 | | 52 | | IP Loopbacks​ | devices:
- ipv4_loopbacks:
- ipv6_loopbacks: | 0 | | 53 | | LLDP​ | lldp:
- connection:
- port_name: | 1 | Session = Test Port with LLDP enabled | 54 | | LACP | lacp:
- ports:
- port_name:
lacp: | 1 | Session = LAG group, no matter group size​ | 55 | | BGP | devices:
- bgp:
- ipv4_addresses:
- ipv6_addresses:
- peers:​ | 1 | Session = BGP peer | 56 | | ISIS | devices:
- isis:
- interfaces:
- eth_name: ​ | 1 | Session = ISIS interface | 57 | | RSVP | devices:
- rsvp:
- ipv4_interfaces:
- neighbor_ip: ​ | 1 | Session = RSVP neighbor​ | 58 | 59 | ### Data Plane Cost 60 | 61 | Applies only to the Ixia-c software ports. 62 | 63 | | Test Port Speed | DP Cost | 64 | |------------------------|-----------------| 65 | | 1GE | 1 | 66 | | 10GE | 10 | 67 | | 25GE | 25 | 68 | | 40GE | 40 | 69 | | 50GE | 50 | 70 | | 100GE | 100 | 71 | | 200GE | 200 | 72 | | 400GE | 400 | 73 | 74 | ## Sample license consumption scenarios 75 | 76 | ### Test configuration 77 | 78 | Number of `keng-controller` instances: `1` 79 | 80 | * Number of ports: `4` 81 | * Port type: `Ixia-c software` 82 | * Port Speed: `100GE` 83 | * Protocol scale: `100 BGP sessions/port` 84 | 85 | ### Scenario 1: Limited control plane licenses 86 | 87 | ``` 88 | KENG-SEAT: 1 = (1 keng-controller instance and ixia-c SW port) 89 | KENG-DPLU: 400 = (100G speed * 4 ports) 90 | KENG-CPLU: 400 = (100 BGP sessions/port * 4 ports) 91 | ``` 92 | 93 | ### Scenario 2: Unlimited control plane licenses 94 | 95 | ``` 96 | KENG-SEAT: 1 = (1 keng-controller instance and ixia-c SW port) 97 | KENG-DPLU: 400 = (100G speed * 4 ports) 98 | KENG-CPLU: 50 = (CP cost = 400 (100 BGP sessions/port * 4 ports) which is greater than 50 and unlimited cp capability is present) 99 | KENG-UNLIMITED-CP: 1 100 | ``` 101 | 102 | ## Q&A 103 | 104 |
105 | When the licenses are checked-out / checked-in? 106 |
107 | The license check-out/check-in mechanism in the keng-controller works as follows:
108 | 109 | 1. Calculate the Test Cost. For example, Test Cost = N.
110 | 2. Based on the calculation performed in step (1), check-out the licenses at the time of the OTG SetConfig API call.
111 | 3. Execute the test if license check-out is successful.
112 | 4. For the next configuration, calculate Test Cost, For example, Test Cost = M.
113 | 114 | ``` 115 | if M == N: 116 | - keng-controller will not have any communication with license servers 117 | else if M > N: 118 | - keng-controller will not check-in licenses 119 | - it will attempt to check-out required additional licenses 120 | else if M < N: 121 | - keng-controller will check-in surplus of the licenses 122 | ``` 123 |
124 | 125 |
126 | Does licensing have impact on API response time? 127 |
128 | On the timing aspect, the entire license check-out/check-in mechanism works concurrently with the control plane and the data plane configurations in the ports during the OTG SetConfig operation. Therefore, potentially there is a minimal impact in the OTG SetConfig API response time. If the license server is on a remote site from the controller, the OTG SetConfig API response time might get impacted due to the network latency. 129 |
130 | 131 |
132 | What happens if license servers are not available? 133 |
134 | The keng-controller can work with up to 4 license servers. The controller tries to connect to all the license servers during the startup. If none of them is available, the controller capabilities are reduced to the Community Edition. After that, a background routine is initiated to make recurrent attempts to connect the configured license servers in 30 second intervals.
135 | 136 | Once the controller is able to establish a connection with any of the license servers, for any new configuration beyond capabilities of the Community Edition, the keng-controller will try to check-out a license from the license server with which the connection is established.
137 |
138 | 139 |
140 | What is the message generated when the license server is not available? 141 |
142 | When a configured license server is not reachable, the log message with error code 13 is generated by the keng-controller:
143 |
144 | "level":"warn","ctx":"impl/licensing","Not all license server could be reached":"code: 13 ...error details... " 145 |
146 | 147 |
148 | What is the error generated when a license cannot be checked out? 149 |
150 | There are two possible scenarios when the license cannot checkout.
151 |
152 | Scenario 1: Any of the license servers does not have the adequate license features that are required for the test configuration. It will throw an error with the error code 13 and the following error message:
153 |
154 | Current configuration requires following additional license feature(s): {...details...} which is not available in configured license server(s): {...details...} Available license feature(s) in license-server(s) are {...details...}. 155 |
156 |
157 | Scenario 2: Previously active license server is no longer available/reachable. It will throw an error with the error code 13 and the following error message:
158 |
159 | issue consuming license from server ...address...: rpc error: code = DeadlineExceeded desc = context deadline exceeded 160 |
161 |
162 | 163 |
164 | After how many retries things are considered dead and how long does it take? 165 |
166 | The controller will keep probing the list of license servers that are supplied at the time in the background routine in every 30 seconds during the controller lifetime. 167 |
168 | 169 |
170 | What happens if the controller can't check-out the license for a specific server? 171 |
172 | The keng-controller will attempt to check out licenses from the next available license server in the configured list. 173 |
174 | 175 |
176 | How long does a license remain checked-out? 177 |
178 | For the duration of the current test configuration, the license will remain checked-out. Once the new test configuration is applied that doesn't require the license, the license will be checked-in. 179 |
180 | 181 |
182 | How to check-in all the licenses? 183 |
184 | To check-in all the licenses, apply an empty configuration. Alternatively, gracefully stop the keng-controller container. 185 |
186 | 187 |
188 | What happens of the controller can't check-in the license back? 189 |
190 | There is a keep-alive mechanism between the controller and the license server. If the controller crashes, is forcefully stopped, or lost the connection to the license server, the licenses will be automatically checked-in after 5 minutes of keep-alive inactivity. 191 |
192 | --------------------------------------------------------------------------------