ofproto: Avoid emitting illegal instruction sets

The OpenFlow spec forbids multiple occurences of a same instruction
type within a mod_flow message, so make sure
ofp_instruction_from_jsondict doesn't emit such an instruction set.

Signed-off-by: IWAMOTO Toshihiro <iwamoto@valinux.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
IWAMOTO Toshihiro 2017-07-05 14:37:55 +09:00 committed by FUJITA Tomonori
parent 5e176f9e7c
commit ec04ff9f46
2 changed files with 29 additions and 15 deletions

View File

@ -147,12 +147,17 @@ def ofp_instruction_from_jsondict(dp, jsonlist, encap=True):
""" """
proto = dp.ofproto proto = dp.ofproto
parser = dp.ofproto_parser parser = dp.ofproto_parser
actions = []
result = [] result = []
for jsondict in jsonlist: for jsondict in jsonlist:
assert len(jsondict) == 1 assert len(jsondict) == 1
k, v = list(jsondict.items())[0] k, v = list(jsondict.items())[0]
cls = getattr(parser, k) cls = getattr(parser, k)
if not issubclass(cls, parser.OFPAction): if issubclass(cls, parser.OFPAction):
if encap:
actions.append(cls.from_jsondict(v))
continue
else:
ofpinst = getattr(parser, 'OFPInstruction', None) ofpinst = getattr(parser, 'OFPInstruction', None)
if not ofpinst or not issubclass(cls, ofpinst): if not ofpinst or not issubclass(cls, ofpinst):
raise ValueError("Supplied jsondict is of wrong type: %s", raise ValueError("Supplied jsondict is of wrong type: %s",
@ -161,20 +166,13 @@ def ofp_instruction_from_jsondict(dp, jsonlist, encap=True):
if not encap: if not encap:
return result return result
insts = []
actions = [] if actions:
result.append(None) # sentinel # Although the OpenFlow spec says Apply Actions is executed first,
for act_or_inst in result: # let's place it in the head as a precaution.
if isinstance(act_or_inst, parser.OFPAction): result = [parser.OFPInstructionActions(
actions.append(act_or_inst) proto.OFPIT_APPLY_ACTIONS, actions)] + result
else: return result
if actions:
insts.append(parser.OFPInstructionActions(
proto.OFPIT_APPLY_ACTIONS, actions))
actions = []
if act_or_inst is not None:
insts.append(act_or_inst)
return insts
class StringifyMixin(stringify.StringifyMixin): class StringifyMixin(stringify.StringifyMixin):

View File

@ -149,3 +149,19 @@ class Test_OfctlString(unittest.TestCase):
{'len': 8, {'len': 8,
'table_id': 33, 'table_id': 33,
'type': 1}}) 'type': 1}})
def test_multi_unordered(self):
self._test_str(self.fake_dp_of15,
'pop_vlan,goto_table:33,output:1',
{'OFPInstructionActions':
{'actions': [{'OFPActionPopVlan': {'len': 8,
'type': 18}},
{'OFPActionOutput': {'len': 16,
'max_len': 65509,
'port': 1,
'type': 0}}],
'type': 4}},
{'OFPInstructionGotoTable':
{'len': 8,
'table_id': 33,
'type': 1}})