loxi-prep: use plain lists to hold OF actions
Some callsites needed to be changed because they depended on action_list.append
taking a shallow copy.
diff --git a/src/python/of10/message.py b/src/python/of10/message.py
index 4f5a43f..849c15a 100644
--- a/src/python/of10/message.py
+++ b/src/python/of10/message.py
@@ -904,8 +904,6 @@
setattr(self, k, v)
else:
raise NameError("field %s does not exist in %s" % (k, self.__class__))
- # Coerce keyword arg into list type
- self.actions = action_list(self.actions)
def pack(self):
@@ -919,7 +917,7 @@
packed = self.header.pack()
packed += ofp_flow_mod.pack(self)
- packed += self.actions.pack()
+ packed += action_list(self.actions).pack()
return packed
def unpack(self, binary_string):
@@ -935,7 +933,9 @@
binary_string = ofp_flow_mod.unpack(self, binary_string)
ai_len = self.header.length - (OFP_FLOW_MOD_BYTES + OFP_HEADER_BYTES)
- binary_string = self.actions.unpack(binary_string, bytes=ai_len)
+ obj = action_list()
+ binary_string = obj.unpack(binary_string, bytes=ai_len)
+ self.actions = list(obj)
# Fixme: If no self.data, add check for data remaining
return binary_string
@@ -950,7 +950,8 @@
length = OFP_HEADER_BYTES
length += ofp_flow_mod.__len__(self)
- length += len(self.actions)
+ for obj in self.actions:
+ length += len(obj)
return length
def show(self, prefix=''):
@@ -1580,8 +1581,6 @@
setattr(self, k, v)
else:
raise NameError("field %s does not exist in %s" % (k, self.__class__))
- # Coerce keyword arg into list type
- self.actions = action_list(self.actions)
def pack(self):
@@ -1594,9 +1593,11 @@
self.header.length = len(self)
packed = self.header.pack()
- self.actions_len = len(self.actions)
+ self.actions_len = 0
+ for obj in self.actions:
+ self.actions_len += len(obj)
packed += ofp_packet_out.pack(self)
- packed += self.actions.pack()
+ packed += action_list(self.actions).pack()
packed += self.data
return packed
@@ -1612,7 +1613,9 @@
binary_string = self.header.unpack(binary_string)
binary_string = ofp_packet_out.unpack(self, binary_string)
- binary_string = self.actions.unpack(binary_string, bytes=self.actions_len)
+ obj = action_list()
+ binary_string = obj.unpack(binary_string, bytes=self.actions_len)
+ self.actions = list(obj)
self.data = binary_string
binary_string = ''
return binary_string
@@ -1628,7 +1631,8 @@
length = OFP_HEADER_BYTES
length += ofp_packet_out.__len__(self)
- length += len(self.actions)
+ for obj in self.actions:
+ length += len(obj)
length += len(self.data)
return length
@@ -2642,12 +2646,12 @@
"""
def __init__(self):
ofp_flow_stats.__init__(self)
- self.actions = action_list()
+ self.actions = []
def pack(self, assertstruct=True):
self.length = len(self)
packed = ofp_flow_stats.pack(self, assertstruct)
- packed += self.actions.pack()
+ packed += action_list(self.actions).pack()
if len(packed) != self.length:
print("ERROR: flow_stats_entry pack length not equal",
self.length, len(packed))
@@ -2659,7 +2663,9 @@
if ai_len < 0:
print("ERROR: flow_stats_entry unpack length too small",
self.length)
- binary_string = self.actions.unpack(binary_string, bytes=ai_len)
+ obj = action_list()
+ binary_string = obj.unpack(binary_string, bytes=ai_len)
+ self.actions = list(obj)
return binary_string
def __len__(self):
diff --git a/tests/flow_query.py b/tests/flow_query.py
index ee72fc3..2d5c7b5 100644
--- a/tests/flow_query.py
+++ b/tests/flow_query.py
@@ -69,7 +69,6 @@
import oftest.controller as controller
import ofp
import oftest.dataplane as dataplane
-import oftest.action_list as action_list
import oftest.parse as parse
import pktact
import oftest.base_tests as base_tests
@@ -333,7 +332,7 @@
# - idle_timeout
# - hard_timeout
# - priority
- # - action_list
+ # - actions
def __init__(self):
self.priority = 0
@@ -341,7 +340,7 @@
self.match.wildcards = ofp.OFPFW_ALL
self.idle_timeout = 0
self.hard_timeout = 0
- self.actions = action_list.action_list()
+ self.actions = []
# {pri, match} is considered a flow key
def key_equal(self, x):
@@ -396,8 +395,8 @@
if test_param_get("conservative_ordered_actions", True):
# Compare actions lists as unordered
- aa = copy.deepcopy(x.actions.actions)
- for a in self.actions.actions:
+ aa = copy.deepcopy(x.actions)
+ for a in self.actions:
i = 0
while i < len(aa):
if a == aa[i]:
@@ -473,7 +472,7 @@
result = result + (", cookie=%d" % self.cookie)
result = result + (", idle_timeout=%d" % self.idle_timeout)
result = result + (", hard_timeout=%d" % self.hard_timeout)
- for a in self.actions.actions:
+ for a in self.actions:
result = result + (", action=%s" % ofp.ofp_action_type_map[a.type])
if a.type == ofp.OFPAT_OUTPUT:
result = result + ("(%d)" % (a.port))
@@ -519,7 +518,7 @@
set_vlanf = False
strip_vlanf = False
- self.actions = action_list.action_list()
+ self.actions = []
for a in actions:
act = None
if a == ofp.OFPAT_OUTPUT:
@@ -627,7 +626,7 @@
actions = shuffle(actions)
- self.actions = action_list.action_list()
+ self.actions = []
for a in actions:
if a == ofp.OFPAT_OUTPUT:
# TBD - Output actions are clustered in list, spread them out?
diff --git a/tests/pktact.py b/tests/pktact.py
index 9e81af6..bd3e79f 100644
--- a/tests/pktact.py
+++ b/tests/pktact.py
@@ -501,7 +501,6 @@
match.wildcards &= ~ofp.OFPFW_IN_PORT
self.assertTrue(match is not None,
"Could not generate flow match from pkt")
- act = ofp.action.output()
for idx in range(len(of_ports)):
delete_all_flows(self.controller)
@@ -518,10 +517,8 @@
request = ofp.message.flow_mod()
request.match = match
request.buffer_id = 0xffffffff
- act.port = egress_port1
- request.actions.append(act)
- act.port = egress_port2
- request.actions.append(act)
+ request.actions.append(ofp.action.output(port=egress_port1))
+ request.actions.append(ofp.action.output(port=egress_port2))
# logging.info(request.show())
logging.info("Inserting flow")
@@ -559,7 +556,6 @@
match.wildcards &= ~ofp.OFPFW_IN_PORT
self.assertTrue(match is not None,
"Could not generate flow match from pkt")
- act = ofp.action.output()
for ingress_port in of_ports:
delete_all_flows(self.controller)
@@ -574,8 +570,7 @@
for egress_port in of_ports:
if egress_port == ingress_port:
continue
- act.port = egress_port
- request.actions.append(act)
+ request.actions.append(ofp.action.output(port=egress_port))
logging.debug(request.show())
logging.info("Inserting flow")
@@ -611,7 +606,6 @@
match.wildcards &= ~ofp.OFPFW_IN_PORT
self.assertTrue(match is not None,
"Could not generate flow match from pkt")
- act = ofp.action.output()
for ingress_port in of_ports:
delete_all_flows(self.controller)
@@ -623,6 +617,7 @@
request.match = match
request.buffer_id = 0xffffffff
for egress_port in of_ports:
+ act = ofp.action.output()
if egress_port == ingress_port:
act.port = ofp.OFPP_IN_PORT
else:
@@ -713,7 +708,6 @@
match.wildcards &= ~ofp.OFPFW_IN_PORT
self.assertTrue(match is not None,
"Could not generate flow match from pkt")
- act = ofp.action.output()
for ingress_port in of_ports:
delete_all_flows(self.controller)
@@ -724,10 +718,8 @@
request = ofp.message.flow_mod()
request.match = match
request.buffer_id = 0xffffffff
- act.port = ofp.OFPP_FLOOD
- request.actions.append(act)
- act.port = ofp.OFPP_IN_PORT
- request.actions.append(act)
+ request.actions.append(ofp.action.output(port=ofp.OFPP_FLOOD))
+ request.actions.append(ofp.action.output(port=ofp.OFPP_IN_PORT))
logging.info(request.show())
logging.info("Inserting flow")
@@ -804,7 +796,6 @@
match.wildcards &= ~ofp.OFPFW_IN_PORT
self.assertTrue(match is not None,
"Could not generate flow match from pkt")
- act = ofp.action.output()
for ingress_port in of_ports:
delete_all_flows(self.controller)
@@ -815,10 +806,8 @@
request = ofp.message.flow_mod()
request.match = match
request.buffer_id = 0xffffffff
- act.port = ofp.OFPP_ALL
- request.actions.append(act)
- act.port = ofp.OFPP_IN_PORT
- request.actions.append(act)
+ request.actions.append(ofp.action.output(port=ofp.OFPP_ALL))
+ request.actions.append(ofp.action.output(port=ofp.OFPP_IN_PORT))
logging.info(request.show())
logging.info("Inserting flow")
diff --git a/tools/munger/scripts/message_gen.py b/tools/munger/scripts/message_gen.py
index 6761935..5d771e3 100644
--- a/tools/munger/scripts/message_gen.py
+++ b/tools/munger/scripts/message_gen.py
@@ -310,9 +310,6 @@
_p4('setattr(self, k, v)')
_p3('else:')
_p4('raise NameError("field %s does not exist in %s" % (k, self.__class__))')
- if has_list and list_type != None:
- _p2('# Coerce keyword arg into list type')
- _p2('self.%(list_var)s = %(list_type)s(self.%(list_var)s)' % dict(list_type=list_type, list_var=list_var))
print """
@@ -329,7 +326,9 @@
# Have to special case the action length calculation for pkt out
if msg == 'packet_out':
- _p2('self.actions_len = len(self.actions)')
+ _p2('self.actions_len = 0')
+ _p2('for obj in self.actions:')
+ _p3('self.actions_len += len(obj)')
if has_core_members:
_p2("packed += " + parent + ".pack(self)")
if has_list:
@@ -337,7 +336,7 @@
_p2('for obj in self.' + list_var + ':')
_p3('packed += obj.pack()')
else:
- _p2('packed += self.' + list_var + '.pack()')
+ _p2('packed += ' + list_type + '(self.' + list_var + ').pack()')
if has_string:
_p2('packed += self.data')
_p2("return packed")
@@ -367,15 +366,21 @@
_p2("for obj in self." + list_var + ":")
_p3("binary_string = obj.unpack(binary_string)")
elif msg == "packet_out": # Special case this
- _p2('binary_string = self.actions.unpack(' +
+ _p2("obj = action_list()")
+ _p2('binary_string = obj.unpack(' +
'binary_string, bytes=self.actions_len)')
+ _p2("self.actions = list(obj)")
elif msg == "flow_mod": # Special case this
_p2("ai_len = self.header.length - (OFP_FLOW_MOD_BYTES + " +
"OFP_HEADER_BYTES)")
- _p2("binary_string = self.actions.unpack(binary_string, " +
+ _p2("obj = action_list()")
+ _p2("binary_string = obj.unpack(binary_string, " +
"bytes=ai_len)")
+ _p2("self.actions = list(obj)")
else:
- _p2("binary_string = self." + list_var + ".unpack(binary_string)")
+ _p2("obj = " + list_type + "()")
+ _p2("binary_string = obj.unpack(binary_string)")
+ _p2("self." + list_var + " = list(obj)")
if has_string:
_p2("self.data = binary_string")
_p2("binary_string = ''")
@@ -397,11 +402,8 @@
if has_core_members:
_p2("length += " + parent + ".__len__(self)")
if has_list:
- if list_type == None:
- _p2("for obj in self." + list_var + ":")
- _p3("length += len(obj)")
- else:
- _p2("length += len(self." + list_var + ")")
+ _p2("for obj in self." + list_var + ":")
+ _p3("length += len(obj)")
if has_string:
_p2("length += len(self.data)")
_p2("return length")
@@ -680,12 +682,12 @@
\"""
def __init__(self):
ofp_flow_stats.__init__(self)
- self.actions = action_list()
+ self.actions = []
def pack(self, assertstruct=True):
self.length = len(self)
packed = ofp_flow_stats.pack(self, assertstruct)
- packed += self.actions.pack()
+ packed += action_list(self.actions).pack()
if len(packed) != self.length:
print("ERROR: flow_stats_entry pack length not equal",
self.length, len(packed))
@@ -697,7 +699,9 @@
if ai_len < 0:
print("ERROR: flow_stats_entry unpack length too small",
self.length)
- binary_string = self.actions.unpack(binary_string, bytes=ai_len)
+ obj = action_list()
+ binary_string = obj.unpack(binary_string, bytes=ai_len)
+ self.actions = list(obj)
return binary_string
def __len__(self):