blob: bce8cc7212c74603f6042f5f4dd9733863767b79 [file] [log] [blame]
Rich Lane5ec97b82013-01-06 18:04:25 -08001"""
2OpenFlow instruction list class
3"""
4
5import action
6import instruction
7from action_list import action_list
8from base_list import ofp_base_list
9from cstruct import ofp_header
10import unittest
11
12# Instruction list
13
14instruction_object_map = {
15 action.OFPIT_GOTO_TABLE : instruction.instruction_goto_table,
16 action.OFPIT_WRITE_METADATA : instruction.instruction_write_metadata,
17 action.OFPIT_WRITE_ACTIONS : instruction.instruction_write_actions,
18 action.OFPIT_APPLY_ACTIONS : instruction.instruction_apply_actions,
19 action.OFPIT_CLEAR_ACTIONS : instruction.instruction_clear_actions,
20 action.OFPIT_EXPERIMENTER : instruction.instruction_experimenter
21}
22
23class instruction_list(ofp_base_list):
24 """
25 Maintain a list of instructions
26
27 Data members:
28 @arg instructions An array of instructions such as write_actions
29
30 Methods:
31 @arg pack: Pack the structure into a string
32 @arg unpack: Unpack a string to objects, with proper typing
33 @arg add: Add an action to the list; you can directly access
34 the action member, but add will validate that the added object
35 is an action.
36
37 """
38
39 def __init__(self):
40 ofp_base_list.__init__(self)
41 self.instructions = self.items
42 self.name = "instruction"
43 self.class_list = instruction.instruction_class_list
44
45 def unpack(self, binary_string, bytes=None):
46 """
47 Unpack a list of instructions
48
49 Unpack instructions from a binary string, creating an array
50 of objects of the appropriate type
51
52 @param binary_string The string to be unpacked
53
54 @param bytes The total length of the instruction list in bytes.
55 Ignored if decode is True. If bytes is None and decode is false, the
56 list is assumed to extend through the entire string.
57
58 @return The remainder of binary_string that was not parsed
59
60 """
61 if bytes == None:
62 bytes = len(binary_string)
63 bytes_done = 0
64 count = 0
65 cur_string = binary_string
66 while bytes_done < bytes:
67 hdr = instruction.ofp_instruction()
68 hdr.unpack(cur_string)
69 if hdr.len < action.OFP_ACTION_HEADER_BYTES:
70 print "ERROR: Action too short"
71 break
72 if not hdr.type in instruction_object_map.keys():
73 print "WARNING: Skipping unknown action ", hdr.type, hdr.len
74 else:
75 self.instructions.append(instruction_object_map[hdr.type]())
76 self.instructions[count].unpack(cur_string)
77 count += 1
78 cur_string = cur_string[hdr.len:]
79 bytes_done += hdr.len
80 return cur_string
81
82class Instruction_List_Test(unittest.TestCase):
83 def runTest(self):
84 # instructions header is 8 bytes
85 l = instruction_list()
86 act = action.action_output()
87 act.port = 7
88 inst = instruction.instruction_apply_actions()
89 self.assertTrue(inst.actions.add(act))
90 self.assertTrue(l.add(inst))
91 pkt = l.pack()
92 # 24 == 8 (list header) + (apply header) 8 + (output action) 8
93 self.assertEqual(len(pkt),24)
94
95 l = instruction_list()
96 self.assertTrue(l.add(instruction.instruction_goto_table()))
97