Merge pull request #7 from eswierk/master
Fixes to DirectPacketQueue test
diff --git a/tests/flow_query.py b/tests/flow_query.py
index 69402f4..54c264f 100644
--- a/tests/flow_query.py
+++ b/tests/flow_query.py
@@ -37,6 +37,12 @@
# Override list of OF port numbers reported by switch
# Default: none
#
+# Name: queues
+# Type: list of OF (port-number, queue-id) pairs
+# Description:
+# Override list of OF (port-number, queue-id) pairs returned by switch
+# Default: none
+#
# Name: conservative_ordered_actions
# Type: boolean (True or False)
# Description:
@@ -257,7 +263,6 @@
2097152 : 'OFPFW_NW_TOS'
}
-
def wildcard_set(x, w, val):
result = x
if w == ofp.OFPFW_NW_SRC_MASK:
@@ -279,6 +284,25 @@
return (x & ofp.OFPFW_NW_DST_MASK) >> ofp.OFPFW_NW_DST_SHIFT
return 1 if (x & w) != 0 else 0
+def wildcards_to_str(wildcards):
+ result = "{"
+ sep = ""
+ for w in all_wildcards_list:
+ if (wildcards & w) == 0:
+ continue
+ if w == ofp.OFPFW_NW_SRC_MASK:
+ n = wildcard_get(wildcards, w)
+ if n > 0:
+ result = result + sep + ("OFPFW_NW_SRC(%d)" % (n))
+ elif w == ofp.OFPFW_NW_DST_MASK:
+ n = wildcard_get(wildcards, w)
+ if n > 0:
+ result = result + sep + ("OFPFW_NW_DST(%d)" % (n))
+ else:
+ result = result + sep + all_wildcard_names[w]
+ sep = ", "
+ result = result +"}"
+ return result
all_actions_list = [ofp.OFPAT_OUTPUT,
ofp.OFPAT_SET_VLAN_VID,
@@ -294,6 +318,16 @@
ofp.OFPAT_ENQUEUE
]
+def actions_bmap_to_str(bm):
+ result = "{"
+ sep = ""
+ for a in all_actions_list:
+ if ((1 << a) & bm) != 0:
+ result = result + sep + ofp.ofp_action_type_map[a]
+ sep = ", "
+ result = result + "}"
+ return result
+
def dl_addr_to_str(a):
return "%x:%x:%x:%x:%x:%x" % tuple(a)
@@ -407,23 +441,11 @@
result = "priority=%d" % self.priority
# TBD - Would be nice if ofp_match.show() was better behaved
# (no newlines), and more intuitive (things in hex where approprate), etc.
- result = result + (", wildcards=0x%x={" % (self.match.wildcards))
- sep = ""
- for w in all_wildcards_list:
- if (self.match.wildcards & w) == 0:
- continue
- if w == ofp.OFPFW_NW_SRC_MASK:
- n = wildcard_get(self.match.wildcards, w)
- if n > 0:
- result = result + sep + ("OFPFW_NW_SRC(%d)" % (n))
- elif w == ofp.OFPFW_NW_DST_MASK:
- n = wildcard_get(self.match.wildcards, w)
- if n > 0:
- result = result + sep + ("OFPFW_NW_DST(%d)" % (n))
- else:
- result = result + sep + all_wildcard_names[w]
- sep = ", "
- result = result +"}"
+ result = result + (", wildcards=0x%x=%s" \
+ % (self.match.wildcards, \
+ wildcards_to_str(self.match.wildcards) \
+ )
+ )
if wildcard_get(self.match.wildcards, ofp.OFPFW_IN_PORT) == 0:
result = result + (", in_port=%d" % (self.match.in_port))
if wildcard_get(self.match.wildcards, ofp.OFPFW_DL_DST) == 0:
@@ -488,11 +510,14 @@
result = result + ("(port=%d,queue=%d)" % (a.port, a.queue_id))
return result
- def rand_actions_ordered(self, fi, valid_actions, valid_ports):
+ def rand_actions_ordered(self, fi, valid_actions, valid_ports, valid_queues):
# Action lists are ordered, so pick an ordered random subset of
# supported actions
actions_force = test_param_get(fq_config, "actions_force", 0)
+ if actions_force != 0:
+ fq_logger.info("Forced actions:")
+ fq_logger.info(actions_bmap_to_str(actions_force))
ACTION_MAX_LEN = 65535 # @fixme Should be test param?
supported_actions = []
@@ -551,19 +576,19 @@
p = random.randint(1, 100)
if (((1 << ofp.OFPAT_ENQUEUE) & actions_force) != 0 or p <= 33) \
- and ofp.OFPAT_ENQUEUE in actions:
+ and len(valid_queues) > 0 \
+ and ofp.OFPAT_ENQUEUE in actions:
# In not forecd, one third of the time, include ENQUEUE actions
# at end of list
# At most 1 ENQUEUE action
act = action.action_enqueue()
- act.port = rand_pick(valid_ports)
- # TBD - Limits for queue number?
- act.queue_id = random.randint(0, 7)
+ (act.port, act.queue_id) = rand_pick(valid_queues)
act.max_len = ACTION_MAX_LEN
self.actions.add(act)
if (((1 << ofp.OFPAT_OUTPUT) & actions_force) != 0 \
or (p > 33 and p <= 66) \
) \
+ and len(valid_ports) > 0 \
and ofp.OFPAT_OUTPUT in actions:
# One third of the time, include OUTPUT actions at end of list
port_idxs = shuffle(range(len(valid_ports)))
@@ -585,16 +610,19 @@
# Randomize flow data for flow modifies (i.e. cookie and actions)
- def rand_mod(self, fi, valid_actions, valid_ports):
+ def rand_mod(self, fi, valid_actions, valid_ports, valid_queues):
self.cookie = random.randint(0, (1 << 53) - 1)
# By default, test with conservative ordering conventions
# This should probably be indicated in a profile
if test_param_get(fq_config, "conservative_ordered_actions", True):
- self.rand_actions_ordered(fi, valid_actions, valid_ports)
+ self.rand_actions_ordered(fi, valid_actions, valid_ports, valid_queues)
return self
actions_force = test_param_get(fq_config, "actions_force", 0)
+ if actions_force != 0:
+ fq_logger.info("Forced actions:")
+ fq_logger.info(actions_bmap_to_str(actions_force))
ACTION_MAX_LEN = 65535 # @fixme Should be test param?
supported_actions = []
@@ -615,6 +643,8 @@
for a in actions:
if a == ofp.OFPAT_OUTPUT:
# TBD - Output actions are clustered in list, spread them out?
+ if len(valid_ports) == 0:
+ continue
port_idxs = shuffle(range(len(valid_ports)))
port_idxs = port_idxs[0 : random.randint(1, len(valid_ports))]
for pi in port_idxs:
@@ -661,20 +691,23 @@
self.actions.add(act)
elif a == ofp.OFPAT_ENQUEUE:
# TBD - Enqueue actions are clustered in list, spread them out?
- port_idxs = shuffle(range(len(valid_ports)))
- port_idxs = port_idxs[0 : random.randint(1, len(valid_ports))]
- for pi in port_idxs:
+ if len(valid_queues) == 0:
+ continue
+ qidxs = shuffle(range(len(valid_queues)))
+ qidxs = qidxs[0 : random.randint(1, len(valid_queues))]
+ for qi in qidxs:
act = action.action_enqueue()
- act.port = valid_ports[pi]
- # TBD - Limits for queue number?
- act.queue_id = random.randint(0, 7)
+ (act.port, act.queue_id) = valid_queues[qi]
self.actions.add(act)
return self
# Randomize flow cfg
- def rand(self, fi, valid_wildcards, valid_actions, valid_ports):
+ def rand(self, fi, valid_wildcards, valid_actions, valid_ports, valid_queues):
wildcards_force = test_param_get(fq_config, "wildcards_force", 0)
+ if wildcards_force != 0:
+ fq_logger.info("Wildcards forced:")
+ fq_logger.info(wildcards_to_str(wildcards_force))
# Start with no wildcards, i.e. everything specified
self.match.wildcards = 0
@@ -921,7 +954,7 @@
t = random.randint(0, 65535)
self.hard_timeout = 0 if t < 60 else t
- self.rand_mod(fi, valid_actions, valid_ports)
+ self.rand_mod(fi, valid_actions, valid_ports, valid_queues)
return self
@@ -1143,7 +1176,8 @@
fc.rand(fi, \
sw.tbl_stats.stats[tbl].wildcards, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
fc = fc.canonical()
if self.find(fc):
@@ -1180,20 +1214,23 @@
class Switch:
# Members:
- # controller - switch's test controller
- # sw_features - switch's OFPT_FEATURES_REPLY message
- # valid_ports - list of valid port numbers
- # tbl_stats - switch's OFPT_STATS_REPLY message, for table stats request
- # flow_stats - switch's OFPT_STATS_REPLY message, for flow stats request
- # flow_tbl - (test's idea of) switch's flow table
+ # controller - switch's test controller
+ # sw_features - switch's OFPT_FEATURES_REPLY message
+ # valid_ports - list of valid port numbers
+ # valid_queues - list of valid [port, queue] pairs
+ # tbl_stats - switch's OFPT_STATS_REPLY message, for table stats request
+ # queue_stats - switch's OFPT_STATS_REPLY message, for queue stats request
+ # flow_stats - switch's OFPT_STATS_REPLY message, for flow stats request
+ # flow_tbl - (test's idea of) switch's flow table
def __init__(self):
- self.controller = None
- self.sw_features = None
- self.valid_ports = []
- self.tbl_stats = None
- self.flow_stats = None
- self.flow_tbl = Flow_Tbl()
+ self.controller = None
+ self.sw_features = None
+ self.valid_ports = []
+ self.valid_queues = []
+ self.tbl_stats = None
+ self.flow_stats = None
+ self.flow_tbl = Flow_Tbl()
def controller_set(self, controller):
self.controller = controller
@@ -1208,8 +1245,17 @@
request = message.features_request()
(self.sw_features, pkt) = self.controller.transact(request, timeout=2)
if self.sw_features is None:
+ fq_logger.error("Get switch features failed")
return False
self.valid_ports = map(lambda x: x.port_no, self.sw_features.ports)
+ fq_logger.info("Ports reported by switch:")
+ fq_logger.info(self.valid_ports)
+ ports_override = test_param_get(fq_config, "ports", [])
+ if ports_override != []:
+ fq_logger.info("Overriding ports to:")
+ fq_logger.info(ports_override)
+ self.valid_ports = ports_override
+
# TBD - OFPP_LOCAL is returned by OVS is switch features --
# is that universal?
@@ -1223,13 +1269,17 @@
# ofp.OFPP_CONTROLLER \
# ] \
# )
+ fq_logger.info("Supported actions reported by switch:")
+ fq_logger.info("0x%x=%s" \
+ % (self.sw_features.actions, \
+ actions_bmap_to_str(self.sw_features.actions) \
+ ) \
+ )
actions_override = test_param_get(fq_config, "actions", -1)
if actions_override != -1:
+ fq_logger.info("Overriding supported actions to:")
+ fq_logger.info(actions_bmap_to_str(actions_override))
self.sw_features.actions = actions_override
- ports_override = test_param_get(fq_config, "ports", [])
- if ports_override != []:
- self.valid_ports = ports_override
-
return True
def tbl_stats_get(self):
@@ -1237,13 +1287,57 @@
request = message.table_stats_request()
(self.tbl_stats, pkt) = self.controller.transact(request, timeout=2)
if self.tbl_stats is None:
+ fq_logger.error("Get table stats failed")
return False
+ i = 0
for ts in self.tbl_stats.stats:
+ fq_logger.info("Supported wildcards for table %d reported by switch:"
+ % (i)
+ )
+ fq_logger.info("0x%x=%s" \
+ % (ts.wildcards, \
+ wildcards_to_str(ts.wildcards) \
+ ) \
+ )
wildcards_override = test_param_get(fq_config, "wildcards", -1)
if wildcards_override != -1:
+ fq_logger.info("Overriding supported wildcards for table %d to:"
+ % (i)
+ )
+ fq_logger.info(wildcards_to_str(wildcards_override))
ts.wildcards = wildcards_override
+ i = i + 1
return True
+ def queue_stats_get(self):
+ # Get queue stats
+ request = message.queue_stats_request()
+ request.port_no = ofp.OFPP_ALL
+ request.queue_id = ofp.OFPQ_ALL
+ (self.queue_stats, pkt) = self.controller.transact(request, timeout=2)
+ if self.queue_stats is None:
+ fq_logger.error("Get queue stats failed")
+ return False
+ self.valid_queues = map(lambda x: (x.port_no, x.queue_id), \
+ self.queue_stats.stats \
+ )
+ fq_logger.info("(Port, queue) pairs reported by switch:")
+ fq_logger.info(self.valid_queues)
+ queues_override = test_param_get(fq_config, "queues", [])
+ if queues_override != []:
+ fq_logger.info("Overriding (port, queue) pairs to:")
+ fq_logger.info(queues_override)
+ self.valid_queues = queues_override
+ return True
+
+ def connect(self, controller):
+ # Connect to controller, and get all switch capabilities
+ self.controller_set(controller)
+ return (self.features_get() \
+ and self.tbl_stats_get() \
+ and self.queue_stats_get() \
+ )
+
def flow_stats_get(self, limit = 10000):
request = message.flow_stats_request()
query_match = ofp.ofp_match()
@@ -1505,11 +1599,10 @@
# Get switch capabilites
- fq_logger.info("Getting switch capabilities")
sw = Switch()
- sw.controller_set(self.controller)
- self.assertTrue(sw.features_get(), "Get switch features failed")
- self.assertTrue(sw.tbl_stats_get(), "Get table stats failed")
+ self.assertTrue(sw.connect(self.controller), \
+ "Failed to connect to switch" \
+ )
if num_flows == 0:
# Number of flows requested was 0
@@ -1606,11 +1699,10 @@
# Get switch capabilites
- fq_logger.info("Getting switch capabilities")
sw = Switch()
- sw.controller_set(self.controller)
- self.assertTrue(sw.features_get(), "Get switch features failed")
- self.assertTrue(sw.tbl_stats_get(), "Get table stats failed")
+ self.assertTrue(sw.connect(self.controller), \
+ "Failed to connect to switch" \
+ )
# Dream up some flow information, i.e. space to chose from for
# random flow parameter generation
@@ -1625,7 +1717,8 @@
fc.rand(fi, \
sw.tbl_stats.stats[0].wildcards, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
fcc = fc.canonical()
if fcc.match != fc.match:
@@ -1718,11 +1811,10 @@
# Get switch capabilites
- fq_logger.info("Getting switch capabilities")
sw = Switch()
- sw.controller_set(self.controller)
- self.assertTrue(sw.features_get(), "Get switch features failed")
- self.assertTrue(sw.tbl_stats_get(), "Get table stats failed")
+ self.assertTrue(sw.connect(self.controller), \
+ "Failed to connect to switch" \
+ )
num_flows = 0
for ts in sw.tbl_stats.stats:
@@ -1769,7 +1861,8 @@
fc.rand(fi, \
sw.tbl_stats.stats[0].wildcards, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
fc = fc.canonical()
if not ft.find(fc):
@@ -1845,11 +1938,10 @@
# Get switch capabilites
- fq_logger.info("Getting switch capabilities")
sw = Switch()
- sw.controller_set(self.controller)
- self.assertTrue(sw.features_get(), "Get switch features failed")
- self.assertTrue(sw.tbl_stats_get(), "Get table stats failed")
+ self.assertTrue(sw.connect(self.controller), \
+ "Failed to connect to switch" \
+ )
# Dream up some flow information, i.e. space to chose from for
# random flow parameter generation
@@ -1863,7 +1955,8 @@
fc.rand(fi, \
sw.tbl_stats.stats[0].wildcards, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
fc = fc.canonical()
@@ -1882,7 +1975,8 @@
while True:
fc2.rand_mod(fi, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
if fc2 != fc:
break
@@ -1963,11 +2057,10 @@
# Get switch capabilites
- fq_logger.info("Getting switch capabilities")
sw = Switch()
- sw.controller_set(self.controller)
- self.assertTrue(sw.features_get(), "Get switch features failed")
- self.assertTrue(sw.tbl_stats_get(), "Get table stats failed")
+ self.assertTrue(sw.connect(self.controller), \
+ "Failed to connect to switch" \
+ )
# Dream up some flow information, i.e. space to chose from for
# random flow parameter generation
@@ -1982,7 +2075,8 @@
fc.rand(fi, \
sw.tbl_stats.stats[0].wildcards, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
fc = fc.canonical()
if fc.match.wildcards != ofp.OFPFW_ALL:
@@ -2087,11 +2181,10 @@
# Get switch capabilites
- fq_logger.info("Getting switch capabilities")
sw = Switch()
- sw.controller_set(self.controller)
- self.assertTrue(sw.features_get(), "Get switch features failed")
- self.assertTrue(sw.tbl_stats_get(), "Get table stats failed")
+ self.assertTrue(sw.connect(self.controller), \
+ "Failed to connect to switch" \
+ )
# Dream up some flow information, i.e. space to chose from for
# random flow parameter generation
@@ -2105,7 +2198,8 @@
fc.rand(fi, \
sw.tbl_stats.stats[0].wildcards, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
fc = fc.canonical()
@@ -2124,7 +2218,8 @@
while True:
fc2.rand_mod(fi, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
if fc2 != fc:
break
@@ -2210,11 +2305,10 @@
# Get switch capabilites
- fq_logger.info("Getting switch capabilities")
sw = Switch()
- sw.controller_set(self.controller)
- self.assertTrue(sw.features_get(), "Get switch features failed")
- self.assertTrue(sw.tbl_stats_get(), "Get table stats failed")
+ self.assertTrue(sw.connect(self.controller), \
+ "Failed to connect to switch" \
+ )
# Dream up some flow information, i.e. space to chose from for
# random flow parameter generation
@@ -2256,7 +2350,11 @@
# Pick a random flow as a basis
mfc = copy.deepcopy((ft.values())[0])
- mfc.rand_mod(fi, sw.sw_features.actions, sw.valid_ports)
+ mfc.rand_mod(fi, \
+ sw.sw_features.actions, \
+ sw.valid_ports, \
+ sw.valid_queues \
+ )
# Repeatedly wildcard qualifiers
@@ -2354,11 +2452,10 @@
# Get switch capabilites
- fq_logger.info("Getting switch capabilities")
sw = Switch()
- sw.controller_set(self.controller)
- self.assertTrue(sw.features_get(), "Get switch features failed")
- self.assertTrue(sw.tbl_stats_get(), "Get table stats failed")
+ self.assertTrue(sw.connect(self.controller), \
+ "Failed to connect to switch" \
+ )
# Dream up some flow information, i.e. space to chose from for
# random flow parameter generation
@@ -2372,7 +2469,8 @@
fc.rand(fi, \
sw.tbl_stats.stats[0].wildcards, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
fc = fc.canonical()
@@ -2406,6 +2504,116 @@
fq_logger.info("Flow_Mod_3 TEST PASSED")
+# FLOW MODIFY 3_1
+
+# OVERVIEW
+# No-op modify
+#
+# PURPOSE
+# Verify that modify of a flow with new actions same as old ones operates correctly
+#
+# PARAMETERS
+# None
+#
+# PROCESS
+# 1. Delete all flows from switch
+# 2. Send single flow mod, as strict modify, to switch
+# 3. Verify flow table in switch
+# 4. Send same flow mod, as strict modify, to switch
+# 5. Verify flow table in switch
+# 6. Test PASSED iff flow defined in step 2 and 4 above verified; else FAILED
+
+class Flow_Mod_3_1(basic.SimpleProtocol):
+ """
+ Test FLOW_MOD_3_1 from draft top-half test plan
+
+ INPUTS
+ None
+ """
+
+ def runTest(self):
+ fq_logger.info("Flow_Mod_3_1 TEST BEGIN")
+
+ # Clear all flows from switch
+
+ fq_logger.info("Deleting all flows from switch")
+ rc = delete_all_flows(self.controller, fq_logger)
+ self.assertEqual(rc, 0, "Failed to delete all flows")
+
+ # Get switch capabilites
+
+ sw = Switch()
+ self.assertTrue(sw.connect(self.controller), \
+ "Failed to connect to switch" \
+ )
+
+ # Dream up some flow information, i.e. space to chose from for
+ # random flow parameter generation
+
+ fi = Flow_Info()
+ fi.rand(10)
+
+ # Dream up a flow config
+
+ fc = Flow_Cfg()
+ fc.rand(fi, \
+ sw.tbl_stats.stats[0].wildcards, \
+ sw.sw_features.actions, \
+ sw.valid_ports, \
+ sw.valid_queues \
+ )
+ fc = fc.canonical()
+
+ # Send it to the switch
+
+ fq_logger.info("Sending flow mod to switch:")
+ fq_logger.info(str(fc))
+ ft = Flow_Tbl()
+ fc.send_rem = False
+ self.assertTrue(sw.flow_mod(fc, True), "Failed to modify flows")
+ ft.insert(fc)
+
+ # Do barrier, to make sure all flows are in
+
+ self.assertTrue(sw.barrier(), "Barrier failed")
+
+ result = True
+
+ # Check for any error messages
+
+ if not sw.errors_verify(0):
+ result = False
+
+ # Verify flow table
+
+ sw.flow_tbl = ft
+ if not sw.flow_tbl_verify():
+ result = False
+
+ # Send same flow to the switch again
+
+ fq_logger.info("Sending flow mod to switch:")
+ fq_logger.info(str(fc))
+ self.assertTrue(sw.flow_mod(fc, True), "Failed to modify flows")
+
+ # Do barrier, to make sure all flows are in
+
+ self.assertTrue(sw.barrier(), "Barrier failed")
+
+ # Check for any error messages
+
+ if not sw.errors_verify(0):
+ result = False
+
+ # Verify flow table
+
+ if not sw.flow_tbl_verify():
+ result = False
+
+ self.assertTrue(result, "Flow_Mod_3_1 TEST FAILED")
+ fq_logger.info("Flow_Mod_3_1 TEST PASSED")
+
+
# FLOW DELETE 1
#
# OVERVIEW
@@ -2445,11 +2653,10 @@
# Get switch capabilites
- fq_logger.info("Getting switch capabilities")
sw = Switch()
- sw.controller_set(self.controller)
- self.assertTrue(sw.features_get(), "Get switch features failed")
- self.assertTrue(sw.tbl_stats_get(), "Get table stats failed")
+ self.assertTrue(sw.connect(self.controller), \
+ "Failed to connect to switch" \
+ )
# Dream up some flow information, i.e. space to chose from for
# random flow parameter generation
@@ -2463,7 +2670,8 @@
fc.rand(fi, \
sw.tbl_stats.stats[0].wildcards, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
fc = fc.canonical()
@@ -2482,7 +2690,8 @@
while True:
fc2.rand_mod(fi, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
if fc2 != fc:
break
@@ -2565,11 +2774,10 @@
# Get switch capabilites
- fq_logger.info("Getting switch capabilities")
sw = Switch()
- sw.controller_set(self.controller)
- self.assertTrue(sw.features_get(), "Get switch features failed")
- self.assertTrue(sw.tbl_stats_get(), "Get table stats failed")
+ self.assertTrue(sw.connect(self.controller), \
+ "Failed to connect to switch" \
+ )
# Dream up some flow information, i.e. space to chose from for
# random flow parameter generation
@@ -2611,7 +2819,11 @@
# Pick a random flow as a basis
dfc = copy.deepcopy(ft.values()[0])
- dfc.rand_mod(fi, sw.sw_features.actions, sw.valid_ports)
+ dfc.rand_mod(fi, \
+ sw.sw_features.actions, \
+ sw.valid_ports, \
+ sw.valid_queues \
+ )
# Repeatedly wildcard qualifiers
@@ -2715,11 +2927,10 @@
# Get switch capabilites
- fq_logger.info("Getting switch capabilities")
sw = Switch()
- sw.controller_set(self.controller)
- self.assertTrue(sw.features_get(), "Get switch features failed")
- self.assertTrue(sw.tbl_stats_get(), "Get table stats failed")
+ self.assertTrue(sw.connect(self.controller), \
+ "Failed to connect to switch" \
+ )
# Dream up some flow information, i.e. space to chose from for
# random flow parameter generation
@@ -2733,7 +2944,8 @@
fc.rand(fi, \
sw.tbl_stats.stats[0].wildcards, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
fc = fc.canonical()
@@ -2752,7 +2964,8 @@
while True:
fc2.rand_mod(fi, \
sw.sw_features.actions, \
- sw.valid_ports \
+ sw.valid_ports, \
+ sw.valid_queues \
)
if fc2 != fc:
break
diff --git a/tests/pktact.py b/tests/pktact.py
index eaba624..dc767f0 100644
--- a/tests/pktact.py
+++ b/tests/pktact.py
@@ -1119,6 +1119,52 @@
flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
action_list=[vid_act])
+class ModifyVIDWithTagMatchWildcarded(BaseMatchCase):
+ """
+ With vlan ID and priority wildcarded, perform SET_VLAN_VID action.
+ The same flow should match on both untagged and tagged packets.
+ """
+ def runTest(self):
+ old_vid = 2
+ new_vid = 3
+ sup_acts = supported_actions_get(self)
+ if not (sup_acts & 1 << ofp.OFPAT_SET_VLAN_VID):
+ skip_message_emit(self, "ModifyVIDWithTagWildcarded test")
+ return
+
+ of_ports = pa_port_map.keys()
+ self.assertTrue(len(of_ports) > 1, "Not enough ports for test")
+ ing_port = of_ports[0]
+ egr_ports = of_ports[1]
+
+ rv = delete_all_flows(self.controller, pa_logger)
+ self.assertEqual(rv, 0, "Failed to delete all flows")
+
+ len_untagged = 100
+ len_w_vid = 104
+ untagged_pkt = simple_tcp_packet(pktlen=len_untagged)
+ tagged_pkt = simple_tcp_packet(pktlen=len_w_vid,
+ dl_vlan_enable=True, dl_vlan=old_vid)
+ exp_pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
+ dl_vlan=new_vid)
+ wildcards=ofp.OFPFW_DL_VLAN|ofp.OFPFW_DL_VLAN_PCP
+ vid_act = action.action_set_vlan_vid()
+ vid_act.vlan_vid = new_vid
+ request = flow_msg_create(self, untagged_pkt, ing_port=ing_port,
+ wildcards=wildcards, egr_ports=egr_ports,
+ action_list=[vid_act])
+ flow_msg_install(self, request)
+
+ pa_logger.debug("Send untagged packet: " + str(ing_port) + " to " +
+ str(egr_ports))
+ self.dataplane.send(ing_port, str(untagged_pkt))
+ receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
+
+ pa_logger.debug("Send tagged packet: " + str(ing_port) + " to " +
+ str(egr_ports))
+ self.dataplane.send(ing_port, str(tagged_pkt))
+ receive_pkt_verify(self, egr_ports, exp_pkt, ing_port)
+
class ModifyVlanPcp(BaseMatchCase):
"""
Modify the priority field of the VLAN tag of a tagged packet
@@ -1161,6 +1207,30 @@
flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt,
action_list=[vid_act])
+class StripVLANTagWithTagMatchWildcarded(BaseMatchCase):
+ """
+ Strip the VLAN tag from a tagged packet.
+ Differs from StripVLANTag in that VID and PCP are both wildcarded.
+ """
+ def runTest(self):
+ old_vid = 2
+ sup_acts = supported_actions_get(self)
+ if not (sup_acts & 1 << ofp.OFPAT_STRIP_VLAN):
+ skip_message_emit(self, "StripVLANTagWithTagWildcarded test")
+ return
+
+ len_w_vid = 104
+ len_untagged = 100
+ pkt = simple_tcp_packet(pktlen=len_w_vid, dl_vlan_enable=True,
+ dl_vlan=old_vid)
+ exp_pkt = simple_tcp_packet(pktlen=len_untagged)
+ vid_act = action.action_strip_vlan()
+
+ flow_match_test(self, pa_port_map,
+ wildcards=ofp.OFPFW_DL_VLAN|ofp.OFPFW_DL_VLAN_PCP,
+ pkt=pkt, exp_pkt=exp_pkt,
+ action_list=[vid_act])
+
def init_pkt_args():
"""
Pass back a dictionary with default packet arguments