blob: 7a50c750bd8d7db4c2269e497869740d213b0490 [file] [log] [blame]
Rich Lane629393f2013-01-10 15:37:33 -08001import struct
ederlffdedc072013-01-18 09:32:00 -02002import binascii
Rich Lane629393f2013-01-10 15:37:33 -08003import match as match
ederlffdedc072013-01-18 09:32:00 -02004from match import oxm_tlv
Rich Lane629393f2013-01-10 15:37:33 -08005from base_list import ofp_base_list
6
7
8class match_list(ofp_base_list):
9
10 def __init__(self):
11 ofp_base_list.__init__(self)
12 self.tlvs = self.items
13 self.name = "match"
14 self.class_list = match.match_class_list
15
16 def __len__(self):
17 return sum([len(i) for i in self])
ederlffdedc072013-01-18 09:32:00 -020018
19 def __eq__(self, other):
20 self.tlvs.sort(key=lambda x: x.field);
21 other.tlvs.sort(key=lambda x: x.field);
22 return self.tlvs == other.tlvs
23
Rich Lane629393f2013-01-10 15:37:33 -080024 def unpack(self, binary_string, bytes=None):
ederlffdedc072013-01-18 09:32:00 -020025 oxm_tlv.factory()
Rich Lane629393f2013-01-10 15:37:33 -080026 if bytes <= 4:
27 return binary_string[4:]
28 if bytes == None:
29 bytes = len(binary_string)
30 offset = 0
31 cur_string = binary_string
ederlffdedc072013-01-18 09:32:00 -020032 part = lambda: cur_string[read+4:read+4+oxm_length]
Rich Lane629393f2013-01-10 15:37:33 -080033 while offset < bytes:
34 read = 0
ederlffdedc072013-01-18 09:32:00 -020035 oxm_class, oxm_fieldhm, oxm_length = struct.unpack("!HBB",
36 cur_string[read:read+4])
Rich Lane629393f2013-01-10 15:37:33 -080037 #Found padding bytes?
38 if not oxm_class:
39 break
40 oxm_field = oxm_fieldhm >> 1
41 oxm_hasmask = oxm_fieldhm & 0x00000001
ederlffdedc072013-01-18 09:32:00 -020042
43 if oxm_length == 1:
44 if oxm_hasmask:
45 value, mask = struct.unpack("BB", part())[:2]
46 else:
47 value = struct.unpack("!B", part())[0]
48 mask = None
49 elif oxm_length == 2 or (oxm_length == 4 and oxm_hasmask == True):
50 if oxm_hasmask:
51 value, mask = struct.unpack("!HH", part())[:2]
52 else:
53 value = struct.unpack("!H", part())[0]
54 mask = None
55 elif oxm_length == 4 or (oxm_length == 8 and oxm_hasmask == True):
56 if oxm_hasmask:
57 value, mask = struct.unpack("!II", part())[:2]
58 else:
59 value = struct.unpack("!I", part())[0]
60 mask = None
61 elif oxm_length == 6 or oxm_length == 12:
62 if oxm_hasmask:
63 data = struct.unpack("!12B", part())[0]
64 value, mask = data[:6], data[6:]
65 else:
66 value = list(struct.unpack("!6B", part()))
67 mask = None
68 elif oxm_length == 8 or (oxm_length == 16 and oxm_hasmask == True):
69 if oxm_hasmask:
70 value, mask = struct.unpack("!QQ", part())[0]
71 else:
72 value = struct.unpack("!Q", part())[0]
73 mask = None
74 elif oxm_length == 16 or oxm_length == 32:
75 if oxm_hasmask:
76 data = struct.unpack("!32s", part())[0]
77 value, mask = data[:16], data[16:]
78 else:
79 value = struct.unpack("!16s", part())[0]
80 mask = None
81
82 oxm = oxm_tlv.create(oxm_field)
83 oxm.set_hasmask(oxm_hasmask)
84 oxm.set_value(value)
85 oxm.set_mask(mask)
Rich Lane629393f2013-01-10 15:37:33 -080086 self.tlvs.append(oxm)
87 read = 4 + oxm_length
88 offset += read
ederlffdedc072013-01-18 09:32:00 -020089 cur_string = cur_string[read:]
Rich Lane629393f2013-01-10 15:37:33 -080090 return cur_string