Rich Lane | 629393f | 2013-01-10 15:37:33 -0800 | [diff] [blame] | 1 | import struct |
ederlf | fdedc07 | 2013-01-18 09:32:00 -0200 | [diff] [blame] | 2 | import binascii |
Rich Lane | 629393f | 2013-01-10 15:37:33 -0800 | [diff] [blame] | 3 | import match as match |
ederlf | fdedc07 | 2013-01-18 09:32:00 -0200 | [diff] [blame] | 4 | from match import oxm_tlv |
Rich Lane | 629393f | 2013-01-10 15:37:33 -0800 | [diff] [blame] | 5 | from base_list import ofp_base_list |
| 6 | |
| 7 | |
| 8 | class 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]) |
ederlf | fdedc07 | 2013-01-18 09:32:00 -0200 | [diff] [blame] | 18 | |
| 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 Lane | 629393f | 2013-01-10 15:37:33 -0800 | [diff] [blame] | 24 | def unpack(self, binary_string, bytes=None): |
ederlf | fdedc07 | 2013-01-18 09:32:00 -0200 | [diff] [blame] | 25 | oxm_tlv.factory() |
Rich Lane | 629393f | 2013-01-10 15:37:33 -0800 | [diff] [blame] | 26 | 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 |
ederlf | fdedc07 | 2013-01-18 09:32:00 -0200 | [diff] [blame] | 32 | part = lambda: cur_string[read+4:read+4+oxm_length] |
Rich Lane | 629393f | 2013-01-10 15:37:33 -0800 | [diff] [blame] | 33 | while offset < bytes: |
| 34 | read = 0 |
ederlf | fdedc07 | 2013-01-18 09:32:00 -0200 | [diff] [blame] | 35 | oxm_class, oxm_fieldhm, oxm_length = struct.unpack("!HBB", |
| 36 | cur_string[read:read+4]) |
Rich Lane | 629393f | 2013-01-10 15:37:33 -0800 | [diff] [blame] | 37 | #Found padding bytes? |
| 38 | if not oxm_class: |
| 39 | break |
| 40 | oxm_field = oxm_fieldhm >> 1 |
| 41 | oxm_hasmask = oxm_fieldhm & 0x00000001 |
ederlf | fdedc07 | 2013-01-18 09:32:00 -0200 | [diff] [blame] | 42 | |
| 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 Lane | 629393f | 2013-01-10 15:37:33 -0800 | [diff] [blame] | 86 | self.tlvs.append(oxm) |
| 87 | read = 4 + oxm_length |
| 88 | offset += read |
ederlf | fdedc07 | 2013-01-18 09:32:00 -0200 | [diff] [blame] | 89 | cur_string = cur_string[read:] |
Rich Lane | 629393f | 2013-01-10 15:37:33 -0800 | [diff] [blame] | 90 | return cur_string |