blob: 5327eee2dcea0c529f5e433ce948be73b8d52294 [file] [log] [blame]
Dan Talaycof75360a2010-02-05 22:22:54 -08001"""
2OpenFlow actions list class
3"""
4
5from action import *
6from ofp import ofp_header
7
8# # Map OFP action identifiers to the actual structures used on the wire
9# action_object_map = {
10# OFPAT_OUTPUT : ofp_action_output,
11# OFPAT_SET_VLAN_VID : ofp_action_vlan_vid,
12# OFPAT_SET_VLAN_PCP : ofp_action_vlan_pcp,
13# OFPAT_STRIP_VLAN : ofp_action_header,
14# OFPAT_SET_DL_SRC : ofp_action_dl_addr,
15# OFPAT_SET_DL_DST : ofp_action_dl_addr,
16# OFPAT_SET_NW_SRC : ofp_action_nw_addr,
17# OFPAT_SET_NW_DST : ofp_action_nw_addr,
18# OFPAT_SET_NW_TOS : ofp_action_nw_tos,
19# OFPAT_SET_TP_SRC : ofp_action_tp_port,
20# OFPAT_SET_TP_DST : ofp_action_tp_port,
21# OFPAT_ENQUEUE : ofp_action_enqueue
22# }
23
24# For debugging
25action_object_map = {
26 OFPAT_OUTPUT : action_output,
27 OFPAT_SET_VLAN_VID : action_set_vlan_vid,
28 OFPAT_SET_VLAN_PCP : action_set_vlan_pcp,
29 OFPAT_STRIP_VLAN : action_strip_vlan,
30 OFPAT_SET_DL_SRC : action_set_dl_src,
31 OFPAT_SET_DL_DST : action_set_dl_dst,
32 OFPAT_SET_NW_SRC : action_set_nw_src,
33 OFPAT_SET_NW_DST : action_set_nw_dst,
34 OFPAT_SET_NW_TOS : action_set_nw_tos,
35 OFPAT_SET_TP_SRC : action_set_tp_src,
36 OFPAT_SET_TP_DST : action_set_tp_dst,
37 OFPAT_ENQUEUE : action_enqueue
38}
39
40class action_list(object):
41 """
42 Maintain a list of actions
43
44 Data members:
45 @arg actions: An array of action objects such as action_output, etc.
46
47 Methods:
48 @arg pack: Pack the structure into a string
49 @arg unpack: Unpack a string to objects, with proper typing
50 @arg add: Add an action to the list; you can directly access
51 the action member, but add will validate that the added object
52 is an action.
53
54 """
55
56 def __init__(self):
57 self.actions = []
58
59 def pack(self):
60 """
61 Pack a list of actions
62
63 Returns the packed string
64 """
65
66 packed = ""
67 for act in self.actions:
68 packed += act.pack()
69 return packed
70
71 def unpack(self, binary_string, bytes=None):
72 """
73 Unpack a list of actions
74
75 Unpack actions from a binary string, creating an array
76 of objects of the appropriate type
77
78 @param binary_string The string to be unpacked
79
80 @param bytes The total length of the action list in bytes.
81 Ignored if decode is True. If None and decode is false, the
82 list is assumed to extend through the entire string.
83
84 @return The remainder of binary_string that was not parsed
85
86 """
87 if bytes == None:
88 bytes = len(binary_string)
89 bytes_done = 0
90 count = 0
91 cur_string = binary_string
92 while bytes_done < bytes:
93 hdr = ofp_action_header()
94 hdr.unpack(cur_string)
Dan Talaycoc398ca92010-02-07 22:57:28 -080095 if hdr.len < OFP_ACTION_HEADER_BYTES:
96 print "ERROR: Action too short"
97 break
Dan Talaycof75360a2010-02-05 22:22:54 -080098 if not hdr.type in action_object_map.keys():
99 print "WARNING: Skipping unknown action ", hdr.type
100 else:
Dan Talaycof75360a2010-02-05 22:22:54 -0800101 self.actions.append(action_object_map[hdr.type]())
102 self.actions[count].unpack(binary_string)
103 count += 1
104 cur_string = cur_string[hdr.len:]
105 bytes_done += hdr.len
106 return cur_string
107
108 def add(self, action):
109 """
110 Add an action to an action list
111
112 @param action The action to add
113
114 @return True if successful, False if not an action object
115
116 """
117 if isinstance(action, action_class_list):
118 self.actions.append(action)
119 return True
120 return False
121
Dan Talaycoc398ca92010-02-07 22:57:28 -0800122 def remove_type(self, type):
123 """
124 Remove the first action on the list of the given type
125
126 @param type The type of action to search
127
128 @return The object removed, if any; otherwise None
129
130 """
131 for index in xrange(len(self.actions)):
132 if self.actions[index].type == type:
133 return self.actions.pop(index)
134 return None
135
136 def find_type(self, type):
137 """
138 Find the first action on the list of the given type
139
140 @param type The type of action to search
141
142 @return The object with the matching type if any; otherwise None
143
144 """
145 for index in xrange(len(self.actions)):
146 if self.actions[index].type == type:
147 return self.actions[index]
148 return None
149
150 def extend(self, other):
151 """
152 Add the actions in other to this list
153
154 @param other An object of type action_list whose
155 entries are to be merged into this list
156
157 @return True if successful. If not successful, the list
158 may have been modified.
159
160 @todo Check if this is proper deep copy or not
161
162 """
163 for act in other.actions:
164 if not self.add(act):
165 return False
166 return True
167
Dan Talaycof75360a2010-02-05 22:22:54 -0800168 def __len__(self):
169 length = 0
170 for act in self.actions:
171 length += act.__len__()
172 return length
173
174 def __eq__(self, other):
175 if type(self) != type(other): return False
176 if self.actions != other.actions: return False
177 return True
178
179 def __ne__(self, other): return not self.__eq__(other)
180
181 def show(self, prefix=''):
182 print prefix + "Action List with " + str(len(self.actions)) + \
183 " actions"
184 count = 0
185 for obj in self.actions:
186 count += 1
187 print " Action " + str(count) + ": "
188 obj.show(prefix + ' ')