blob: 8800705f0fd2620b6c01f5e757810cca6fdedb6e [file] [log] [blame]
Matteo Scandoloa229eca2017-08-08 13:05:28 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
Dan Talayco79c6c4d2010-06-08 14:01:53 -070017"""
18Basic capabilities and capacities tests
19
20"""
21
22import logging
Rich Lane4f508052013-01-28 10:49:46 -080023import time
Dan Talayco79c6c4d2010-06-08 14:01:53 -070024import unittest
25
Rich Lane477f4812012-10-04 22:49:00 -070026from oftest import config
Dan Talayco79c6c4d2010-06-08 14:01:53 -070027import oftest.controller as controller
Rich Laned7b0ffa2013-03-08 15:53:42 -080028import ofp
Dan Talayco79c6c4d2010-06-08 14:01:53 -070029import oftest.dataplane as dataplane
Dan Talayco79c6c4d2010-06-08 14:01:53 -070030import oftest.parse as parse
Rich Laneb90a1c42012-10-05 09:16:05 -070031import oftest.base_tests as base_tests
Dan Talayco79c6c4d2010-06-08 14:01:53 -070032
Rich Laneda3b5ad2012-10-03 09:05:32 -070033from oftest.testutils import *
Dan Talayco79c6c4d2010-06-08 14:01:53 -070034
Dan Talayco79c6c4d2010-06-08 14:01:53 -070035def flow_caps_common(obj, is_exact=True):
36 """
37 The common function for
38
39 @param obj The calling object
40 @param is_exact If True, checking exact match; else wildcard
41 """
42
Rich Lane477f4812012-10-04 22:49:00 -070043 of_ports = config["port_map"].keys()
Dan Talayco79c6c4d2010-06-08 14:01:53 -070044 of_ports.sort()
45
Rich Lane32bf9482013-01-03 17:26:30 -080046 delete_all_flows(obj.controller)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070047
48 pkt = simple_tcp_packet()
Ed Swierk6192e512012-08-22 11:41:40 -070049 match = packet_to_flow_match(obj, pkt)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070050 obj.assertTrue(match is not None, "Could not generate flow match from pkt")
51 for port in of_ports:
52 break;
53 match.in_port = port
Rich Laned0478ff2013-03-11 12:46:58 -070054 match.ipv4_src = 1
Rich Laneba3f0e22013-03-11 16:43:57 -070055 request = ofp.message.flow_add()
Dan Talayco79c6c4d2010-06-08 14:01:53 -070056 count_check = 101 # fixme: better way to determine this.
57 if is_exact:
58 match.wildcards = 0
59 else:
60 match.wildcards |= ofp.OFPFW_DL_SRC
61
62 request.match = match
Rob Sherwood9130bcd2012-03-07 12:23:50 -080063 request.buffer_id = 0xffffffff # set to NONE
Rich Lane9a003812012-10-04 17:17:59 -070064 logging.info(request.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -070065
Rich Lane28fa9272013-03-08 16:00:25 -080066 tstats = ofp.message.table_stats_request()
Dan Talayco79c6c4d2010-06-08 14:01:53 -070067 try: # Determine the table index to check (or "all")
Rich Lane477f4812012-10-04 22:49:00 -070068 table_idx = config["caps_table_idx"]
Dan Talayco79c6c4d2010-06-08 14:01:53 -070069 except:
70 table_idx = -1 # Accumulate all table counts
71
72 # Make sure we can install at least one flow
Rich Lane9a003812012-10-04 17:17:59 -070073 logging.info("Inserting initial flow")
Rich Lane5c3151c2013-01-03 17:15:41 -080074 obj.controller.message_send(request)
Rich Lane3a261d52013-01-03 17:45:08 -080075 do_barrier(obj.controller, timeout=10)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070076 flow_count = 1
77
Rich Lane9a003812012-10-04 17:17:59 -070078 logging.info("Table idx: " + str(table_idx))
79 logging.info("Check every " + str(count_check) + " inserts")
Dan Talayco79c6c4d2010-06-08 14:01:53 -070080
81 while True:
Rich Laned0478ff2013-03-11 12:46:58 -070082 request.match.ipv4_src += 1
Rich Lane5c3151c2013-01-03 17:15:41 -080083 obj.controller.message_send(request)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070084 flow_count += 1
85 if flow_count % count_check == 0:
Rich Lane3a261d52013-01-03 17:45:08 -080086 do_barrier(obj.controller, timeout=10)
Rich Lanec8aaa3e2012-07-26 19:28:02 -070087 response, pkt = obj.controller.transact(tstats)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070088 obj.assertTrue(response is not None, "Get tab stats failed")
Rich Lane9a003812012-10-04 17:17:59 -070089 logging.info(response.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -070090 if table_idx == -1: # Accumulate for all tables
91 active_flows = 0
Rich Lane5fd6faf2013-03-11 13:30:20 -070092 for stats in response.entries:
Dan Talayco79c6c4d2010-06-08 14:01:53 -070093 active_flows += stats.active_count
94 else: # Table index to use specified in config
Rich Lane5fd6faf2013-03-11 13:30:20 -070095 active_flows = response.entries[table_idx].active_count
Dan Talayco79c6c4d2010-06-08 14:01:53 -070096 if active_flows != flow_count:
97 break
98
Rich Lane9a003812012-10-04 17:17:59 -070099 logging.error("RESULT: " + str(flow_count) + " flows inserted")
100 logging.error("RESULT: " + str(active_flows) + " flows reported")
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700101
Shudong Zhoud71c4a72012-11-18 14:37:43 -0800102 # clean up and wait a bit in case the table is really big
Rich Lane32bf9482013-01-03 17:26:30 -0800103 delete_all_flows(obj.controller)
Shudong Zhoud71c4a72012-11-18 14:37:43 -0800104 time.sleep(flow_count / 100)
105
106
Rich Lane0a4f6372013-01-02 14:40:22 -0800107@disabled
Rich Laneb90a1c42012-10-05 09:16:05 -0700108class FillTableExact(base_tests.SimpleProtocol):
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700109 """
Dan Talayco8f91a5b2010-07-20 14:07:21 -0700110 Fill the flow table with exact matches; can take a while
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700111
112 Fill table until no more flows can be added. Report result.
113 Increment the source IP address. Assume the flow table will
114 fill in less than 4 billion inserts
115
116 To check the number of flows in the tables is expensive, so
117 it's only done periodically. This is controlled by the
118 count_check variable.
119
120 A switch may have multiple tables. The default behaviour
121 is to count all the flows in all the tables. By setting
122 the parameter "caps_table_idx" in the configuration array,
123 you can control which table to check.
124 """
Rich Laned1d9c282012-10-04 22:07:10 -0700125
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700126 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700127 logging.info("Running " + str(self))
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700128 flow_caps_common(self)
129
Rich Lane0a4f6372013-01-02 14:40:22 -0800130@disabled
Rich Laneb90a1c42012-10-05 09:16:05 -0700131class FillTableWC(base_tests.SimpleProtocol):
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700132 """
133 Fill the flow table with wildcard matches
134
135 Fill table using wildcard entries until no more flows can be
136 added. Report result.
137 Increment the source IP address. Assume the flow table will
138 fill in less than 4 billion inserts
139
140 To check the number of flows in the tables is expensive, so
141 it's only done periodically. This is controlled by the
142 count_check variable.
143
144 A switch may have multiple tables. The default behaviour
145 is to count all the flows in all the tables. By setting
146 the parameter "caps_table_idx" in the configuration array,
147 you can control which table to check.
148
149 """
Rich Laned1d9c282012-10-04 22:07:10 -0700150
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700151 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700152 logging.info("Running " + str(self))
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700153 flow_caps_common(self, is_exact=False)