aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Klozik <martin.klozik@tieto.com>2018-06-18 18:40:11 +0000
committerGerrit Code Review <gerrit@opnfv.org>2018-06-18 18:40:11 +0000
commit7e3db8dbc23d91484cc608bd8cb1d42ea7729396 (patch)
tree60d5fff01020b365779079ce1b9c60defdf69bcf
parent89018d21b6383f853a01c57a2270153d266fe087 (diff)
parent63b56ed1d74657129006f066a3f118c4c369d23c (diff)
Merge "connections: Introduction of generic API"
-rw-r--r--3rd_party/ixia/ixnetrfc2544.tcl4
-rw-r--r--3rd_party/ixia/ixnetrfc2544_bad_l2_crc.tcl4
-rwxr-xr-x3rd_party/ixia/ixnetrfc2544v2.tcl4
-rwxr-xr-x3rd_party/ixia/ixnetrfc2544v2_random_ip_crc.tcl4
-rwxr-xr-x3rd_party/ixia/ixnetrfc2544v2_random_udp_crc.tcl4
-rwxr-xr-xci/build-vsperf.sh6
-rwxr-xr-xconf/01_testcases.conf110
-rw-r--r--conf/02_vswitch.conf9
-rw-r--r--conf/03_traffic.conf3
-rw-r--r--conf/integration/01_testcases.conf168
-rw-r--r--conf/integration/01c_trex_vm_tests.conf1
-rw-r--r--core/component_factory.py34
-rw-r--r--core/pktfwd_controller.py8
-rw-r--r--core/vswitch_controller.py44
-rw-r--r--core/vswitch_controller_clean.py30
-rw-r--r--core/vswitch_controller_op2p.py56
-rw-r--r--core/vswitch_controller_p2p.py132
-rw-r--r--core/vswitch_controller_ptunp.py60
-rw-r--r--core/vswitch_controller_pxp.py136
-rw-r--r--docs/testing/developer/devguide/design/vswitchperf_design.rst14
-rw-r--r--testcases/testcase.py2
-rw-r--r--vswitches/ovs.py208
-rw-r--r--vswitches/ovs_dpdk_vhost.py32
-rw-r--r--vswitches/ovs_vanilla.py25
-rw-r--r--vswitches/vpp_dpdk_vhost.py79
-rw-r--r--vswitches/vswitch.py59
26 files changed, 541 insertions, 695 deletions
diff --git a/3rd_party/ixia/ixnetrfc2544.tcl b/3rd_party/ixia/ixnetrfc2544.tcl
index c47e8fc1..435f335f 100644
--- a/3rd_party/ixia/ixnetrfc2544.tcl
+++ b/3rd_party/ixia/ixnetrfc2544.tcl
@@ -1,7 +1,7 @@
#!/usr/bin/env tclsh
# Copyright (c) 2014, Ixia
-# Copyright (c) 2015-2017, Intel Corporation
+# Copyright (c) 2015-2018, Intel Corporation, Tieto
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -2971,7 +2971,7 @@ proc startRfc2544Test { testSpec trafficSpec } {
-trackingEnabled False \
-valueType $L4ValueType \
-activeFieldChoice False \
- -startValue {0} \
+ -startValue $dstPort \
-countValue $L4CountValue
sg_commit
set sg_field [lindex [ixNet remapIds $sg_field] 0]
diff --git a/3rd_party/ixia/ixnetrfc2544_bad_l2_crc.tcl b/3rd_party/ixia/ixnetrfc2544_bad_l2_crc.tcl
index 31031ecb..5c42ea50 100644
--- a/3rd_party/ixia/ixnetrfc2544_bad_l2_crc.tcl
+++ b/3rd_party/ixia/ixnetrfc2544_bad_l2_crc.tcl
@@ -1,7 +1,7 @@
#!/usr/bin/env tclsh
# Copyright (c) 2014, Ixia
-# Copyright (c) 2015-2018, Intel Corporation
+# Copyright (c) 2015-2018, Intel Corporation, Tieto
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -2971,7 +2971,7 @@ proc startRfc2544Test { testSpec trafficSpec } {
-trackingEnabled False \
-valueType $L4ValueType \
-activeFieldChoice False \
- -startValue {0} \
+ -startValue $dstPort \
-countValue $L4CountValue
sg_commit
set sg_field [lindex [ixNet remapIds $sg_field] 0]
diff --git a/3rd_party/ixia/ixnetrfc2544v2.tcl b/3rd_party/ixia/ixnetrfc2544v2.tcl
index b5c0fe2a..01e7b482 100755
--- a/3rd_party/ixia/ixnetrfc2544v2.tcl
+++ b/3rd_party/ixia/ixnetrfc2544v2.tcl
@@ -1,7 +1,7 @@
#!/usr/bin/env tclsh
# Copyright (c) 2014, Ixia
-# Copyright (c) 2015-2017, Intel Corporation
+# Copyright (c) 2015-2018, Intel Corporation, Tieto
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -1667,7 +1667,7 @@ proc startRfc2544Test { testSpec trafficSpec } {
-trackingEnabled False \
-valueType $L4ValueType \
-activeFieldChoice False \
- -startValue {0} \
+ -startValue $dstPort \
-countValue $L4CountValue
#
diff --git a/3rd_party/ixia/ixnetrfc2544v2_random_ip_crc.tcl b/3rd_party/ixia/ixnetrfc2544v2_random_ip_crc.tcl
index 7955fd23..29cb6e83 100755
--- a/3rd_party/ixia/ixnetrfc2544v2_random_ip_crc.tcl
+++ b/3rd_party/ixia/ixnetrfc2544v2_random_ip_crc.tcl
@@ -1,7 +1,7 @@
#!/usr/bin/env tclsh
# Copyright (c) 2014, Ixia
-# Copyright (c) 2015-2017, Intel Corporation
+# Copyright (c) 2015-2018, Intel Corporation, Tieto
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -1667,7 +1667,7 @@ proc startRfc2544Test { testSpec trafficSpec } {
-trackingEnabled False \
-valueType $L4ValueType \
-activeFieldChoice False \
- -startValue {0} \
+ -startValue $dstPort \
-countValue $L4CountValue
#
diff --git a/3rd_party/ixia/ixnetrfc2544v2_random_udp_crc.tcl b/3rd_party/ixia/ixnetrfc2544v2_random_udp_crc.tcl
index dc35f78e..7af4b9fc 100755
--- a/3rd_party/ixia/ixnetrfc2544v2_random_udp_crc.tcl
+++ b/3rd_party/ixia/ixnetrfc2544v2_random_udp_crc.tcl
@@ -1,7 +1,7 @@
#!/usr/bin/env tclsh
# Copyright (c) 2014, Ixia
-# Copyright (c) 2015-2017, Intel Corporation
+# Copyright (c) 2015-2018, Intel Corporation, Tieto
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -1667,7 +1667,7 @@ proc startRfc2544Test { testSpec trafficSpec } {
-trackingEnabled False \
-valueType $L4ValueType \
-activeFieldChoice False \
- -startValue {0} \
+ -startValue $dstPort \
-countValue $L4CountValue
#
diff --git a/ci/build-vsperf.sh b/ci/build-vsperf.sh
index 265a2031..a5ee8501 100755
--- a/ci/build-vsperf.sh
+++ b/ci/build-vsperf.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright 2015-2017 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -44,9 +44,9 @@ RESULTS_ARCHIVE="$HOME/ci_results_archive"
# CI job specific configuration
# VERIFY - run basic set of TCs with default settings
-TESTCASES_VERIFY="vswitch_add_del_bridge vswitch_add_del_bridges vswitch_add_del_vport vswitch_add_del_vports vswitch_vports_add_del_flow"
+TESTCASES_VERIFY="vswitch_add_del_bridge vswitch_add_del_bridges vswitch_add_del_vport vswitch_add_del_vports vswitch_vports_add_del_connection"
TESTPARAM_VERIFY="--integration"
-TESTCASES_VERIFY_VPP="vswitch_add_del_bridge vswitch_add_del_bridges vswitch_add_del_vport vswitch_add_del_vports vswitch_vports_add_del_connection_vpp"
+TESTCASES_VERIFY_VPP=$TESTCASES_VERIFY
TESTPARAM_VERIFY_VPP=$TESTPARAM_VERIFY
# MERGE - run selected TCs with default settings
TESTCASES_MERGE=$TESTCASES_VERIFY
diff --git a/conf/01_testcases.conf b/conf/01_testcases.conf
index 4a68ab3f..d766df65 100755
--- a/conf/01_testcases.conf
+++ b/conf/01_testcases.conf
@@ -1,4 +1,4 @@
-# Copyright 2015-2017 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -92,82 +92,6 @@
# "Dependency": [Test_Case_Name |None],
#
-# VPP specific macros used in TC defintions
-#
-VPP_P2P = [
- ['vswitch', 'add_switch', 'int_br0'], # STEP 0
- ['vswitch', 'add_phy_port', 'int_br0'], # STEP 1
- ['vswitch', 'add_phy_port', 'int_br0'], # STEP 2
- ['vswitch', 'add_connection', 'int_br0', '#STEP[1][0]', '#STEP[2][0]', True],
- ['vswitch', 'add_connection', 'int_br0', '#STEP[2][0]', '#STEP[1][0]', True],
- ['trafficgen', 'send_traffic', {}],
- ['vswitch', 'dump_connections', 'int_br0'],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[1][0]', '#STEP[2][0]', True],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[2][0]', '#STEP[1][0]', True],
- ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'],
- ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'],
- ['vswitch', 'del_switch', 'int_br0'],
- ]
-VPP_PVP = [
- ['vswitch', 'add_switch', 'int_br0'], # STEP 0
- ['vswitch', 'add_phy_port', 'int_br0'], # STEP 1
- ['vswitch', 'add_phy_port', 'int_br0'], # STEP 2
- ['vswitch', 'add_vport', 'int_br0'], # STEP 3
- ['vswitch', 'add_vport', 'int_br0'], # STEP 4
- ['vswitch', 'add_connection', 'int_br0', '#STEP[1][0]', '#STEP[3][0]', True],
- ['vswitch', 'add_connection', 'int_br0', '#STEP[4][0]', '#STEP[2][0]', True],
- ['vswitch', 'add_connection', 'int_br0', '#STEP[2][0]', '#STEP[4][0]', True],
- ['vswitch', 'add_connection', 'int_br0', '#STEP[3][0]', '#STEP[1][0]', True],
- ['vnf', 'start'],
- ['trafficgen', 'send_traffic', {}],
- ['vnf', 'stop'],
- ['vswitch', 'dump_connections', 'int_br0'],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[1][0]', '#STEP[3][0]', True],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[4][0]', '#STEP[2][0]', True],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[2][0]', '#STEP[4][0]', True],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[3][0]', '#STEP[1][0]', True],
- ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'],
- ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'],
- ['vswitch', 'del_port', 'int_br0', '#STEP[3][0]'],
- ['vswitch', 'del_port', 'int_br0', '#STEP[4][0]'],
- ['vswitch', 'del_switch', 'int_br0'],
- ]
-VPP_PVVP = [
- ['vswitch', 'add_switch', 'int_br0'], # STEP 0
- ['vswitch', 'add_phy_port', 'int_br0'], # STEP 1
- ['vswitch', 'add_phy_port', 'int_br0'], # STEP 2
- ['vswitch', 'add_vport', 'int_br0'], # STEP 3
- ['vswitch', 'add_vport', 'int_br0'], # STEP 4
- ['vswitch', 'add_vport', 'int_br0'], # STEP 5
- ['vswitch', 'add_vport', 'int_br0'], # STEP 6
- ['vswitch', 'add_connection', 'int_br0', '#STEP[1][0]', '#STEP[3][0]', True],
- ['vswitch', 'add_connection', 'int_br0', '#STEP[4][0]', '#STEP[5][0]', True],
- ['vswitch', 'add_connection', 'int_br0', '#STEP[6][0]', '#STEP[2][0]', True],
- ['vswitch', 'add_connection', 'int_br0', '#STEP[2][0]', '#STEP[6][0]', True],
- ['vswitch', 'add_connection', 'int_br0', '#STEP[5][0]', '#STEP[4][0]', True],
- ['vswitch', 'add_connection', 'int_br0', '#STEP[3][0]', '#STEP[1][0]', True],
- ['vnf1', 'start'],
- ['vnf2', 'start'],
- ['trafficgen', 'send_traffic', {}],
- ['vnf2', 'stop'],
- ['vnf1', 'stop'],
- ['vswitch', 'dump_connections', 'int_br0'],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[1][0]', '#STEP[3][0]', True],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[4][0]', '#STEP[5][0]', True],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[6][0]', '#STEP[2][0]', True],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[2][0]', '#STEP[6][0]', True],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[5][0]', '#STEP[4][0]', True],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[3][0]', '#STEP[1][0]', True],
- ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'],
- ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'],
- ['vswitch', 'del_port', 'int_br0', '#STEP[3][0]'],
- ['vswitch', 'del_port', 'int_br0', '#STEP[4][0]'],
- ['vswitch', 'del_port', 'int_br0', '#STEP[5][0]'],
- ['vswitch', 'del_port', 'int_br0', '#STEP[6][0]'],
- ['vswitch', 'del_switch', 'int_br0'],
- ]
-
-#
# Generic performance TC definitions
#
PERFORMANCE_TESTS = [
@@ -397,9 +321,14 @@ PERFORMANCE_TESTS = [
},
},
},
+ #
+ # Backward compatible definition of VPP TCs.
+ # It will be removed after CI reporting will be fixed to use
+ # default TCs for VPP reporting.
+ #
{
"Name": "phy2phy_tput_vpp",
- "Deployment": "clean",
+ "Deployment": "p2p",
"Description": "VPP: LTD.Throughput.RFC2544.PacketLossRatio",
"vSwitch" : "VppDpdkVhost",
"Parameters" : {
@@ -407,11 +336,10 @@ PERFORMANCE_TESTS = [
"traffic_type" : "rfc2544_throughput",
},
},
- "TestSteps": VPP_P2P,
},
{
"Name": "phy2phy_cont_vpp",
- "Deployment": "clean",
+ "Deployment": "p2p",
"Description": "VPP: Phy2Phy Continuous Stream",
"vSwitch" : "VppDpdkVhost",
"Parameters" : {
@@ -420,11 +348,10 @@ PERFORMANCE_TESTS = [
"frame_rate" : 100,
},
},
- "TestSteps": VPP_P2P,
},
{
"Name": "phy2phy_back2back_vpp",
- "Deployment": "clean",
+ "Deployment": "p2p",
"Description": "VPP: LTD.Throughput.RFC2544.BackToBackFrames",
"vSwitch" : "VppDpdkVhost",
"Parameters" : {
@@ -432,11 +359,10 @@ PERFORMANCE_TESTS = [
"traffic_type" : "rfc2544_back2back",
},
},
- "TestSteps": VPP_P2P,
},
{
"Name": "pvp_tput_vpp",
- "Deployment": "clean",
+ "Deployment": "pvp",
"Description": "VPP: LTD.Throughput.RFC2544.PacketLossRatio",
"vSwitch" : "VppDpdkVhost",
"Parameters" : {
@@ -444,11 +370,10 @@ PERFORMANCE_TESTS = [
"traffic_type" : "rfc2544_throughput",
},
},
- "TestSteps": VPP_PVP,
},
{
"Name": "pvp_cont_vpp",
- "Deployment": "clean",
+ "Deployment": "pvp",
"Description": "VPP: PVP Continuous Stream",
"vSwitch" : "VppDpdkVhost",
"Parameters" : {
@@ -456,11 +381,10 @@ PERFORMANCE_TESTS = [
"traffic_type" : "rfc2544_continuous",
},
},
- "TestSteps": VPP_PVP,
},
{
"Name": "pvp_back2back_vpp",
- "Deployment": "clean",
+ "Deployment": "pvp",
"Description": "VPP: LTD.Throughput.RFC2544.BackToBackFrames",
"vSwitch" : "VppDpdkVhost",
"Parameters" : {
@@ -468,11 +392,10 @@ PERFORMANCE_TESTS = [
"traffic_type" : "rfc2544_back2back",
},
},
- "TestSteps": VPP_PVP,
},
{
"Name": "pvvp_tput_vpp",
- "Deployment": "clean",
+ "Deployment": "pvvp",
"Description": "VPP: LTD.Throughput.RFC2544.PacketLossRatio",
"vSwitch" : "VppDpdkVhost",
"Parameters" : {
@@ -480,11 +403,10 @@ PERFORMANCE_TESTS = [
"traffic_type" : "rfc2544_throughput",
},
},
- "TestSteps": VPP_PVVP,
},
{
"Name": "pvvp_cont_vpp",
- "Deployment": "clean",
+ "Deployment": "pvvp",
"Description": "VPP: PVP Continuous Stream",
"vSwitch" : "VppDpdkVhost",
"Parameters" : {
@@ -492,11 +414,10 @@ PERFORMANCE_TESTS = [
"traffic_type" : "rfc2544_continuous",
},
},
- "TestSteps": VPP_PVVP,
},
{
"Name": "pvvp_back2back_vpp",
- "Deployment": "clean",
+ "Deployment": "pvvp",
"Description": "VPP: LTD.Throughput.RFC2544.BackToBackFrames",
"vSwitch" : "VppDpdkVhost",
"Parameters" : {
@@ -504,6 +425,5 @@ PERFORMANCE_TESTS = [
"traffic_type" : "rfc2544_back2back",
},
},
- "TestSteps": VPP_PVVP,
},
]
diff --git a/conf/02_vswitch.conf b/conf/02_vswitch.conf
index 61131a77..84ef71cb 100644
--- a/conf/02_vswitch.conf
+++ b/conf/02_vswitch.conf
@@ -210,6 +210,15 @@ OVS_VSCTL_ARGS = []
OVS_OFCTL_ARGS = ['-O', 'OpenFlow13'] # backward compatible default value
OVS_APPCTL_ARGS = []
+# default flow template to be used by OVS classes
+OVS_FLOW_TEMPLATE = {
+ 'idle_timeout': '0'
+}
+
+# enable or disable configuration of routing tables; See vswitchperf_design.rst
+# for details.
+OVS_ROUTING_TABLES = False
+
#########################
## VPP
#########################
diff --git a/conf/03_traffic.conf b/conf/03_traffic.conf
index f043b4ca..597f2ceb 100644
--- a/conf/03_traffic.conf
+++ b/conf/03_traffic.conf
@@ -1,4 +1,4 @@
-# Copyright 2015-2017 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -64,7 +64,6 @@ LOG_FILE_TRAFFIC_GEN = 'traffic-gen.log'
# feature. If enabled, it will implicitly insert a flow
# for each stream. If multistream is disabled, then
# pre-installed flows will be ignored.
-# Note: It is supported only for p2p deployment scenario.
# Data type: str
# Supported values:
# "Yes" - flows will be inserted into OVS
diff --git a/conf/integration/01_testcases.conf b/conf/integration/01_testcases.conf
index 945b36f7..7daff217 100644
--- a/conf/integration/01_testcases.conf
+++ b/conf/integration/01_testcases.conf
@@ -35,7 +35,9 @@
# Common TestSteps parts ("macros")
#
+#
# P2P macros
+#
STEP_VSWITCH_P2P_INIT = [
['vswitch', 'add_switch', 'int_br0'], # STEP 0
['vswitch', 'add_phy_port', 'int_br0'], # STEP 1
@@ -48,6 +50,18 @@ STEP_VSWITCH_P2P_FINIT = [
['vswitch', 'del_switch', 'int_br0'],
]
+STEP_VSWITCH_P2P_CONNECTIONS_INIT = STEP_VSWITCH_P2P_INIT + [
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[1][0]', '#STEP[2][0]'],
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[2][0]', '#STEP[1][0]'],
+]
+
+STEP_VSWITCH_P2P_CONNECTIONS_FINIT = [
+ ['vswitch', 'dump_connections', 'int_br0'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[1][0]', '#STEP[2][0]'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[2][0]', '#STEP[1][0]'],
+] + STEP_VSWITCH_P2P_FINIT
+
+# P2P OVS specific macros
STEP_VSWITCH_P2P_FLOWS_INIT = STEP_VSWITCH_P2P_INIT + [
['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', 'actions': ['output:#STEP[2][1]'], 'idle_timeout': '0'}],
['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[2][1]', 'actions': ['output:#STEP[1][1]'], 'idle_timeout': '0'}],
@@ -59,7 +73,9 @@ STEP_VSWITCH_P2P_FLOWS_FINIT = [
['vswitch', 'del_flow', 'int_br0', {'in_port': '#STEP[2][1]'}],
] + STEP_VSWITCH_P2P_FINIT
-# PVP and PVVP macros
+#
+# PVP macros
+#
STEP_VSWITCH_PVP_INIT = STEP_VSWITCH_P2P_INIT + [
['vswitch', 'add_vport', 'int_br0'], # STEP 3 vm1 ports
['vswitch', 'add_vport', 'int_br0'], # STEP 4
@@ -70,6 +86,22 @@ STEP_VSWITCH_PVP_FINIT = [
['vswitch', 'del_port', 'int_br0', '#STEP[4][0]'],
] + STEP_VSWITCH_P2P_FINIT
+STEP_VSWITCH_PVP_CONNECTIONS_INIT = STEP_VSWITCH_PVP_INIT + [
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[1][0]', '#STEP[3][0]'],
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[4][0]', '#STEP[2][0]'],
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[2][0]', '#STEP[4][0]'],
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[3][0]', '#STEP[1][0]'],
+]
+
+STEP_VSWITCH_PVP_CONNECTIONS_FINIT = [
+ ['vswitch', 'dump_connections', 'int_br0'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[1][0]', '#STEP[3][0]'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[4][0]', '#STEP[2][0]'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[2][0]', '#STEP[4][0]'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[3][0]', '#STEP[1][0]'],
+] + STEP_VSWITCH_PVP_FINIT
+
+# PVP OVS specific macros
STEP_VSWITCH_PVP_FLOWS_INIT = STEP_VSWITCH_PVP_INIT + [
['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', 'actions': ['output:#STEP[3][1]'], 'idle_timeout': '0'}],
['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[4][1]', 'actions': ['output:#STEP[2][1]'], 'idle_timeout': '0'}],
@@ -85,6 +117,9 @@ STEP_VSWITCH_PVP_FLOWS_FINIT = [
['vswitch', 'del_flow', 'int_br0', {'in_port': '#STEP[3][1]'}],
] + STEP_VSWITCH_PVP_FINIT
+#
+# PVVP macros
+#
STEP_VSWITCH_PVVP_INIT = STEP_VSWITCH_PVP_INIT + [
['vswitch', 'add_vport', 'int_br0'], # STEP 5 vm2 ports
['vswitch', 'add_vport', 'int_br0'], # STEP 6
@@ -95,6 +130,26 @@ STEP_VSWITCH_PVVP_FINIT = [
['vswitch', 'del_port', 'int_br0', '#STEP[6][0]'],
] + STEP_VSWITCH_PVP_FINIT
+STEP_VSWITCH_PVVP_CONNECTIONS_INIT = STEP_VSWITCH_PVVP_INIT + [
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[1][0]', '#STEP[3][0]'],
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[4][0]', '#STEP[5][0]'],
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[6][0]', '#STEP[2][0]'],
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[2][0]', '#STEP[6][0]'],
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[5][0]', '#STEP[4][0]'],
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[3][0]', '#STEP[1][0]'],
+]
+
+STEP_VSWITCH_PVVP_CONNECTIONS_FINIT = [
+ ['vswitch', 'dump_connections', 'int_br0'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[1][0]', '#STEP[3][0]'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[4][0]', '#STEP[5][0]'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[6][0]', '#STEP[2][0]'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[2][0]', '#STEP[6][0]'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[5][0]', '#STEP[4][0]'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[3][0]', '#STEP[1][0]'],
+] + STEP_VSWITCH_PVVP_FINIT
+
+# PVVP OVS specific macros
STEP_VSWITCH_PVVP_FLOWS_INIT = STEP_VSWITCH_PVVP_INIT + [
['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', 'actions': ['output:#STEP[3][1]'], 'idle_timeout': '0'}],
['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[4][1]', 'actions': ['output:#STEP[5][1]'], 'idle_timeout': '0'}],
@@ -255,9 +310,49 @@ INTEGRATION_TESTS = [
]
},
{
+ "Name": "vswitch_add_del_connection",
+ "Deployment": "clean",
+ "Description": "vSwitch - add and delete connection",
+ "TestSteps": [
+ ['vswitch', 'add_switch', 'int_br0'],
+ ['vswitch', 'add_phy_port', 'int_br0'],
+ ['vswitch', 'add_phy_port', 'int_br0'],
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[1][0]', '#STEP[2][0]'],
+ ['vswitch', 'dump_connections', 'int_br0'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[1][0]', '#STEP[2][0]'],
+ ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'],
+ ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'],
+ ['vswitch', 'del_switch', 'int_br0'],
+ ]
+ },
+ {
+ "Name": "vswitch_vports_add_del_connection",
+ "Deployment": "clean",
+ "Description": "vSwitch - add and delete connection",
+ "Description": "vSwitch - configure switch with vports, add and delete connection",
+ "TestSteps": [
+ ['vswitch', 'add_switch', 'int_br0'],
+ ['vswitch', 'add_vport', 'int_br0'],
+ ['vswitch', 'add_vport', 'int_br0'],
+ ['vswitch', 'add_connection', 'int_br0', '#STEP[1][0]', '#STEP[2][0]'],
+ ['vswitch', 'dump_connections', 'int_br0'],
+ ['vswitch', 'del_connection', 'int_br0', '#STEP[1][0]', '#STEP[2][0]'],
+ ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'],
+ ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'],
+ ['vswitch', 'del_switch', 'int_br0'],
+ ]
+ },
+ {
+ "Name": "vswitch_add_del_connections",
+ "Deployment": "clean",
+ "Description": "vSwitch - add and delete connections",
+ "TestSteps": STEP_VSWITCH_P2P_CONNECTIONS_INIT +
+ STEP_VSWITCH_P2P_CONNECTIONS_FINIT
+ },
+ {
"Name": "vswitch_add_del_flow",
"Deployment": "clean",
- "Description": "vSwitch - add and delete flow",
+ "Description": "OVS: vSwitch - add and delete flow",
"TestSteps": [
['vswitch', 'add_switch', 'int_br0'],
['vswitch', 'add_phy_port', 'int_br0'],
@@ -272,7 +367,7 @@ INTEGRATION_TESTS = [
{
"Name": "vswitch_vports_add_del_flow",
"Deployment": "clean",
- "Description": "vSwitch - configure switch with vports, add and delete flow",
+ "Description": "OVS: vSwitch - configure switch with vports, add and delete flow",
"TestSteps": [
['vswitch', 'add_switch', 'int_br0'],
['vswitch', 'add_vport', 'int_br0'],
@@ -287,7 +382,7 @@ INTEGRATION_TESTS = [
{
"Name": "vswitch_add_del_flows",
"Deployment": "clean",
- "Description": "vSwitch - add and delete flows",
+ "Description": "OVS: vSwitch - add and delete flows",
"TestSteps": STEP_VSWITCH_P2P_FLOWS_INIT +
STEP_VSWITCH_P2P_FLOWS_FINIT
},
@@ -295,31 +390,31 @@ INTEGRATION_TESTS = [
"Name": "vswitch_p2p_tput",
"Deployment": "clean",
"Description": "vSwitch - configure switch and execute RFC2544 throughput test",
- "TestSteps": STEP_VSWITCH_P2P_FLOWS_INIT +
+ "TestSteps": STEP_VSWITCH_P2P_CONNECTIONS_INIT +
[
['trafficgen', 'send_traffic', {'traffic_type' : 'rfc2544_throughput', 'bidir' : 'True'}],
] +
- STEP_VSWITCH_P2P_FLOWS_FINIT
+ STEP_VSWITCH_P2P_CONNECTIONS_FINIT
},
{
"Name": "vswitch_p2p_back2back",
"Deployment": "clean",
"Description": "vSwitch - configure switch and execute RFC2544 back2back test",
- "TestSteps": STEP_VSWITCH_P2P_FLOWS_INIT +
+ "TestSteps": STEP_VSWITCH_P2P_CONNECTIONS_INIT +
[
['trafficgen', 'send_traffic', {'traffic_type' : 'rfc2544_back2back', 'bidir' : 'True'}],
] +
- STEP_VSWITCH_P2P_FLOWS_FINIT
+ STEP_VSWITCH_P2P_CONNECTIONS_FINIT
},
{
"Name": "vswitch_p2p_cont",
"Deployment": "clean",
"Description": "vSwitch - configure switch and execute RFC2544 continuous stream test",
- "TestSteps": STEP_VSWITCH_P2P_FLOWS_INIT +
+ "TestSteps": STEP_VSWITCH_P2P_CONNECTIONS_INIT +
[
['trafficgen', 'send_traffic', {'traffic_type' : 'rfc2544_continuous', 'bidir' : 'True'}],
] +
- STEP_VSWITCH_P2P_FLOWS_FINIT
+ STEP_VSWITCH_P2P_CONNECTIONS_FINIT
},
{
"Name": "vswitch_pvp",
@@ -351,43 +446,43 @@ INTEGRATION_TESTS = [
"Name": "vswitch_pvp_tput",
"Deployment": "clean",
"Description": "vSwitch - configure switch, vnf and execute RFC2544 throughput test",
- "TestSteps": STEP_VSWITCH_PVP_FLOWS_INIT +
+ "TestSteps": STEP_VSWITCH_PVP_CONNECTIONS_INIT +
[
['vnf', 'start'],
['trafficgen', 'send_traffic', {'traffic_type' : 'rfc2544_throughput', 'bidir' : 'True'}],
['vnf', 'stop'],
] +
- STEP_VSWITCH_PVP_FLOWS_FINIT
+ STEP_VSWITCH_PVP_CONNECTIONS_FINIT
},
{
"Name": "vswitch_pvp_back2back",
"Deployment": "clean",
"Description": "vSwitch - configure switch, vnf and execute RFC2544 back2back test",
- "TestSteps": STEP_VSWITCH_PVP_FLOWS_INIT +
+ "TestSteps": STEP_VSWITCH_PVP_CONNECTIONS_INIT +
[
['vnf', 'start'],
['trafficgen', 'send_traffic', {'traffic_type' : 'rfc2544_back2back', 'bidir' : 'True'}],
['vnf', 'stop'],
] +
- STEP_VSWITCH_PVP_FLOWS_FINIT
+ STEP_VSWITCH_PVP_CONNECTIONS_FINIT
},
{
"Name": "vswitch_pvp_cont",
"Deployment": "clean",
"Description": "vSwitch - configure switch, vnf and execute RFC2544 continuous stream test",
- "TestSteps": STEP_VSWITCH_PVP_FLOWS_INIT +
+ "TestSteps": STEP_VSWITCH_PVP_CONNECTIONS_INIT +
[
['vnf', 'start'],
['trafficgen', 'send_traffic', {'traffic_type' : 'rfc2544_continuous', 'bidir' : 'True'}],
['vnf', 'stop'],
] +
- STEP_VSWITCH_PVP_FLOWS_FINIT
+ STEP_VSWITCH_PVP_CONNECTIONS_FINIT
},
{
"Name": "vswitch_pvp_all",
"Deployment": "clean",
"Description": "vSwitch - configure switch, vnf and execute all test types",
- "TestSteps": STEP_VSWITCH_PVP_FLOWS_INIT +
+ "TestSteps": STEP_VSWITCH_PVP_CONNECTIONS_INIT +
[
['vnf', 'start'],
['trafficgen', 'send_traffic', {'traffic_type' : 'rfc2544_throughput', 'bidir' : 'True'}],
@@ -395,7 +490,7 @@ INTEGRATION_TESTS = [
['trafficgen', 'send_traffic', {'traffic_type' : 'rfc2544_continuous', 'bidir' : 'True'}],
['vnf', 'stop'],
] +
- STEP_VSWITCH_PVP_FLOWS_FINIT
+ STEP_VSWITCH_PVP_CONNECTIONS_FINIT
},
{
"Name": "vswitch_pvvp",
@@ -414,7 +509,7 @@ INTEGRATION_TESTS = [
"Name": "vswitch_pvvp_tput",
"Deployment": "clean",
"Description": "vSwitch - configure switch, two chained vnfs and execute RFC2544 throughput test",
- "TestSteps": STEP_VSWITCH_PVVP_FLOWS_INIT +
+ "TestSteps": STEP_VSWITCH_PVVP_CONNECTIONS_INIT +
[
['vnf1', 'start'],
['vnf2', 'start'],
@@ -422,13 +517,13 @@ INTEGRATION_TESTS = [
['vnf1', 'stop'],
['vnf2', 'stop'],
] +
- STEP_VSWITCH_PVVP_FLOWS_FINIT
+ STEP_VSWITCH_PVVP_CONNECTIONS_FINIT
},
{
"Name": "vswitch_pvvp_back2back",
"Deployment": "clean",
"Description": "vSwitch - configure switch, two chained vnfs and execute RFC2544 back2back test",
- "TestSteps": STEP_VSWITCH_PVVP_FLOWS_INIT +
+ "TestSteps": STEP_VSWITCH_PVVP_CONNECTIONS_INIT +
[
['vnf1', 'start'],
['vnf2', 'start'],
@@ -436,13 +531,13 @@ INTEGRATION_TESTS = [
['vnf1', 'stop'],
['vnf2', 'stop'],
] +
- STEP_VSWITCH_PVVP_FLOWS_FINIT
+ STEP_VSWITCH_PVVP_CONNECTIONS_FINIT
},
{
"Name": "vswitch_pvvp_cont",
"Deployment": "clean",
"Description": "vSwitch - configure switch, two chained vnfs and execute RFC2544 continuous stream test",
- "TestSteps": STEP_VSWITCH_PVVP_FLOWS_INIT +
+ "TestSteps": STEP_VSWITCH_PVVP_CONNECTIONS_INIT +
[
['vnf1', 'start'],
['vnf2', 'start'],
@@ -450,13 +545,13 @@ INTEGRATION_TESTS = [
['vnf1', 'stop'],
['vnf2', 'stop'],
] +
- STEP_VSWITCH_PVVP_FLOWS_FINIT
+ STEP_VSWITCH_PVVP_CONNECTIONS_FINIT
},
{
"Name": "vswitch_pvvp_all",
"Deployment": "clean",
"Description": "vSwitch - configure switch, two chained vnfs and execute all test types",
- "TestSteps": STEP_VSWITCH_PVVP_FLOWS_INIT +
+ "TestSteps": STEP_VSWITCH_PVVP_CONNECTIONS_INIT +
[
['vnf1', 'start'],
['vnf2', 'start'],
@@ -466,7 +561,7 @@ INTEGRATION_TESTS = [
['vnf1', 'stop'],
['vnf2', 'stop'],
] +
- STEP_VSWITCH_PVVP_FLOWS_FINIT
+ STEP_VSWITCH_PVVP_CONNECTIONS_FINIT
},
{
"Name": "vswitch_p4vp_tput",
@@ -682,23 +777,6 @@ INTEGRATION_TESTS = [
['tools', 'assert', 'len(#STEP[-1][0])'],
]
},
- {
- "Name": "vswitch_vports_add_del_connection_vpp",
- "Deployment": "clean",
- "Description": "VPP: vSwitch - configure switch with vports, add and delete connection",
- "vSwitch" : "VppDpdkVhost",
- "TestSteps": [
- ['vswitch', 'add_switch', 'int_br0'],
- ['vswitch', 'add_vport', 'int_br0'],
- ['vswitch', 'add_vport', 'int_br0'],
- ['vswitch', 'add_connection', 'int_br0', '#STEP[1][0]', '#STEP[2][0]', True],
- ['vswitch', 'dump_connections', 'int_br0'],
- ['vswitch', 'del_connection', 'int_br0', '#STEP[1][0]', '#STEP[2][0]', True],
- ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'],
- ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'],
- ['vswitch', 'del_switch', 'int_br0'],
- ]
- },
#
# END of VPP tests used by VERIFY and MERGE jobs by OPNFV Jenkins
#
@@ -874,11 +952,11 @@ INTEGRATION_TESTS += [
# "VNF" : "QemuVirtioNet",
# "Trafficgen": "IxNet",
# "Parameters": {"GUEST_LOOPBACK" : ["linux_bridge"],},
-# "TestSteps": STEP_VSWITCH_PVP_FLOWS_INIT +
+# "TestSteps": STEP_VSWITCH_PVP_CONNECTIONS_INIT +
# [
# ['vnf', 'start'],
# ['trafficgen', 'send_traffic', {'traffic_type' : 'rfc2544_continuous', 'bidir' : 'True'}],
# ['vnf', 'stop'],
# ] +
-# STEP_VSWITCH_PVP_FLOWS_FINIT
+# STEP_VSWITCH_PVP_CONNECTIONS_FINIT
# },
diff --git a/conf/integration/01c_trex_vm_tests.conf b/conf/integration/01c_trex_vm_tests.conf
index 50982bea..1bec4efd 100644
--- a/conf/integration/01c_trex_vm_tests.conf
+++ b/conf/integration/01c_trex_vm_tests.conf
@@ -30,6 +30,7 @@ TREX_VM_INIT = [
['#trex_p2', 'vswitch', 'add_vport', 'int_br0'],
# configure IP access to T-Rex VM
['vswitch', 'add_switch', 'trex_br'],
+ ['vswitch', 'add_flow', 'trex_br', {'actions': ['NORMAL']}], # turn on MAC learning mode
['#trex_admin', 'vswitch', 'add_vport', 'trex_br'],
['#trex_spare', 'vswitch', 'add_vport', 'trex_br'], # spare to have even number of NICs
['tools', 'exec_shell', 'sudo ip addr flush dev trex_br'],
diff --git a/core/component_factory.py b/core/component_factory.py
index b6bd2677..2c51a060 100644
--- a/core/component_factory.py
+++ b/core/component_factory.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2017 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -66,23 +66,23 @@ def create_vswitch(deployment_scenario, vswitch_class, traffic,
:return: IVSwitchController for the deployment_scenario
"""
# pylint: disable=too-many-return-statements
- deployment_scenario = deployment_scenario.lower()
- if deployment_scenario.startswith("p2p"):
- return VswitchControllerP2P(vswitch_class, traffic)
- elif deployment_scenario.startswith("pvp"):
- return VswitchControllerPXP(deployment_scenario, vswitch_class, traffic)
- elif deployment_scenario.startswith("pvvp"):
- return VswitchControllerPXP(deployment_scenario, vswitch_class, traffic)
- elif deployment_scenario.startswith("pvpv"):
- return VswitchControllerPXP(deployment_scenario, vswitch_class, traffic)
- elif deployment_scenario.startswith("op2p"):
- return VswitchControllerOP2P(vswitch_class, traffic, tunnel_operation)
- elif deployment_scenario.startswith("ptunp"):
- return VswitchControllerPtunP(vswitch_class, traffic)
- elif deployment_scenario.startswith("clean"):
- return VswitchControllerClean(vswitch_class, traffic)
+ deployment = deployment_scenario.lower()
+ if deployment.startswith("p2p"):
+ return VswitchControllerP2P(deployment, vswitch_class, traffic)
+ elif deployment.startswith("pvp"):
+ return VswitchControllerPXP(deployment, vswitch_class, traffic)
+ elif deployment.startswith("pvvp"):
+ return VswitchControllerPXP(deployment, vswitch_class, traffic)
+ elif deployment.startswith("pvpv"):
+ return VswitchControllerPXP(deployment, vswitch_class, traffic)
+ elif deployment.startswith("op2p"):
+ return VswitchControllerOP2P(deployment, vswitch_class, traffic, tunnel_operation)
+ elif deployment.startswith("ptunp"):
+ return VswitchControllerPtunP(deployment, vswitch_class, traffic)
+ elif deployment.startswith("clean"):
+ return VswitchControllerClean(deployment, vswitch_class, traffic)
else:
- raise RuntimeError("Unknown deployment scenario '{}'.".format(deployment_scenario))
+ raise RuntimeError("Unknown deployment scenario '{}'.".format(deployment))
def create_vnf(deployment_scenario, vnf_class, extra_vnfs):
diff --git a/core/pktfwd_controller.py b/core/pktfwd_controller.py
index bdc91822..363302c3 100644
--- a/core/pktfwd_controller.py
+++ b/core/pktfwd_controller.py
@@ -1,4 +1,4 @@
-# Copyright 2016 Intel Corporation.
+# Copyright 2016-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -89,9 +89,9 @@ class PktFwdController(object):
"""
return self._pktfwd
- def dump_vswitch_flows(self):
- """ Dumps flows from vswitch
+ def dump_vswitch_connections(self):
+ """ Dumps connections from vswitch
"""
raise NotImplementedError(
"The PktFwdController does not implement the "
- "\"dump_vswitch_flows\" function.")
+ "\"dump_vswitch_connections\" function.")
diff --git a/core/vswitch_controller.py b/core/vswitch_controller.py
index 855de8b2..889f14bc 100644
--- a/core/vswitch_controller.py
+++ b/core/vswitch_controller.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,33 +13,57 @@
# limitations under the License.
"""Interface for deployment specific vSwitch controllers
"""
+import logging
class IVswitchController(object):
- """Abstract class which defines a vSwitch controller object
+ """Interface class for a vSwitch controller object
This interface is used to setup and control a vSwitch provider for a
particular deployment scenario.
"""
- def __enter__(self):
+ def __init__(self, deployment, vswitch_class, traffic):
+ """Initializes up the generic prerequisites for deployment scenario.
+
+ :deployment: the deployment scenario to configure
+ :vswitch_class: the vSwitch class to be used.
+ :traffic: dictionary with detailed traffic definition
+ """
+ self._logger = logging.getLogger(__name__)
+ self._vswitch_class = vswitch_class
+ self._vswitch = vswitch_class()
+ self._deployment_scenario = deployment
+ self._logger.debug('Creation using %s', str(self._vswitch_class))
+ self._traffic = traffic.copy()
+ self._bridge = None
+
+ def setup(self):
"""Sets up the switch for the particular deployment scenario
"""
raise NotImplementedError(
"The VswitchController does not implement the \"setup\" function.")
- def __exit__(self, type_, value, traceback):
+ def stop(self):
"""Tears down the switch created in setup()
"""
raise NotImplementedError(
"The VswitchController does not implement the \"stop\" function.")
+ def __enter__(self):
+ """Sets up the switch for the particular deployment scenario
+ """
+ self.setup()
+
+ def __exit__(self, type_, value, traceback):
+ """Tears down the switch created in setup()
+ """
+ self.stop()
+
def get_vswitch(self):
"""Get the controlled vSwitch
:return: The controlled IVswitch
"""
- raise NotImplementedError(
- "The VswitchController does not implement the \"get_vswitch\" "
- "function.")
+ return self._vswitch
def get_ports_info(self):
"""Returns a dictionary describing all ports on the vSwitch.
@@ -50,9 +74,9 @@ class IVswitchController(object):
"The VswitchController does not implement the \"get_ports_info\" "
"function.")
- def dump_vswitch_flows(self):
- """ Dumps flows from vswitch
+ def dump_vswitch_connections(self):
+ """ Dumps connections from vswitch
"""
raise NotImplementedError(
"The VswitchController does not implement the "
- "\"dump_vswitch_flows\" function.")
+ "\"dump_vswitch_connections\" function.")
diff --git a/core/vswitch_controller_clean.py b/core/vswitch_controller_clean.py
index 432406a7..7a771226 100644
--- a/core/vswitch_controller_clean.py
+++ b/core/vswitch_controller_clean.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2016 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,9 +14,6 @@
"""VSwitch controller for basic initialization of vswitch
"""
-
-import logging
-
from core.vswitch_controller import IVswitchController
class VswitchControllerClean(IVswitchController):
@@ -28,18 +25,6 @@ class VswitchControllerClean(IVswitchController):
_deployment_scenario: A string describing the scenario to set-up in the
constructor.
"""
- def __init__(self, vswitch_class, traffic):
- """Initializes up the prerequisites for the Clean deployment scenario.
-
- :vswitch_class: the vSwitch class to be used.
- """
- self._logger = logging.getLogger(__name__)
- self._vswitch_class = vswitch_class
- self._vswitch = vswitch_class()
- self._deployment_scenario = "Clean"
- self._logger.debug('Creation using %s', str(self._vswitch_class))
- self._traffic = traffic.copy()
-
def setup(self):
"""Sets up the switch for Clean.
"""
@@ -57,23 +42,12 @@ class VswitchControllerClean(IVswitchController):
self._logger.debug('Stop using %s', str(self._vswitch_class))
self._vswitch.stop()
- def __enter__(self):
- self.setup()
-
- def __exit__(self, type_, value, traceback):
- self.stop()
-
- def get_vswitch(self):
- """See IVswitchController for description
- """
- return self._vswitch
-
def get_ports_info(self):
"""See IVswitchController for description
"""
pass
- def dump_vswitch_flows(self):
+ def dump_vswitch_connections(self):
"""See IVswitchController for description
"""
pass
diff --git a/core/vswitch_controller_op2p.py b/core/vswitch_controller_op2p.py
index 3f879f9f..072a690a 100644
--- a/core/vswitch_controller_op2p.py
+++ b/core/vswitch_controller_op2p.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2017 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,39 +14,19 @@
"""VSwitch controller for Physical to Tunnel Endpoint to Physical deployment
"""
-
-import logging
-
from core.vswitch_controller import IVswitchController
from vswitches.utils import add_ports_to_flow
from conf import settings as S
from tools import tasks
-_FLOW_TEMPLATE = {
- 'idle_timeout': '0'
-}
-
class VswitchControllerOP2P(IVswitchController):
"""VSwitch controller for OP2P deployment scenario.
-
- Attributes:
- _vswitch_class: The vSwitch class to be used.
- _vswitch: The vSwitch object controlled by this controller
- _deployment_scenario: A string describing the scenario to set-up in the
- constructor.
"""
- def __init__(self, vswitch_class, traffic, tunnel_operation=None):
- """Initializes up the prerequisites for the OP2P deployment scenario.
-
- :vswitch_class: the vSwitch class to be used.
+ def __init__(self, deployment, vswitch_class, traffic, tunnel_operation=None):
+ """See IVswitchController for general description
"""
- self._logger = logging.getLogger(__name__)
- self._vswitch_class = vswitch_class
- self._vswitch = vswitch_class()
- self._deployment_scenario = "OP2P"
- self._traffic = traffic.copy()
+ super().__init__(deployment, vswitch_class, traffic)
self._tunnel_operation = tunnel_operation
- self._logger.debug('Creation using %s', str(self._vswitch_class))
def setup(self):
""" Sets up the switch for overlay P2P (tunnel encap or decap)
@@ -118,10 +98,13 @@ class VswitchControllerOP2P(IVswitchController):
# Test is unidirectional for now
self._vswitch.del_flow(bridge)
- flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy1_number,
+ flow1 = add_ports_to_flow(S.getValue('OVS_FLOW_TEMPLATE'), phy1_number,
phy2_number)
self._vswitch.add_flow(bridge, flow1)
-
+ # enable MAC learning mode at external bridge
+ flow_ext = S.getValue('OVS_FLOW_TEMPLATE').copy()
+ flow_ext.update({'actions': ['NORMAL']})
+ self._vswitch.add_flow(bridge_ext, flow_ext)
except:
self._vswitch.stop()
raise
@@ -178,7 +161,7 @@ class VswitchControllerOP2P(IVswitchController):
bridge)
# Test is unidirectional for now
self._vswitch.del_flow(bridge_ext)
- flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy3_number,
+ flow1 = add_ports_to_flow(S.getValue('OVS_FLOW_TEMPLATE'), phy3_number,
phy2_number)
self._vswitch.add_flow(bridge_ext, flow1)
@@ -251,7 +234,7 @@ class VswitchControllerOP2P(IVswitchController):
# Test is unidirectional for now
self._vswitch.del_flow(bridge_ext)
- flow1 = add_ports_to_flow(_FLOW_TEMPLATE, phy2_number, 'LOCAL')
+ flow1 = add_ports_to_flow(S.getValue('OVS_FLOW_TEMPLATE'), phy2_number, 'LOCAL')
self._vswitch.add_flow(bridge_ext, flow1)
except:
@@ -264,17 +247,6 @@ class VswitchControllerOP2P(IVswitchController):
self._logger.debug('Stop using %s', str(self._vswitch_class))
self._vswitch.stop()
- def __enter__(self):
- self.setup()
-
- def __exit__(self, type_, value, traceback):
- self.stop()
-
- def get_vswitch(self):
- """See IVswitchController for description
- """
- return self._vswitch
-
def get_ports_info(self):
"""See IVswitchController for description
"""
@@ -286,8 +258,8 @@ class VswitchControllerOP2P(IVswitchController):
self._vswitch.get_ports(
S.getValue('TUNNEL_EXTERNAL_BRIDGE'))
- def dump_vswitch_flows(self):
+ def dump_vswitch_connections(self):
"""See IVswitchController for description
"""
- self._vswitch.dump_flows(S.getValue('TUNNEL_INTEGRATION_BRIDGE'))
- self._vswitch.dump_flows(S.getValue('TUNNEL_EXTERNAL_BRIDGE'))
+ self._vswitch.dump_connections(S.getValue('TUNNEL_INTEGRATION_BRIDGE'))
+ self._vswitch.dump_connections(S.getValue('TUNNEL_EXTERNAL_BRIDGE'))
diff --git a/core/vswitch_controller_p2p.py b/core/vswitch_controller_p2p.py
index eb1f57f0..d8f22e4c 100644
--- a/core/vswitch_controller_p2p.py
+++ b/core/vswitch_controller_p2p.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2017 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,20 +14,9 @@
"""VSwitch controller for Physical to Physical deployment
"""
-
-import logging
-import netaddr
-
from core.vswitch_controller import IVswitchController
from conf import settings
-_FLOW_TEMPLATE = {
- 'idle_timeout': '0'
-}
-
-_PROTO_TCP = 6
-_PROTO_UDP = 17
-
class VswitchControllerP2P(IVswitchController):
"""VSwitch controller for P2P deployment scenario.
@@ -37,17 +26,11 @@ class VswitchControllerP2P(IVswitchController):
_deployment_scenario: A string describing the scenario to set-up in the
constructor.
"""
- def __init__(self, vswitch_class, traffic):
- """Initializes up the prerequisites for the P2P deployment scenario.
-
- :vswitch_class: the vSwitch class to be used.
+ def __init__(self, deployment, vswitch_class, traffic):
+ """See IVswitchController for general description
"""
- self._logger = logging.getLogger(__name__)
- self._vswitch_class = vswitch_class
- self._vswitch = vswitch_class()
- self._deployment_scenario = "P2P"
- self._logger.debug('Creation using %s', str(self._vswitch_class))
- self._traffic = traffic.copy()
+ super().__init__(deployment, vswitch_class, traffic)
+ self._bridge = settings.getValue('VSWITCH_BRIDGE_NAME')
def setup(self):
"""Sets up the switch for p2p.
@@ -57,51 +40,14 @@ class VswitchControllerP2P(IVswitchController):
try:
self._vswitch.start()
- bridge = settings.getValue('VSWITCH_BRIDGE_NAME')
- self._vswitch.add_switch(bridge)
-
- (_, _) = self._vswitch.add_phy_port(bridge)
- (_, _) = self._vswitch.add_phy_port(bridge)
-
- self._vswitch.del_flow(bridge)
-
- # table#0 - flows designed to force 5 & 13 tuple matches go here
- flow = {'table':'0', 'priority':'1', 'actions': ['goto_table:1']}
- self._vswitch.add_flow(bridge, flow)
-
- # table#1 - flows to route packets between ports goes here. The
- # chosen port is communicated to subsequent tables by setting the
- # metadata value to the egress port number
+ self._vswitch.add_switch(self._bridge)
- # configure flows according to the TC definition
- flow_template = _FLOW_TEMPLATE.copy()
- if self._traffic['flow_type'] == 'IP':
- flow_template.update({'dl_type':'0x0800', 'nw_src':self._traffic['l3']['srcip'],
- 'nw_dst':self._traffic['l3']['dstip']})
+ (port1, _) = self._vswitch.add_phy_port(self._bridge)
+ (port2, _) = self._vswitch.add_phy_port(self._bridge)
- flow = flow_template.copy()
- flow.update({'table':'1', 'priority':'1', 'in_port':'1',
- 'actions': ['write_actions(output:2)', 'write_metadata:0x2',
- 'goto_table:2']})
- self.process_flow_template(bridge, flow)
- flow = flow_template.copy()
- flow.update({'table':'1', 'priority':'1', 'in_port':'2',
- 'actions': ['write_actions(output:1)', 'write_metadata:0x1',
- 'goto_table:2']})
- self.process_flow_template(bridge, flow)
+ self._vswitch.add_connection(self._bridge, port1, port2, self._traffic)
+ self._vswitch.add_connection(self._bridge, port2, port1, self._traffic)
- # Frame modification table. Frame modification flow rules are
- # isolated in this table so that they can be turned on or off
- # without affecting the routing or tuple-matching flow rules.
- flow = {'table':'2', 'priority':'1', 'actions': ['goto_table:3']}
- self._vswitch.add_flow(bridge, flow)
-
- # Egress table
- # (TODO) Billy O'Mahony - the drop action here actually required in
- # order to egress the packet. This is the subject of a thread on
- # ovs-discuss 2015-06-30.
- flow = {'table':'3', 'priority':'1', 'actions': ['drop']}
- self._vswitch.add_flow(bridge, flow)
except:
self._vswitch.stop()
raise
@@ -112,65 +58,13 @@ class VswitchControllerP2P(IVswitchController):
self._logger.debug('Stop using %s', str(self._vswitch_class))
self._vswitch.stop()
- def __enter__(self):
- self.setup()
-
- def __exit__(self, type_, value, traceback):
- self.stop()
-
- def get_vswitch(self):
- """See IVswitchController for description
- """
- return self._vswitch
-
def get_ports_info(self):
"""See IVswitchController for description
"""
self._logger.debug('get_ports_info using %s', str(self._vswitch_class))
- return self._vswitch.get_ports(settings.getValue('VSWITCH_BRIDGE_NAME'))
+ return self._vswitch.get_ports(self._bridge)
- def dump_vswitch_flows(self):
+ def dump_vswitch_connections(self):
"""See IVswitchController for description
"""
- self._vswitch.dump_flows(settings.getValue('VSWITCH_BRIDGE_NAME'))
-
- def process_flow_template(self, bridge, flow_template):
- """Method adds flows into the vswitch based on given flow template
- and configuration of multistream feature.
- """
- if ('pre_installed_flows' in self._traffic and
- self._traffic['pre_installed_flows'].lower() == 'yes' and
- 'multistream' in self._traffic and self._traffic['multistream'] > 0 and
- 'stream_type' in self._traffic):
- # multistream feature is enabled and flows should be inserted into OVS
- # so generate flows based on template and multistream configuration
- if self._traffic['stream_type'] == 'L2':
- # iterate through destimation MAC address
- dst_mac_value = netaddr.EUI(self._traffic['l2']['dstmac']).value
- for i in range(self._traffic['multistream']):
- tmp_mac = netaddr.EUI(dst_mac_value + i)
- tmp_mac.dialect = netaddr.mac_unix_expanded
- flow_template.update({'dl_dst':tmp_mac})
- # optimize flow insertion by usage of cache
- self._vswitch.add_flow(bridge, flow_template, cache='on')
- elif self._traffic['stream_type'] == 'L3':
- # iterate through destimation IP address
- dst_ip_value = netaddr.IPAddress(self._traffic['l3']['dstip']).value
- for i in range(self._traffic['multistream']):
- tmp_ip = netaddr.IPAddress(dst_ip_value + i)
- flow_template.update({'dl_type':'0x0800', 'nw_dst':tmp_ip})
- # optimize flow insertion by usage of cache
- self._vswitch.add_flow(bridge, flow_template, cache='on')
- elif self._traffic['stream_type'] == 'L4':
- # read transport protocol from configuration and iterate through its destination port
- proto = _PROTO_TCP if self._traffic['l3']['proto'].lower() == 'tcp' else _PROTO_UDP
- for i in range(self._traffic['multistream']):
- flow_template.update({'dl_type':'0x0800', 'nw_proto':proto, 'tp_dst':i})
- # optimize flow insertion by usage of cache
- self._vswitch.add_flow(bridge, flow_template, cache='on')
- else:
- self._logger.error('Stream type is set to uknown value %s', self._traffic['stream_type'])
- # insert cached flows into the OVS
- self._vswitch.add_flow(bridge, [], cache='flush')
- else:
- self._vswitch.add_flow(bridge, flow_template)
+ self._vswitch.dump_connections(self._bridge)
diff --git a/core/vswitch_controller_ptunp.py b/core/vswitch_controller_ptunp.py
index 853c7d5c..b10da2a9 100644
--- a/core/vswitch_controller_ptunp.py
+++ b/core/vswitch_controller_ptunp.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2016 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,8 +15,6 @@
"""VSwitch controller for Physical to VxLAN Tunnel Endpoint to Physical
deployment with mod operation.
"""
-
-import logging
from netaddr import EUI, IPNetwork, mac_unix
from core.vswitch_controller import IVswitchController
@@ -24,10 +22,6 @@ from vswitches.utils import add_ports_to_flow
from conf import settings
from tools import tasks
-_FLOW_TEMPLATE = {
- 'idle_timeout': '0'
-}
-
class VswitchControllerPtunP(IVswitchController):
"""VSwitch controller for VxLAN ptunp deployment scenario.
The deployment scenario is to test VxLAN tunneling feature without using an
@@ -40,16 +34,10 @@ class VswitchControllerPtunP(IVswitchController):
_deployment_scenario: A string describing the scenario to set-up in the
constructor.
"""
- def __init__(self, vswitch_class, traffic):
- """Initializes up the prerequisites for the ptunp deployment scenario.
-
- :vswitch_class: the vSwitch class to be used.
+ def __init__(self, deployment, vswitch_class, traffic):
+ """See IVswitchController for general description
"""
- self._logger = logging.getLogger(__name__)
- self._vswitch_class = vswitch_class
- self._vswitch = vswitch_class()
- self._deployment_scenario = "ptunp"
- self._traffic = traffic.copy()
+ super().__init__(deployment, vswitch_class, traffic)
self.bridge_phy1 = settings.getValue('TUNNEL_EXTERNAL_BRIDGE1')
self.bridge_phy2 = settings.getValue('TUNNEL_EXTERNAL_BRIDGE2')
self.bridge_mod1 = settings.getValue('TUNNEL_MODIFY_BRIDGE1')
@@ -59,7 +47,6 @@ class VswitchControllerPtunP(IVswitchController):
self.br_mod_ip1 = settings.getValue('TUNNEL_MODIFY_BRIDGE_IP1')
self.br_mod_ip2 = settings.getValue('TUNNEL_MODIFY_BRIDGE_IP2')
self.tunnel_type = settings.getValue('TUNNEL_TYPE')
- self._logger.debug('Creation using %s', str(self._vswitch_class))
def setup(self):
""" Sets up the switch for VxLAN overlay PTUNP (tunnel encap or decap)
@@ -156,23 +143,23 @@ class VswitchControllerPtunP(IVswitchController):
self._vswitch.del_flow(self.bridge_phy2)
self._vswitch.del_flow(self.bridge_mod1)
self._vswitch.del_flow(self.bridge_mod2)
- flow = add_ports_to_flow(_FLOW_TEMPLATE, phy1_number,
+ flow = add_ports_to_flow(settings.getValue('OVS_FLOW_TEMPLATE'), phy1_number,
phy3_number)
self._vswitch.add_flow(self.bridge_phy1, flow)
- flow = add_ports_to_flow(_FLOW_TEMPLATE, phy3_number,
+ flow = add_ports_to_flow(settings.getValue('OVS_FLOW_TEMPLATE'), phy3_number,
phy1_number)
self._vswitch.add_flow(self.bridge_phy1, flow)
- flow = add_ports_to_flow(_FLOW_TEMPLATE, phy2_number,
+ flow = add_ports_to_flow(settings.getValue('OVS_FLOW_TEMPLATE'), phy2_number,
phy4_number)
self._vswitch.add_flow(self.bridge_phy2, flow)
- flow = add_ports_to_flow(_FLOW_TEMPLATE, phy4_number,
+ flow = add_ports_to_flow(settings.getValue('OVS_FLOW_TEMPLATE'), phy4_number,
phy2_number)
self._vswitch.add_flow(self.bridge_phy2, flow)
- flow = add_ports_to_flow(_FLOW_TEMPLATE, phy5_number,
+ flow = add_ports_to_flow(settings.getValue('OVS_FLOW_TEMPLATE'), phy5_number,
'LOCAL')
self._vswitch.add_flow(self.bridge_mod1, flow)
- mod_flow_template = _FLOW_TEMPLATE.copy()
+ mod_flow_template = settings.getValue('OVS_FLOW_TEMPLATE').copy()
mod_flow_template.update({'ip':'',
'actions':
['mod_dl_src:' + str(vxlan_rem_mac2),
@@ -183,10 +170,10 @@ class VswitchControllerPtunP(IVswitchController):
})
flow = add_ports_to_flow(mod_flow_template, 'LOCAL', phy5_number)
self._vswitch.add_flow(self.bridge_mod1, flow)
- flow = add_ports_to_flow(_FLOW_TEMPLATE, phy6_number,
+ flow = add_ports_to_flow(settings.getValue('OVS_FLOW_TEMPLATE'), phy6_number,
'LOCAL')
self._vswitch.add_flow(self.bridge_mod2, flow)
- mod_flow_template = _FLOW_TEMPLATE.copy()
+ mod_flow_template = settings.getValue('OVS_FLOW_TEMPLATE').copy()
mod_flow_template.update({'ip':'',
'actions':
['mod_dl_src:' + str(vxlan_rem_mac1),
@@ -207,17 +194,6 @@ class VswitchControllerPtunP(IVswitchController):
self._logger.debug('Stop using %s', str(self._vswitch_class))
self._vswitch.stop()
- def __enter__(self):
- self.setup()
-
- def __exit__(self, type_, value, traceback):
- self.stop()
-
- def get_vswitch(self):
- """See IVswitchController for description
- """
- return self._vswitch
-
def get_ports_info(self):
"""See IVswitchController for description
"""
@@ -228,11 +204,11 @@ class VswitchControllerPtunP(IVswitchController):
self._vswitch.get_ports(self.bridge_mod2)
return ports
- def dump_vswitch_flows(self):
+ def dump_vswitch_connections(self):
"""See IVswitchController for description
"""
- self._logger.debug('dump_flows using %s', str(self._vswitch_class))
- self._vswitch.dump_flows(self.bridge_phy1)
- self._vswitch.dump_flows(self.bridge_mod1)
- self._vswitch.dump_flows(self.bridge_phy2)
- self._vswitch.dump_flows(self.bridge_mod2)
+ self._logger.debug('dump_connections using %s', str(self._vswitch_class))
+ self._vswitch.dump_connections(self.bridge_phy1)
+ self._vswitch.dump_connections(self.bridge_mod1)
+ self._vswitch.dump_connections(self.bridge_phy2)
+ self._vswitch.dump_connections(self.bridge_mod2)
diff --git a/core/vswitch_controller_pxp.py b/core/vswitch_controller_pxp.py
index e3c208a3..d36ecdba 100644
--- a/core/vswitch_controller_pxp.py
+++ b/core/vswitch_controller_pxp.py
@@ -1,4 +1,4 @@
-# Copyright 2016 Intel Corporation.
+# Copyright 2016-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,34 +14,18 @@
"""VSwitch controller for multi VM scenarios with serial or parallel connection
"""
-
-import logging
import netaddr
from core.vswitch_controller import IVswitchController
-from vswitches.utils import add_ports_to_flow
from conf import settings
-_FLOW_TEMPLATE = {
- 'idle_timeout': '0'
-}
-
-_PROTO_TCP = 6
-_PROTO_UDP = 17
-
class VswitchControllerPXP(IVswitchController):
"""VSwitch controller for PXP deployment scenario.
"""
def __init__(self, deployment, vswitch_class, traffic):
- """Initializes up the prerequisites for the PXP deployment scenario.
-
- :vswitch_class: the vSwitch class to be used.
- :deployment: the deployment scenario to configure
- :traffic: dictionary with detailed traffic definition
+ """See IVswitchController for general description
"""
- self._logger = logging.getLogger(__name__)
- self._vswitch_class = vswitch_class
- self._vswitch = vswitch_class()
+ super().__init__(deployment, vswitch_class, traffic)
self._pxp_topology = 'parallel' if deployment.startswith('pvpv') else 'serial'
if deployment == 'pvp':
self._pxp_vm_count = 1
@@ -55,9 +39,7 @@ class VswitchControllerPXP(IVswitchController):
self._deployment_scenario = deployment
- self._traffic = traffic.copy()
self._bidir = True if self._traffic['bidir'] == 'True' else False
- self._logger.debug('Creation using %s', str(self._vswitch_class))
self._bridge = settings.getValue('VSWITCH_BRIDGE_NAME')
def setup(self):
@@ -71,8 +53,8 @@ class VswitchControllerPXP(IVswitchController):
self._vswitch.add_switch(self._bridge)
# create physical ports
- (_, phy1_number) = self._vswitch.add_phy_port(self._bridge)
- (_, phy2_number) = self._vswitch.add_phy_port(self._bridge)
+ (phy1, _) = self._vswitch.add_phy_port(self._bridge)
+ (phy2, _) = self._vswitch.add_phy_port(self._bridge)
# create VM ports
# initialize vport array to requested number of VMs
@@ -86,54 +68,42 @@ class VswitchControllerPXP(IVswitchController):
self._logger.debug('Create %s vports for %s. VM with index %s',
nics_nr, vmindex + 1, vmindex)
for _ in range(nics_nr):
- (_, vport) = self._vswitch.add_vport(self._bridge)
+ (vport, _) = self._vswitch.add_vport(self._bridge)
vm_ports[vmindex].append(vport)
- self._vswitch.del_flow(self._bridge)
-
- # configure flows according to the TC definition
+ # configure connections according to the TC definition
if self._pxp_topology == 'serial':
- flow = _FLOW_TEMPLATE.copy()
- if self._traffic['flow_type'] == 'IP':
- flow.update({'dl_type':'0x0800',
- 'nw_src':self._traffic['l3']['srcip'],
- 'nw_dst':self._traffic['l3']['dstip']})
+ # NOTE: all traffic from VMs is sent to other ports directly
+ # without applying traffic options to avoid issues with MAC swapping
+ # and upper layer mods performed inside guests
- # insert flows for phy ports first
+ # insert connections for phy ports first
# from 1st PHY to 1st vport of 1st VM
- self._add_flow(flow,
- phy1_number,
- vm_ports[0][0],
- self._bidir)
+ self._vswitch.add_connection(self._bridge, phy1, vm_ports[0][0], self._traffic)
+ self._vswitch.add_connection(self._bridge, vm_ports[0][0], phy1)
# from last vport of last VM to 2nd phy
- self._add_flow(flow,
- vm_ports[self._pxp_vm_count-1][-1],
- phy2_number,
- self._bidir)
+ self._vswitch.add_connection(self._bridge, vm_ports[self._pxp_vm_count-1][-1], phy2)
+ self._vswitch.add_connection(self._bridge, phy2, vm_ports[self._pxp_vm_count-1][-1], self._traffic)
# add serial connections among VMs and VM NICs pairs if needed
# in case of multiple NICs pairs per VM, the pairs are chained
- # first, before flow to the next VM is created
+ # first, before connection to the next VM is created
for vmindex in range(self._pxp_vm_count):
# connect VMs NICs pairs in case of 4 and more NICs per VM
connections = [(vm_ports[vmindex][2*(x+1)-1],
vm_ports[vmindex][2*(x+1)])
for x in range(int(len(vm_ports[vmindex])/2)-1)]
for connection in connections:
- self._add_flow(flow,
- connection[0],
- connection[1],
- self._bidir)
+ self._vswitch.add_connection(self._bridge, connection[0], connection[1])
+ self._vswitch.add_connection(self._bridge, connection[1], connection[0])
# connect last NICs to the next VM if there is any
if self._pxp_vm_count > vmindex + 1:
- self._add_flow(flow,
- vm_ports[vmindex][-1],
- vm_ports[vmindex+1][0],
- self._bidir)
+ self._vswitch.add_connection(self._bridge, vm_ports[vmindex][-1], vm_ports[vmindex+1][0])
+ self._vswitch.add_connection(self._bridge, vm_ports[vmindex+1][0], vm_ports[vmindex][-1])
else:
- proto = _PROTO_TCP if self._traffic['l3']['proto'].lower() == 'tcp' else _PROTO_UDP
- dst_mac_value = netaddr.EUI(self._traffic['l2']['dstmac']).value
- dst_ip_value = netaddr.IPAddress(self._traffic['l3']['dstip']).value
+ mac_value = netaddr.EUI(self._traffic['l2']['dstmac']).value
+ ip_value = netaddr.IPAddress(self._traffic['l3']['dstip']).value
+ port_value = self._traffic['l4']['dstport']
# initialize stream index; every NIC pair of every VM uses unique stream
stream = 0
for vmindex in range(self._pxp_vm_count):
@@ -146,31 +116,33 @@ class VswitchControllerPXP(IVswitchController):
port_pairs = [(vm_ports[vmindex][0], vm_ports[vmindex][0])]
for port_pair in port_pairs:
- flow_p = _FLOW_TEMPLATE.copy()
- flow_v = _FLOW_TEMPLATE.copy()
-
- # update flow based on trafficgen settings
+ # override traffic options to ensure, that traffic is
+ # dispatched among VMs connected in parallel
+ options = {'multistream':1,
+ 'stream_type':self._traffic['stream_type'],
+ 'pre_installed_flows':'Yes'}
+ # update connection based on trafficgen settings
if self._traffic['stream_type'] == 'L2':
- tmp_mac = netaddr.EUI(dst_mac_value + stream)
+ tmp_mac = netaddr.EUI(mac_value + stream)
tmp_mac.dialect = netaddr.mac_unix_expanded
- flow_p.update({'dl_dst':tmp_mac})
+ options.update({'l2':{'dstmac':tmp_mac}})
elif self._traffic['stream_type'] == 'L3':
- tmp_ip = netaddr.IPAddress(dst_ip_value + stream)
- flow_p.update({'dl_type':'0x0800', 'nw_dst':tmp_ip})
+ tmp_ip = netaddr.IPAddress(ip_value + stream)
+ options.update({'l3':{'dstip':tmp_ip}})
elif self._traffic['stream_type'] == 'L4':
- flow_p.update({'dl_type':'0x0800', 'nw_proto':proto, 'tp_dst':stream})
+ options.update({'l3':{'proto':self._traffic['l3']['proto']}})
+ options.update({'l4':{'dstport':(port_value + stream) % 65536}})
else:
raise RuntimeError('Unknown stream_type {}'.format(self._traffic['stream_type']))
- # insert flow to dispatch traffic from physical ports
+ # insert connection to dispatch traffic from physical ports
# to VMs based on stream type; all traffic from VMs is
# sent to physical ports to avoid issues with MAC swapping
# and upper layer mods performed inside guests
- self._add_flow(flow_p, phy1_number, port_pair[0])
- self._add_flow(flow_v, port_pair[1], phy2_number)
- if self._bidir:
- self._add_flow(flow_p, phy2_number, port_pair[1])
- self._add_flow(flow_v, port_pair[0], phy1_number)
+ self._vswitch.add_connection(self._bridge, phy1, port_pair[0], options)
+ self._vswitch.add_connection(self._bridge, port_pair[1], phy2)
+ self._vswitch.add_connection(self._bridge, phy2, port_pair[1], options)
+ self._vswitch.add_connection(self._bridge, port_pair[0], phy1)
# every NIC pair needs its own unique traffic stream
stream += 1
@@ -185,37 +157,13 @@ class VswitchControllerPXP(IVswitchController):
self._logger.debug('Stop using %s', str(self._vswitch_class))
self._vswitch.stop()
- def _add_flow(self, flow, port1, port2, reverse_flow=False):
- """ Helper method to insert flow into the vSwitch
- """
- self._vswitch.add_flow(self._bridge,
- add_ports_to_flow(flow,
- port1,
- port2))
- if reverse_flow:
- self._vswitch.add_flow(self._bridge,
- add_ports_to_flow(flow,
- port2,
- port1))
-
- def __enter__(self):
- self.setup()
-
- def __exit__(self, type_, value, traceback):
- self.stop()
-
- def get_vswitch(self):
- """See IVswitchController for description
- """
- return self._vswitch
-
def get_ports_info(self):
"""See IVswitchController for description
"""
self._logger.debug('get_ports_info using %s', str(self._vswitch_class))
return self._vswitch.get_ports(self._bridge)
- def dump_vswitch_flows(self):
+ def dump_vswitch_connections(self):
"""See IVswitchController for description
"""
- self._vswitch.dump_flows(self._bridge)
+ self._vswitch.dump_connections(self._bridge)
diff --git a/docs/testing/developer/devguide/design/vswitchperf_design.rst b/docs/testing/developer/devguide/design/vswitchperf_design.rst
index 7fbde886..b8a3ba19 100644
--- a/docs/testing/developer/devguide/design/vswitchperf_design.rst
+++ b/docs/testing/developer/devguide/design/vswitchperf_design.rst
@@ -1,6 +1,6 @@
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
-.. (c) OPNFV, Intel Corporation, AT&T and others.
+.. (c) OPNFV, Intel Corporation, AT&T, Tieto and others.
.. _vsperf-design:
@@ -332,7 +332,6 @@ Detailed description of ``TRAFFIC`` dictionary items follows:
feature. If enabled, it will implicitly insert a flow
for each stream. If multistream is disabled, then
pre-installed flows will be ignored.
- Note: It is supported only for p2p deployment scenario.
Data type: str
Supported values:
"Yes" - flows will be inserted into OVS
@@ -777,6 +776,13 @@ As it is able to forward traffic between multiple VM NIC pairs.
Note: In case of ``linux_bridge``, all NICs are connected to the same
bridge inside the VM.
+Note: In case that multistream feature is configured and ``pre_installed_flows``
+is set to ``Yes``, then stream specific flows will be inserted only for connections
+originating at physical ports. The rest of the flows will be based on port
+numbers only. The same logic applies in case that ``flow_type`` TRAFFIC option
+is set to ``ip``. This configuration will avoid a testcase malfunction if frame headers
+are modified inside VM (e.g. MAC swap or IP change).
+
VM, vSwitch, Traffic Generator Independence
===========================================
@@ -912,6 +918,10 @@ Vsperf uses a standard set of routing tables in order to allow tests to easily
mix and match Deployment Scenarios (PVP, P2P topology), Tuple Matching and
Frame Modification requirements.
+The usage of routing tables is driven by configuration parameter ``OVS_ROUTING_TABLES``.
+Routing tables are disabled by default (i.e. parameter is set to ``False``) for better
+comparison of results among supported vSwitches (e.g. OVS vs. VPP).
+
.. code-block:: console
+--------------+
diff --git a/testcases/testcase.py b/testcases/testcase.py
index 809e3b34..a30558ff 100644
--- a/testcases/testcase.py
+++ b/testcases/testcase.py
@@ -373,7 +373,7 @@ class TestCase(object):
# dump vswitch flows before they are affected by VNF termination
if not self._vswitch_none:
- self._vswitch_ctl.dump_vswitch_flows()
+ self._vswitch_ctl.dump_vswitch_connections()
# garbage collection for case that TestSteps modify existing deployment
self.step_stop_vnfs()
diff --git a/vswitches/ovs.py b/vswitches/ovs.py
index be7b77df..6dbf0cf8 100644
--- a/vswitches/ovs.py
+++ b/vswitches/ovs.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2018 Intel Corporation, Tieto and Others.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,12 +15,13 @@
"""VSPERF Open vSwitch base class
"""
-import logging
import os
import re
import time
import datetime
import random
+import socket
+import netaddr
import pexpect
from conf import settings
@@ -28,6 +29,10 @@ from src.ovs import OFBridge, flow_key, flow_match
from vswitches.vswitch import IVSwitch
from tools import tasks
from tools.module_manager import ModuleManager
+
+# enable caching of flows if their number exceeds given limit
+_CACHE_FLOWS_LIMIT = 10
+
# pylint: disable=too-many-public-methods
class IVSwitchOvs(IVSwitch, tasks.Process):
"""Open vSwitch base class implementation
@@ -41,23 +46,31 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
def __init__(self):
"""See IVswitch for general description
"""
+ super().__init__()
self._logfile = os.path.join(settings.getValue('LOG_DIR'),
settings.getValue('LOG_FILE_VSWITCHD'))
self._ovsdb_pidfile_path = os.path.join(settings.getValue('TOOLS')['ovs_var_tmp'],
"ovsdb-server.pid")
self._vswitchd_pidfile_path = os.path.join(settings.getValue('TOOLS')['ovs_var_tmp'],
"{}.pid".format(self._proc_name))
- self._logger = logging.getLogger(__name__)
# sign '|' must be escaped or avoided, otherwise it is handled as 'or' by regex
self._expect = r'bridge.INFO.{}'.format(self._proc_name)
- self._timeout = 30
- self._bridges = {}
self._vswitchd_args = ['--pidfile=' + self._vswitchd_pidfile_path,
'--overwrite-pidfile', '--log-file=' + self._logfile]
- self._cmd = []
self._cmd_template = ['sudo', '-E', settings.getValue('TOOLS')['ovs-vswitchd']]
- self._stamp = None
self._module_manager = ModuleManager()
+ self._flow_template = settings.getValue('OVS_FLOW_TEMPLATE').copy()
+ self._flow_actions = ['output:{}']
+
+ # if routing tables are enabled, then flows should go into table 1
+ # see design document for details about Routing Tables feature
+ if settings.getValue('OVS_ROUTING_TABLES'):
+ # flows should be added into table 1
+ self._flow_template.update({'table':'1', 'priority':'1'})
+ # and chosen port will be propagated via metadata
+ self._flow_actions = ['write_actions(output:{})',
+ 'write_metadata:{}',
+ 'goto_table:2']
def start(self):
""" Start ``ovsdb-server`` and ``ovs-vswitchd`` instance.
@@ -85,7 +98,7 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
tasks.Process.start(self)
self.relinquish()
except (pexpect.EOF, pexpect.TIMEOUT) as exc:
- logging.error("Exception during VSwitch start.")
+ self._logger.error("Exception during VSwitch start.")
self._kill_ovsdb()
raise exc
@@ -107,7 +120,7 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
tasks.Process.start(self)
self.relinquish()
except (pexpect.EOF, pexpect.TIMEOUT) as exc:
- logging.error("Exception during VSwitch start.")
+ self._logger.error("Exception during VSwitch start.")
self._kill_ovsdb()
raise exc
self._logger.info("Vswitchd...Started.")
@@ -128,31 +141,57 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
def stop(self):
"""See IVswitch for general description
"""
- for switch_name in list(self._bridges):
+ for switch_name in list(self._switches):
self.del_switch(switch_name)
self._logger.info("Terminating vswitchd...")
self.kill()
- self._bridges = {}
+ self._switches = {}
self._logger.info("Vswitchd...Terminated.")
def add_switch(self, switch_name, params=None):
"""See IVswitch for general description
"""
+ # create and configure new ovs bridge and delete all default flows
bridge = OFBridge(switch_name)
bridge.create(params)
+ bridge.del_flow({})
bridge.set_db_attribute('Open_vSwitch', '.',
'other_config:max-idle',
settings.getValue('VSWITCH_FLOW_TIMEOUT'))
- self._bridges[switch_name] = bridge
+ self._switches[switch_name] = bridge
+ if settings.getValue('OVS_ROUTING_TABLES'):
+ # table#0 - flows designed to force 5 & 13 tuple matches go here
+ flow = {'table':'0', 'priority':'1', 'actions': ['goto_table:1']}
+ bridge.add_flow(flow)
+
+ # table#1 - flows to route packets between ports goes here. The
+ # chosen port is communicated to subsequent tables by setting the
+ # metadata value to the egress port number
+ #
+ # A placeholder - flows are added into this table by deployments
+ # or by TestSteps via add_connection() method
+
+ # table#2 - frame modification table. Frame modification flow rules are
+ # isolated in this table so that they can be turned on or off
+ # without affecting the routing or tuple-matching flow rules.
+ flow = {'table':'2', 'priority':'1', 'actions': ['goto_table:3']}
+ bridge.add_flow(flow)
+
+ # table#3 - egress table
+ # (NOTE) Billy O'Mahony - the drop action here actually required in
+ # order to egress the packet. This is the subject of a thread on
+ # ovs-discuss 2015-06-30.
+ flow = {'table':'3', 'priority':'1', 'actions': ['drop']}
+ bridge.add_flow(flow)
def del_switch(self, switch_name):
"""See IVswitch for general description
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
bridge.del_flow({})
for port in list(bridge.get_ports()):
bridge.del_port(port)
- self._bridges.pop(switch_name)
+ self._switches.pop(switch_name)
bridge.destroy()
def add_phy_port(self, switch_name):
@@ -173,8 +212,8 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
if switch_name is None or remote_switch_name is None:
return None
- bridge = self._bridges[switch_name]
- remote_bridge = self._bridges[remote_switch_name]
+ bridge = self._switches[switch_name]
+ remote_bridge = self._switches[remote_switch_name]
pcount = str(self._get_port_count('type=patch'))
# NOTE ::: What if interface name longer than allowed width??
local_port_name = switch_name + '-' + remote_switch_name + '-' + pcount
@@ -200,7 +239,7 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
def add_tunnel_port(self, switch_name, remote_ip, tunnel_type='vxlan', params=None):
"""Creates tunneling port
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
pcount = str(self._get_port_count('type=' + tunnel_type))
port_name = tunnel_type + pcount
local_params = ['--', 'set', 'Interface', port_name,
@@ -216,53 +255,123 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
def get_ports(self, switch_name):
"""See IVswitch for general description
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
ports = list(bridge.get_ports().items())
return [(name, of_port) for (name, (of_port, _)) in ports]
def del_port(self, switch_name, port_name):
"""See IVswitch for general description
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
bridge.del_port(port_name)
def add_flow(self, switch_name, flow, cache='off'):
"""See IVswitch for general description
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
bridge.add_flow(flow, cache=cache)
def del_flow(self, switch_name, flow=None):
"""See IVswitch for general description
"""
flow = flow or {}
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
bridge.del_flow(flow)
def dump_flows(self, switch_name):
"""See IVswitch for general description
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
bridge.dump_flows()
+ def _prepare_flows(self, operation, switch_name, port1, port2, traffic=None):
+ """Prepare flows for add_connection, del_connection and validate methods
+ It returns a list of flows based on given parameters.
+ """
+ flows = []
+ if operation == 'add':
+ bridge = self._switches[switch_name]
+ flow = self._flow_template.copy()
+ actions = [action.format(bridge.get_ports()[port2][0]) for action in self._flow_actions]
+ flow.update({'in_port': bridge.get_ports()[port1][0], 'actions': actions})
+ # check if stream specific connection(s) should be crated for multistream feature
+ if traffic and traffic['pre_installed_flows'].lower() == 'yes':
+ for stream in range(traffic['multistream']):
+ tmp_flow = flow.copy()
+ # update flow based on trafficgen settings
+ if traffic['stream_type'] == 'L2':
+ dst_mac_value = netaddr.EUI(traffic['l2']['dstmac']).value
+ tmp_mac = netaddr.EUI(dst_mac_value + stream)
+ tmp_mac.dialect = netaddr.mac_unix_expanded
+ tmp_flow.update({'dl_dst':tmp_mac})
+ elif traffic['stream_type'] == 'L3':
+ dst_ip_value = netaddr.IPAddress(traffic['l3']['dstip']).value
+ tmp_ip = netaddr.IPAddress(dst_ip_value + stream)
+ tmp_flow.update({'dl_type':'0x0800', 'nw_dst':tmp_ip})
+ elif traffic['stream_type'] == 'L4':
+ tmp_flow.update({'dl_type':'0x0800',
+ 'nw_proto':socket.getprotobyname(traffic['l3']['proto'].lower()),
+ 'tp_dst':(traffic['l4']['dstport'] + stream) % 65536})
+ flows.append(tmp_flow)
+ elif traffic and traffic['flow_type'].lower() == 'ip':
+ flow.update({'dl_type':'0x0800', 'nw_src':traffic['l3']['srcip'],
+ 'nw_dst':traffic['l3']['dstip']})
+ flows.append(flow)
+ else:
+ flows.append(flow)
+ elif operation == 'del' and port1:
+ bridge = self._switches[switch_name]
+ flows.append({'in_port': bridge.get_ports()[port1][0]})
+ else:
+ flows.append({})
+
+ return flows
+
+ def add_connection(self, switch_name, port1, port2, traffic=None):
+ """See IVswitch for general description
+ """
+ flows = self._prepare_flows('add', switch_name, port1, port2, traffic)
+
+ # enable flows caching for large number of flows
+ cache = 'on' if len(flows) > _CACHE_FLOWS_LIMIT else 'off'
+
+ for flow in flows:
+ self.add_flow(switch_name, flow, cache)
+
+ if cache == 'on':
+ self.add_flow(switch_name, [], cache='flush')
+
+ def del_connection(self, switch_name, port1=None, port2=None):
+ """See IVswitch for general description
+ """
+ flows = self._prepare_flows('del', switch_name, port1, port2)
+
+ for flow in flows:
+ self.del_flow(switch_name, flow)
+
+ def dump_connections(self, switch_name):
+ """See IVswitch for general description
+ """
+ self.dump_flows(switch_name)
+
def add_route(self, switch_name, network, destination):
"""See IVswitch for general description
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
bridge.add_route(network, destination)
def set_tunnel_arp(self, ip_addr, mac_addr, switch_name):
"""See IVswitch for general description
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
bridge.set_tunnel_arp(ip_addr, mac_addr, switch_name)
def _get_port_count(self, param):
"""Returns the number of ports having a certain parameter
"""
cnt = 0
- for k in self._bridges:
- pparams = [c for (_, (_, c)) in list(self._bridges[k].get_ports().items())]
+ for k in self._switches:
+ pparams = [c for (_, (_, c)) in list(self._switches[k].get_ports().items())]
phits = [i for i in pparams if param in i]
cnt += len(phits)
@@ -276,7 +385,7 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
:param switch_name: bridge to disable stp
:return: None
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
bridge.set_stp(False)
self._logger.info('Sleeping for 50 secs to allow stp to stop.')
time.sleep(50) # needs time to disable
@@ -287,7 +396,7 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
:param switch_name: bridge to enable stp
:return: None
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
bridge.set_stp(True)
self._logger.info('Sleeping for 50 secs to allow stp to start.')
time.sleep(50) # needs time to enable
@@ -298,7 +407,7 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
:param switch_name: bridge to disable rstp
:return: None
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
bridge.set_rstp(False)
self._logger.info('Sleeping for 15 secs to allow rstp to stop.')
time.sleep(15) # needs time to disable
@@ -309,7 +418,7 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
:param switch_name: bridge to enable rstp
:return: None
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
bridge.set_rstp(True)
self._logger.info('Sleeping for 15 secs to allow rstp to start.')
time.sleep(15) # needs time to enable
@@ -417,7 +526,7 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
def validate_add_switch(self, _dummy_result, switch_name, _dummy_params=None):
"""Validate - Create a new logical switch with no ports
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
output = bridge.run_vsctl(['show'], check_error=True)
assert not output[1] # there shouldn't be any stderr, but in case
assert re.search('Bridge ["\']?%s["\']?' % switch_name, output[0]) is not None
@@ -437,7 +546,7 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
def validate_add_phy_port(self, result, switch_name):
""" Validate that physical port was added to bridge.
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
output = bridge.run_vsctl(['show'], check_error=True)
assert not output[1] # there shouldn't be any stderr, but in case
assert re.search('Port ["\']?%s["\']?' % result[0], output[0]) is not None
@@ -452,12 +561,35 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
def validate_del_port(self, _dummy_result, switch_name, port_name):
""" Validate that port_name was removed from bridge.
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
output = bridge.run_vsctl(['show'], check_error=True)
assert not output[1] # there shouldn't be any stderr, but in case
assert 'Port "%s"' % port_name not in output[0]
return True
+ def validate_add_connection(self, result, switch_name, port1, port2, traffic=None):
+ """ Validate that connection was added
+ """
+ for flow in self._prepare_flows('add', switch_name, port1, port2, traffic):
+ if not self.validate_add_flow(result, switch_name, flow):
+ return False
+
+ return True
+
+ def validate_del_connection(self, result, switch_name, port1, port2):
+ """ Validate that connection was deleted
+ """
+ for flow in self._prepare_flows('del', switch_name, port1, port2):
+ if not self.validate_del_flow(result, switch_name, flow):
+ return False
+
+ return True
+
+ def validate_dump_connections(self, _dummy_result, _dummy_switch_name):
+ """ Validate dump connections call
+ """
+ return True
+
def validate_add_flow(self, _dummy_result, switch_name, flow, _dummy_cache='off'):
""" Validate insertion of the flow into the switch
"""
@@ -471,7 +603,7 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
# get dump of flows and compare them one by one
flow_src = flow_key(flow)
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
output = bridge.run_ofctl(['dump-flows', switch_name], check_error=True)
for flow_dump in output[0].split('\n'):
if flow_match(flow_dump, flow_src):
@@ -495,25 +627,25 @@ class IVSwitchOvs(IVSwitch, tasks.Process):
def validate_disable_rstp(self, _dummy_result, switch_name):
""" Validate rstp disable
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
return 'rstp_enable : false' in ''.join(bridge.bridge_info())
def validate_enable_rstp(self, _dummy_result, switch_name):
""" Validate rstp enable
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
return 'rstp_enable : true' in ''.join(bridge.bridge_info())
def validate_disable_stp(self, _dummy_result, switch_name):
""" Validate stp disable
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
return 'stp_enable : false' in ''.join(bridge.bridge_info())
def validate_enable_stp(self, _dummy_result, switch_name):
""" Validate stp enable
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
return 'stp_enable : true' in ''.join(bridge.bridge_info())
def validate_restart(self, _dummy_result):
diff --git a/vswitches/ovs_dpdk_vhost.py b/vswitches/ovs_dpdk_vhost.py
index 6deb0c25..8da043c6 100644
--- a/vswitches/ovs_dpdk_vhost.py
+++ b/vswitches/ovs_dpdk_vhost.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2017 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
"""VSPERF VSwitch implementation using DPDK and vhost ports
"""
-import logging
import subprocess
from src.ovs import OFBridge
@@ -36,9 +35,7 @@ class OvsDpdkVhost(IVSwitchOvs):
"""
def __init__(self):
- super(OvsDpdkVhost, self).__init__()
- self._logger = logging.getLogger(__name__)
-
+ super().__init__()
vswitchd_args = []
# legacy DPDK configuration through --dpdk option of vswitchd
@@ -104,9 +101,9 @@ class OvsDpdkVhost(IVSwitchOvs):
if S.getValue('VSWITCH_AFFINITIZATION_ON') == 1:
# Sets the PMD core mask to VSWITCH_PMD_CPU_MASK
# for CPU core affinitization
- self._bridges[switch_name].set_db_attribute('Open_vSwitch', '.',
- 'other_config:pmd-cpu-mask',
- S.getValue('VSWITCH_PMD_CPU_MASK'))
+ self._switches[switch_name].set_db_attribute('Open_vSwitch', '.',
+ 'other_config:pmd-cpu-mask',
+ S.getValue('VSWITCH_PMD_CPU_MASK'))
def add_phy_port(self, switch_name):
"""See IVswitch for general description
@@ -115,7 +112,7 @@ class OvsDpdkVhost(IVSwitchOvs):
The new port is named dpdk<n> where n is an integer starting from 0.
"""
_nics = S.getValue('NICS')
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
dpdk_count = self._get_port_count('type=dpdk')
if dpdk_count == len(_nics):
raise RuntimeError("Can't add phy port! There are only {} ports defined "
@@ -144,7 +141,7 @@ class OvsDpdkVhost(IVSwitchOvs):
The new port is named dpdkvhost<n> where n is an integer starting
from 0
"""
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
if S.getValue('VSWITCH_VHOSTUSER_SERVER_MODE'):
nic_type = 'dpdkvhostuser'
@@ -177,18 +174,3 @@ class OvsDpdkVhost(IVSwitchOvs):
return True
except subprocess.CalledProcessError:
return False
-
- def add_connection(self, switch_name, port1, port2, bidir=False):
- """See IVswitch for general description
- """
- raise NotImplementedError()
-
- def del_connection(self, switch_name, port1, port2, bidir=False):
- """See IVswitch for general description
- """
- raise NotImplementedError()
-
- def dump_connections(self, switch_name):
- """See IVswitch for general description
- """
- raise NotImplementedError()
diff --git a/vswitches/ovs_vanilla.py b/vswitches/ovs_vanilla.py
index 83c52050..d23a0c61 100644
--- a/vswitches/ovs_vanilla.py
+++ b/vswitches/ovs_vanilla.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2017 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
"""VSPERF Vanilla OVS implementation
"""
-import logging
import time
from conf import settings
from vswitches.ovs import IVSwitchOvs
@@ -36,9 +35,8 @@ class OvsVanilla(IVSwitchOvs):
_vport_id = 0
def __init__(self):
- super(OvsVanilla, self).__init__()
+ super().__init__()
self._ports = list(nic['device'] for nic in settings.getValue('NICS'))
- self._logger = logging.getLogger(__name__)
self._vswitchd_args += ["unix:%s" % self.get_db_sock_path()]
self._vswitchd_args += settings.getValue('VSWITCHD_VANILLA_ARGS')
@@ -81,7 +79,7 @@ class OvsVanilla(IVSwitchOvs):
self._logger.error("Can't detect device name for NIC %s", self._current_id)
raise ValueError("Invalid device name for %s" % self._current_id)
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
port_name = self._ports[self._current_id]
params = []
@@ -129,21 +127,6 @@ class OvsVanilla(IVSwitchOvs):
tasks.run_task(['sudo', 'ip', 'link', 'set', 'dev', tap_name, 'up'],
self._logger, 'Bring up ' + tap_name, False)
- bridge = self._bridges[switch_name]
+ bridge = self._switches[switch_name]
of_port = bridge.add_port(tap_name, [])
return (tap_name, of_port)
-
- def add_connection(self, switch_name, port1, port2, bidir=False):
- """See IVswitch for general description
- """
- raise NotImplementedError()
-
- def del_connection(self, switch_name, port1, port2, bidir=False):
- """See IVswitch for general description
- """
- raise NotImplementedError()
-
- def dump_connections(self, switch_name):
- """See IVswitch for general description
- """
- raise NotImplementedError()
diff --git a/vswitches/vpp_dpdk_vhost.py b/vswitches/vpp_dpdk_vhost.py
index 15e32f32..5d676a01 100644
--- a/vswitches/vpp_dpdk_vhost.py
+++ b/vswitches/vpp_dpdk_vhost.py
@@ -1,4 +1,4 @@
-# Copyright 2017 Intel Corporation.
+# Copyright 2017-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
"""VSPERF VPP implementation using DPDK and vhostuser vports
"""
-import logging
import os
import copy
import re
@@ -37,19 +36,13 @@ class VppDpdkVhost(IVSwitch, tasks.Process):
def __init__(self):
"""See IVswitch for general description
"""
+ super().__init__()
self._logfile = os.path.join(S.getValue('LOG_DIR'),
S.getValue('LOG_FILE_VPP'))
- self._logger = logging.getLogger(__name__)
self._expect = r'vpp#'
- self._timeout = 30
- self._vswitch_args = []
- self._cmd = []
self._cmd_template = ['sudo', '-E', S.getValue('TOOLS')['vpp']]
- self._stamp = None
- self._logger = logging.getLogger(__name__)
self._phy_ports = []
self._virt_ports = []
- self._switches = {}
self._vpp_ctl = ['sudo', S.getValue('TOOLS')['vppctl']]
# configure DPDK NICs
@@ -151,7 +144,7 @@ class VppDpdkVhost(IVSwitch, tasks.Process):
tasks.Process.start(self)
self.relinquish()
except (pexpect.EOF, pexpect.TIMEOUT) as exc:
- logging.error("Exception during VPP start.")
+ self._logger.error("Exception during VPP start.")
raise exc
self._logger.info("VPP...Started.")
@@ -269,21 +262,17 @@ class VppDpdkVhost(IVSwitch, tasks.Process):
else:
self._logger.warning("Port %s is not configured.", port_name)
- def add_l2patch(self, port1, port2, bidir=False):
+ def add_l2patch(self, port1, port2):
"""Create l2patch connection between given ports
"""
self.run_vppctl(['test', 'l2patch', 'rx', port1, 'tx', port2])
- if bidir:
- self.run_vppctl(['test', 'l2patch', 'rx', port2, 'tx', port1])
- def add_xconnect(self, port1, port2, bidir=False):
+ def add_xconnect(self, port1, port2):
"""Create l2patch connection between given ports
"""
self.run_vppctl(['set', 'interface', 'l2', 'xconnect', port1, port2])
- if bidir:
- self.run_vppctl(['set', 'interface', 'l2', 'xconnect', port2, port1])
- def add_bridge(self, switch_name, port1, port2, _dummy_bidir=False):
+ def add_bridge(self, switch_name, port1, port2):
"""Add given ports to bridge ``switch_name``
"""
self.run_vppctl(['set', 'interface', 'l2', 'bridge', port1,
@@ -291,33 +280,33 @@ class VppDpdkVhost(IVSwitch, tasks.Process):
self.run_vppctl(['set', 'interface', 'l2', 'bridge', port2,
str(self._switches[switch_name])])
- def add_connection(self, switch_name, port1, port2, bidir=False):
+ def add_connection(self, switch_name, port1, port2, traffic=None):
"""See IVswitch for general description
:raises: RuntimeError
"""
+ if traffic:
+ self._logger.warning("VPP add_connection() does not support 'traffic' options.")
+
mode = S.getValue('VSWITCH_VPP_L2_CONNECT_MODE')
if mode == 'l2patch':
- self.add_l2patch(port1, port2, bidir)
+ self.add_l2patch(port1, port2)
elif mode == 'xconnect':
- self.add_xconnect(port1, port2, bidir)
+ self.add_xconnect(port1, port2)
elif mode == 'bridge':
self.add_bridge(switch_name, port1, port2)
else:
raise RuntimeError('VPP: Unsupported l2 connection mode detected %s' % mode)
- def del_l2patch(self, port1, port2, bidir=False):
+ def del_l2patch(self, port1, port2):
"""Remove l2patch connection between given ports
:param port1: port to be used in connection
:param port2: port to be used in connection
- :param bidir: switch between uni and bidirectional traffic
"""
self.run_vppctl(['test', 'l2patch', 'rx', port1, 'tx', port2, 'del'])
- if bidir:
- self.run_vppctl(['test', 'l2patch', 'rx', port2, 'tx', port1, 'del'])
- def del_xconnect(self, port1, port2, _dummy_bidir=False):
+ def del_xconnect(self, port1, port2):
"""Remove xconnect connection between given ports
"""
self.run_vppctl(['set', 'interface', 'l3', port1])
@@ -329,20 +318,21 @@ class VppDpdkVhost(IVSwitch, tasks.Process):
self.run_vppctl(['set', 'interface', 'l3', port1])
self.run_vppctl(['set', 'interface', 'l3', port2])
- def del_connection(self, switch_name, port1, port2, bidir=False):
+ def del_connection(self, switch_name, port1=None, port2=None):
"""See IVswitch for general description
:raises: RuntimeError
"""
- mode = S.getValue('VSWITCH_VPP_L2_CONNECT_MODE')
- if mode == 'l2patch':
- self.del_l2patch(port1, port2, bidir)
- elif mode == 'xconnect':
- self.del_xconnect(port1, port2, bidir)
- elif mode == 'bridge':
- self.del_bridge(switch_name, port1, port2)
- else:
- raise RuntimeError('VPP: Unsupported l2 connection mode detected %s' % mode)
+ if port1 and port2:
+ mode = S.getValue('VSWITCH_VPP_L2_CONNECT_MODE')
+ if mode == 'l2patch':
+ self.del_l2patch(port1, port2)
+ elif mode == 'xconnect':
+ self.del_xconnect(port1, port2)
+ elif mode == 'bridge':
+ self.del_bridge(switch_name, port1, port2)
+ else:
+ raise RuntimeError('VPP: Unsupported l2 connection mode detected %s' % mode)
def dump_l2patch(self):
"""Dump l2patch connections
@@ -417,13 +407,13 @@ class VppDpdkVhost(IVSwitch, tasks.Process):
# pylint: disable=no-self-use
def validate_add_connection(self, _dummy_result, _dummy_switch_name, _dummy_port1,
- _dummy_port2, _dummy_bidir=False):
+ _dummy_port2, _dummy_traffic=None):
""" Validate that connection was added
"""
return True
def validate_del_connection(self, _dummy_result, _dummy_switch_name, _dummy_port1,
- _dummy_port2, _dummy_bidir=False):
+ _dummy_port2):
""" Validate that connection was deleted
"""
return True
@@ -442,21 +432,6 @@ class VppDpdkVhost(IVSwitch, tasks.Process):
#
# Non implemented methods
#
- def add_flow(self, switch_name, flow, cache='off'):
- """See IVswitch for general description
- """
- raise NotImplementedError()
-
- def del_flow(self, switch_name, flow=None):
- """See IVswitch for general description
- """
- raise NotImplementedError()
-
- def dump_flows(self, switch_name):
- """See IVswitch for general description
- """
- raise NotImplementedError()
-
def add_route(self, switch_name, network, destination):
"""See IVswitch for general description
"""
diff --git a/vswitches/vswitch.py b/vswitches/vswitch.py
index efa3a349..a3d4e974 100644
--- a/vswitches/vswitch.py
+++ b/vswitches/vswitch.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2016 Intel Corporation.
+# Copyright 2015-2018 Intel Corporation., Tieto
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,12 +14,23 @@
"""Generic interface VSPERF uses for controlling a vSwitch
"""
+import logging
class IVSwitch(object):
"""Interface class that is implemented by vSwitch-specific classes
Other methods are called only between start() and stop()
"""
+ def __init__(self):
+ """Initialization of vswitch class
+ """
+ self._timeout = 30
+ self._switches = {}
+ self._logger = logging.getLogger(__name__)
+ self._cmd = []
+ self._vswitch_args = []
+ self._stamp = None
+
def get_version(self):
"""Return version of vSwitch and DPDK (if used by vSwitch)
This method should be implemented in case, that version
@@ -112,58 +123,23 @@ class IVSwitch(object):
"""
raise NotImplementedError()
- def add_flow(self, switch_name, flow, cache='off'):
- """Add a flow rule to the logical switch
-
- :param switch_name: The switch on which to operate
- :param flow: Flow description as a dictionary
- :param cache: Optional. Specifies if flow should be inserted
- to the switch or cached to increase performance during manipulation
- with large number of flows.
- Values:
- 'off' - cache is off and flow is inserted directly to the switch
- 'on' - cache is on and flow is inserted into the cache
- 'flush' - cache content will be inserted into the switch
-
- Example flow dictionary:
- flow = {
- 'in_port': '1',
- 'idle_timeout': '0',
- 'actions': ['output:3']
- }
- """
- raise NotImplementedError()
-
- def del_flow(self, switch_name, flow=None):
- """Delete the flow rule from the logical switch
-
- :param switch_name: The switch on which to operate
- :param flow: Flow description as a dictionary
-
- For flow dictionary description, see add_flow
- For flow==None, all flows are deleted
- """
- raise NotImplementedError()
-
- def add_connection(self, switch_name, port1, port2, bidir=False):
+ def add_connection(self, switch_name, port1, port2, traffic=None):
"""Creates connection between given ports.
:param switch_name: switch on which to operate
:param port1: port to be used in connection
:param port2: port to be used in connection
- :param bidir: switch between uni and bidirectional traffic
:raises: RuntimeError
"""
raise NotImplementedError()
- def del_connection(self, switch_name, port1, port2, bidir=False):
+ def del_connection(self, switch_name, port1=None, port2=None):
"""Remove connection between two interfaces.
:param switch_name: switch on which to operate
:param port1: port to be used in connection
:param port2: port to be used in connection
- :param bidir: switch between uni and bidirectional traffic
:raises: RuntimeError
"""
@@ -178,13 +154,6 @@ class IVSwitch(object):
"""
raise NotImplementedError()
- def dump_flows(self, switch_name):
- """Dump flows from the logical switch
-
- :param switch_name: The switch on which to operate
- """
- raise NotImplementedError()
-
def add_route(self, switch_name, network, destination):
"""Add a route for tunneling routing table