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:
parent
5e176f9e7c
commit
ec04ff9f46
|
@ -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):
|
||||||
|
|
|
@ -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}})
|
||||||
|
|
Loading…
Reference in New Issue