blob: 628e067e139c3cdf3bc923f192760dd1cb661a5b [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
115 @return True if successful, False if not an action object
116
117 """
118 if isinstance(action, action_class_list):
Dan Talayco3afcf722010-05-11 15:05:11 -0700119 tmp = copy.deepcopy(action)
120 self.actions.append(tmp)
Dan Talaycof75360a2010-02-05 22:22:54 -0800121 return True
122 return False
123
Dan Talaycoc398ca92010-02-07 22:57:28 -0800124 def remove_type(self, type):
125 """
126 Remove the first action on the list of the given type
127
128 @param type The type of action to search
129
130 @return The object removed, if any; otherwise None
131
132 """
133 for index in xrange(len(self.actions)):
134 if self.actions[index].type == type:
135 return self.actions.pop(index)
136 return None
137
138 def find_type(self, type):
139 """
140 Find the first action on the list of the given type
141
142 @param type The type of action to search
143
144 @return The object with the matching type if any; otherwise None
145
146 """
147 for index in xrange(len(self.actions)):
148 if self.actions[index].type == type:
149 return self.actions[index]
150 return None
151
152 def extend(self, other):
153 """
154 Add the actions in other to this list
155
156 @param other An object of type action_list whose
157 entries are to be merged into this list
158
159 @return True if successful. If not successful, the list
160 may have been modified.
161
162 @todo Check if this is proper deep copy or not
163
164 """
165 for act in other.actions:
166 if not self.add(act):
167 return False
168 return True
169
Dan Talaycof75360a2010-02-05 22:22:54 -0800170 def __len__(self):
171 length = 0
172 for act in self.actions:
173 length += act.__len__()
174 return length
175
176 def __eq__(self, other):
177 if type(self) != type(other): return False
178 if self.actions != other.actions: return False
179 return True
180
181 def __ne__(self, other): return not self.__eq__(other)
182
183 def show(self, prefix=''):
Dan Talayco46755fa2010-03-09 21:44:29 -0800184 outstr = prefix + "Action List with " + str(len(self.actions)) + \
185 " actions\n"
Dan Talaycof75360a2010-02-05 22:22:54 -0800186 count = 0
187 for obj in self.actions:
188 count += 1
Dan Talayco46755fa2010-03-09 21:44:29 -0800189 outstr += prefix + " Action " + str(count) + ": \n"
190 outstr += obj.show(prefix + ' ')
191 return outstr