blob: 2c5a9069262d843c953190136ad5886e41bc5aa7 [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
Rich Lane72a0cfe2013-01-04 14:37:53 -080057 def __init__(self, actions=None):
58 if actions == None:
59 actions = []
60 self.actions = actions
Dan Talaycof75360a2010-02-05 22:22:54 -080061
62 def pack(self):
63 """
64 Pack a list of actions
65
66 Returns the packed string
67 """
68
69 packed = ""
70 for act in self.actions:
71 packed += act.pack()
72 return packed
73
74 def unpack(self, binary_string, bytes=None):
75 """
76 Unpack a list of actions
77
78 Unpack actions from a binary string, creating an array
79 of objects of the appropriate type
80
81 @param binary_string The string to be unpacked
82
83 @param bytes The total length of the action list in bytes.
84 Ignored if decode is True. If None and decode is false, the
85 list is assumed to extend through the entire string.
86
87 @return The remainder of binary_string that was not parsed
88
89 """
90 if bytes == None:
91 bytes = len(binary_string)
92 bytes_done = 0
93 count = 0
94 cur_string = binary_string
95 while bytes_done < bytes:
96 hdr = ofp_action_header()
97 hdr.unpack(cur_string)
Dan Talaycoc398ca92010-02-07 22:57:28 -080098 if hdr.len < OFP_ACTION_HEADER_BYTES:
99 print "ERROR: Action too short"
100 break
Dan Talaycof75360a2010-02-05 22:22:54 -0800101 if not hdr.type in action_object_map.keys():
Dan Talayco56eb48d2010-02-10 22:38:24 -0800102 print "WARNING: Skipping unknown action ", hdr.type, hdr.len
Dan Talaycof75360a2010-02-05 22:22:54 -0800103 else:
Dan Talaycof75360a2010-02-05 22:22:54 -0800104 self.actions.append(action_object_map[hdr.type]())
Dan Talayco56eb48d2010-02-10 22:38:24 -0800105 self.actions[count].unpack(cur_string)
Dan Talaycof75360a2010-02-05 22:22:54 -0800106 count += 1
107 cur_string = cur_string[hdr.len:]
108 bytes_done += hdr.len
109 return cur_string
110
Rich Lanec495d9e2013-03-08 17:43:36 -0800111 def append(self, action):
Dan Talaycof75360a2010-02-05 22:22:54 -0800112 """
Rich Lanec495d9e2013-03-08 17:43:36 -0800113 Append an action to an action list
Dan Talaycof75360a2010-02-05 22:22:54 -0800114
Rich Lanec495d9e2013-03-08 17:43:36 -0800115 @param action The action to append
Dan Talaycof75360a2010-02-05 22:22:54 -0800116
Dan Talaycof75360a2010-02-05 22:22:54 -0800117 """
Rich Lanee30455b2013-01-03 16:24:44 -0800118 if not isinstance(action, action_class_list):
119 raise ValueError("%s is not an action" % type(action))
120 self.actions.append(copy.deepcopy(action))
121 return True # for backwards compatibility
Dan Talaycof75360a2010-02-05 22:22:54 -0800122
Dan Talaycoc398ca92010-02-07 22:57:28 -0800123 def extend(self, other):
124 """
125 Add the actions in other to this list
126
127 @param other An object of type action_list whose
128 entries are to be merged into this list
129
130 @return True if successful. If not successful, the list
131 may have been modified.
132
133 @todo Check if this is proper deep copy or not
134
135 """
136 for act in other.actions:
Rich Lanee30455b2013-01-03 16:24:44 -0800137 self.add(act)
138 return True # for backwards compatibility
Dan Talaycoc398ca92010-02-07 22:57:28 -0800139
Dan Talaycof75360a2010-02-05 22:22:54 -0800140 def __len__(self):
141 length = 0
142 for act in self.actions:
143 length += act.__len__()
144 return length
145
Rich Lanee6ea3fe2013-03-08 17:54:38 -0800146 def __iter__(self):
147 return self.actions.__iter__()
148
Dan Talaycof75360a2010-02-05 22:22:54 -0800149 def __eq__(self, other):
150 if type(self) != type(other): return False
151 if self.actions != other.actions: return False
152 return True
153
154 def __ne__(self, other): return not self.__eq__(other)