blob: 75c014da377b34d78dea3980a9c095f765cca9e3 [file] [log] [blame]
Dan Talaycof75360a2010-02-05 22:22:54 -08001"""
2OpenFlow actions list class
3"""
4
5from action import *
Dan Talaycob9cb5482010-02-09 15:23:12 -08006from cstruct import ofp_header
Dan Talayco3afcf722010-05-11 15:05:11 -07007import copy
Dan Talaycof75360a2010-02-05 22:22:54 -08008
9# # Map OFP action identifiers to the actual structures used on the wire
10# action_object_map = {
11# OFPAT_OUTPUT : ofp_action_output,
12# OFPAT_SET_VLAN_VID : ofp_action_vlan_vid,
13# OFPAT_SET_VLAN_PCP : ofp_action_vlan_pcp,
14# OFPAT_STRIP_VLAN : ofp_action_header,
15# OFPAT_SET_DL_SRC : ofp_action_dl_addr,
16# OFPAT_SET_DL_DST : ofp_action_dl_addr,
17# OFPAT_SET_NW_SRC : ofp_action_nw_addr,
18# OFPAT_SET_NW_DST : ofp_action_nw_addr,
19# OFPAT_SET_NW_TOS : ofp_action_nw_tos,
20# OFPAT_SET_TP_SRC : ofp_action_tp_port,
21# OFPAT_SET_TP_DST : ofp_action_tp_port,
22# OFPAT_ENQUEUE : ofp_action_enqueue
23# }
24
Dan Talaycof75360a2010-02-05 22:22:54 -080025action_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,
Dan Talayco56eb48d2010-02-10 22:38:24 -080037 OFPAT_ENQUEUE : action_enqueue,
38 OFPAT_VENDOR : action_vendor
Dan Talaycof75360a2010-02-05 22:22:54 -080039}
40
41class action_list(object):
42 """
43 Maintain a list of actions
44
45 Data members:
46 @arg actions: An array of action objects such as action_output, etc.
47
48 Methods:
49 @arg pack: Pack the structure into a string
50 @arg unpack: Unpack a string to objects, with proper typing
51 @arg add: Add an action to the list; you can directly access
52 the action member, but add will validate that the added object
53 is an action.
54
55 """
56
57 def __init__(self):
58 self.actions = []
59
60 def pack(self):
61 """
62 Pack a list of actions
63
64 Returns the packed string
65 """
66
67 packed = ""
68 for act in self.actions:
69 packed += act.pack()
70 return packed
71
72 def unpack(self, binary_string, bytes=None):
73 """
74 Unpack a list of actions
75
76 Unpack actions from a binary string, creating an array
77 of objects of the appropriate type
78
79 @param binary_string The string to be unpacked
80
81 @param bytes The total length of the action list in bytes.
82 Ignored if decode is True. If None and decode is false, the
83 list is assumed to extend through the entire string.
84
85 @return The remainder of binary_string that was not parsed
86
87 """
88 if bytes == None:
89 bytes = len(binary_string)
90 bytes_done = 0
91 count = 0
92 cur_string = binary_string
93 while bytes_done < bytes:
94 hdr = ofp_action_header()
95 hdr.unpack(cur_string)
Dan Talaycoc398ca92010-02-07 22:57:28 -080096 if hdr.len < OFP_ACTION_HEADER_BYTES:
97 print "ERROR: Action too short"
98 break
Dan Talaycof75360a2010-02-05 22:22:54 -080099 if not hdr.type in action_object_map.keys():
Dan Talayco56eb48d2010-02-10 22:38:24 -0800100 print "WARNING: Skipping unknown action ", hdr.type, hdr.len
Dan Talaycof75360a2010-02-05 22:22:54 -0800101 else:
Dan Talaycof75360a2010-02-05 22:22:54 -0800102 self.actions.append(action_object_map[hdr.type]())
Dan Talayco56eb48d2010-02-10 22:38:24 -0800103 self.actions[count].unpack(cur_string)
Dan Talaycof75360a2010-02-05 22:22:54 -0800104 count += 1
105 cur_string = cur_string[hdr.len:]
106 bytes_done += hdr.len
107 return cur_string
108
109 def add(self, action):
110 """
111 Add an action to an action list
112
113 @param action The action to add
114
Dan Talaycof75360a2010-02-05 22:22:54 -0800115 """
Rich Lanee30455b2013-01-03 16:24:44 -0800116 if not isinstance(action, action_class_list):
117 raise ValueError("%s is not an action" % type(action))
118 self.actions.append(copy.deepcopy(action))
119 return True # for backwards compatibility
Dan Talaycof75360a2010-02-05 22:22:54 -0800120
Dan Talaycoc398ca92010-02-07 22:57:28 -0800121 def remove_type(self, type):
122 """
123 Remove the first action on the list of the given type
124
125 @param type The type of action to search
126
127 @return The object removed, if any; otherwise None
128
129 """
130 for index in xrange(len(self.actions)):
131 if self.actions[index].type == type:
132 return self.actions.pop(index)
133 return None
134
135 def find_type(self, type):
136 """
137 Find the first action on the list of the given type
138
139 @param type The type of action to search
140
141 @return The object with the matching type if any; otherwise None
142
143 """
144 for index in xrange(len(self.actions)):
145 if self.actions[index].type == type:
146 return self.actions[index]
147 return None
148
149 def extend(self, other):
150 """
151 Add the actions in other to this list
152
153 @param other An object of type action_list whose
154 entries are to be merged into this list
155
156 @return True if successful. If not successful, the list
157 may have been modified.
158
159 @todo Check if this is proper deep copy or not
160
161 """
162 for act in other.actions:
Rich Lanee30455b2013-01-03 16:24:44 -0800163 self.add(act)
164 return True # for backwards compatibility
Dan Talaycoc398ca92010-02-07 22:57:28 -0800165
Dan Talaycof75360a2010-02-05 22:22:54 -0800166 def __len__(self):
167 length = 0
168 for act in self.actions:
169 length += act.__len__()
170 return length
171
172 def __eq__(self, other):
173 if type(self) != type(other): return False
174 if self.actions != other.actions: return False
175 return True
176
177 def __ne__(self, other): return not self.__eq__(other)
178
179 def show(self, prefix=''):
Dan Talayco46755fa2010-03-09 21:44:29 -0800180 outstr = prefix + "Action List with " + str(len(self.actions)) + \
181 " actions\n"
Dan Talaycof75360a2010-02-05 22:22:54 -0800182 count = 0
183 for obj in self.actions:
184 count += 1
Dan Talayco46755fa2010-03-09 21:44:29 -0800185 outstr += prefix + " Action " + str(count) + ": \n"
186 outstr += obj.show(prefix + ' ')
187 return outstr