backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / ofproto / nx_match.py
1 # Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation.
2 # Copyright (C) 2011, 2012 Isaku Yamahata <yamahata at valinux co jp>
3 # Copyright (C) 2012 Simon Horman <horms ad verge net au>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #    http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 # implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17
18 import struct
19
20 from ryu import exception
21 from ryu.lib import mac
22 from ryu.lib.pack_utils import msg_pack_into
23 from ryu.ofproto import ether
24 from ryu.ofproto import ofproto_parser
25 from ryu.ofproto import ofproto_v1_0
26 from ryu.ofproto import inet
27
28
29 import logging
30 LOG = logging.getLogger('ryu.ofproto.nx_match')
31
32
33 UINT64_MAX = (1 << 64) - 1
34 UINT32_MAX = (1 << 32) - 1
35 UINT16_MAX = (1 << 16) - 1
36
37 FWW_IN_PORT = 1 << 0
38 FWW_DL_TYPE = 1 << 4
39 FWW_NW_PROTO = 1 << 5
40 # No corresponding OFPFW_* bits
41 FWW_NW_DSCP = 1 << 1
42 FWW_NW_ECN = 1 << 2
43 FWW_ARP_SHA = 1 << 3
44 FWW_ARP_THA = 1 << 6
45 FWW_IPV6_LABEL = 1 << 7
46 FWW_NW_TTL = 1 << 8
47 FWW_ALL = (1 << 13) - 1
48
49 FLOW_NW_FRAG_ANY = 1 << 0
50 FLOW_NW_FRAG_LATER = 1 << 1
51 FLOW_NW_FRAG_MASK = FLOW_NW_FRAG_ANY | FLOW_NW_FRAG_LATER
52
53 IP_ECN_MASK = 0x03
54 IP_DSCP_MASK = 0xfc
55
56 MF_PACK_STRING_BE64 = '!Q'
57 MF_PACK_STRING_BE32 = '!I'
58 MF_PACK_STRING_BE16 = '!H'
59 MF_PACK_STRING_8 = '!B'
60 MF_PACK_STRING_MAC = '!6s'
61 MF_PACK_STRING_IPV6 = '!8H'
62
63 _MF_FIELDS = {}
64
65 FLOW_N_REGS = 8  # ovs 1.5
66
67
68 class Flow(ofproto_parser.StringifyMixin):
69     def __init__(self):
70         self.in_port = 0
71         self.dl_vlan = 0
72         self.dl_vlan_pcp = 0
73         self.dl_src = mac.DONTCARE
74         self.dl_dst = mac.DONTCARE
75         self.dl_type = 0
76         self.tp_dst = 0
77         self.tp_src = 0
78         self.nw_tos = 0
79         self.vlan_tci = 0
80         self.nw_ttl = 0
81         self.nw_proto = 0
82         self.arp_sha = 0
83         self.arp_tha = 0
84         self.nw_src = 0
85         self.nw_dst = 0
86         self.tun_id = 0
87         self.arp_spa = 0
88         self.arp_tpa = 0
89         self.ipv6_src = []
90         self.ipv6_dst = []
91         self.nd_target = []
92         self.nw_frag = 0
93         self.regs = [0] * FLOW_N_REGS
94         self.ipv6_label = 0
95         self.pkt_mark = 0
96         self.tcp_flags = 0
97
98
99 class FlowWildcards(ofproto_parser.StringifyMixin):
100     def __init__(self):
101         self.dl_src_mask = 0
102         self.dl_dst_mask = 0
103         self.tp_src_mask = 0
104         self.tp_dst_mask = 0
105         self.nw_src_mask = 0
106         self.nw_dst_mask = 0
107         self.tun_id_mask = 0
108         self.arp_spa_mask = 0
109         self.arp_tpa_mask = 0
110         self.vlan_tci_mask = 0
111         self.ipv6_src_mask = []
112         self.ipv6_dst_mask = []
113         self.nd_target_mask = []
114         self.nw_frag_mask = 0
115         self.regs_bits = 0
116         self.regs_mask = [0] * FLOW_N_REGS
117         self.wildcards = ofproto_v1_0.OFPFW_ALL
118         self.pkt_mark_mask = 0
119         self.tcp_flags_mask = 0
120
121
122 class ClsRule(ofproto_parser.StringifyMixin):
123     """describe a matching rule for OF 1.0 OFPMatch (and NX).
124     """
125
126     def __init__(self, **kwargs):
127         self.wc = FlowWildcards()
128         self.flow = Flow()
129
130         for key, value in kwargs.items():
131             if key[:3] == 'reg':
132                 register = int(key[3:] or -1)
133                 self.set_reg(register, value)
134                 continue
135
136             setter = getattr(self, 'set_' + key, None)
137             if not setter:
138                 LOG.error('Invalid kwarg specified to ClsRule (%s)', key)
139                 continue
140
141             if not isinstance(value, (tuple, list)):
142                 value = (value, )
143
144             setter(*value)
145
146     def set_in_port(self, port):
147         self.wc.wildcards &= ~FWW_IN_PORT
148         self.flow.in_port = port
149
150     def set_dl_vlan(self, dl_vlan):
151         self.wc.wildcards &= ~ofproto_v1_0.OFPFW_DL_VLAN
152         self.flow.dl_vlan = dl_vlan
153
154     def set_dl_vlan_pcp(self, dl_vlan_pcp):
155         self.wc.wildcards &= ~ofproto_v1_0.OFPFW_DL_VLAN_PCP
156         self.flow.dl_vlan_pcp = dl_vlan_pcp
157
158     def set_dl_dst(self, dl_dst):
159         self.flow.dl_dst = dl_dst
160
161     def set_dl_dst_masked(self, dl_dst, mask):
162         self.wc.dl_dst_mask = mask
163         # bit-wise and of the corresponding elements of dl_dst and mask
164         self.flow.dl_dst = mac.haddr_bitand(dl_dst, mask)
165
166     def set_dl_src(self, dl_src):
167         self.flow.dl_src = dl_src
168
169     def set_dl_src_masked(self, dl_src, mask):
170         self.wc.dl_src_mask = mask
171         self.flow.dl_src = mac.haddr_bitand(dl_src, mask)
172
173     def set_dl_type(self, dl_type):
174         self.wc.wildcards &= ~FWW_DL_TYPE
175         self.flow.dl_type = dl_type
176
177     def set_dl_tci(self, tci):
178         self.set_dl_tci_masked(tci, UINT16_MAX)
179
180     def set_dl_tci_masked(self, tci, mask):
181         self.wc.vlan_tci_mask = mask
182         self.flow.vlan_tci = tci
183
184     def set_tp_src(self, tp_src):
185         self.set_tp_src_masked(tp_src, UINT16_MAX)
186
187     def set_tp_src_masked(self, tp_src, mask):
188         self.wc.tp_src_mask = mask
189         self.flow.tp_src = tp_src & mask
190
191     def set_tp_dst(self, tp_dst):
192         self.set_tp_dst_masked(tp_dst, UINT16_MAX)
193
194     def set_tp_dst_masked(self, tp_dst, mask):
195         self.wc.tp_dst_mask = mask
196         self.flow.tp_dst = tp_dst & mask
197
198     def set_nw_proto(self, nw_proto):
199         self.wc.wildcards &= ~FWW_NW_PROTO
200         self.flow.nw_proto = nw_proto
201
202     def set_nw_src(self, nw_src):
203         self.set_nw_src_masked(nw_src, UINT32_MAX)
204
205     def set_nw_src_masked(self, nw_src, mask):
206         self.flow.nw_src = nw_src
207         self.wc.nw_src_mask = mask
208
209     def set_nw_dst(self, nw_dst):
210         self.set_nw_dst_masked(nw_dst, UINT32_MAX)
211
212     def set_nw_dst_masked(self, nw_dst, mask):
213         self.flow.nw_dst = nw_dst
214         self.wc.nw_dst_mask = mask
215
216     def set_nw_dscp(self, nw_dscp):
217         self.wc.wildcards &= ~FWW_NW_DSCP
218         self.flow.nw_tos &= ~IP_DSCP_MASK
219         self.flow.nw_tos |= nw_dscp & IP_DSCP_MASK
220
221     def set_icmp_type(self, icmp_type):
222         self.set_tp_src(icmp_type)
223
224     def set_icmp_code(self, icmp_code):
225         self.set_tp_dst(icmp_code)
226
227     def set_tun_id(self, tun_id):
228         self.set_tun_id_masked(tun_id, UINT64_MAX)
229
230     def set_tun_id_masked(self, tun_id, mask):
231         self.wc.tun_id_mask = mask
232         self.flow.tun_id = tun_id & mask
233
234     def set_nw_ecn(self, nw_ecn):
235         self.wc.wildcards &= ~FWW_NW_ECN
236         self.flow.nw_tos &= ~IP_ECN_MASK
237         self.flow.nw_tos |= nw_ecn & IP_ECN_MASK
238
239     def set_nw_ttl(self, nw_ttl):
240         self.wc.wildcards &= ~FWW_NW_TTL
241         self.flow.nw_ttl = nw_ttl
242
243     def set_nw_frag(self, nw_frag):
244         self.wc.nw_frag_mask |= FLOW_NW_FRAG_MASK
245         self.flow.nw_frag = nw_frag
246
247     def set_nw_frag_masked(self, nw_frag, mask):
248         self.wc.nw_frag_mask = mask
249         self.flow.nw_frag = nw_frag & mask
250
251     def set_arp_spa(self, spa):
252         self.set_arp_spa_masked(spa, UINT32_MAX)
253
254     def set_arp_spa_masked(self, spa, mask):
255         self.flow.arp_spa = spa
256         self.wc.arp_spa_mask = mask
257
258     def set_arp_tpa(self, tpa):
259         self.set_arp_tpa_masked(tpa, UINT32_MAX)
260
261     def set_arp_tpa_masked(self, tpa, mask):
262         self.flow.arp_tpa = tpa
263         self.wc.arp_tpa_mask = mask
264
265     def set_arp_sha(self, sha):
266         self.wc.wildcards &= ~FWW_ARP_SHA
267         self.flow.arp_sha = sha
268
269     def set_arp_tha(self, tha):
270         self.wc.wildcards &= ~FWW_ARP_THA
271         self.flow.arp_tha = tha
272
273     def set_icmpv6_type(self, icmp_type):
274         self.set_tp_src(icmp_type)
275
276     def set_icmpv6_code(self, icmp_code):
277         self.set_tp_dst(icmp_code)
278
279     def set_ipv6_label(self, label):
280         self.wc.wildcards &= ~FWW_IPV6_LABEL
281         self.flow.ipv6_label = label
282
283     def set_ipv6_src_masked(self, src, mask):
284         self.wc.ipv6_src_mask = mask
285         self.flow.ipv6_src = [x & y for (x, y) in zip(src, mask)]
286
287     def set_ipv6_src(self, src):
288         self.flow.ipv6_src = src
289
290     def set_ipv6_dst_masked(self, dst, mask):
291         self.wc.ipv6_dst_mask = mask
292         self.flow.ipv6_dst = [x & y for (x, y) in zip(dst, mask)]
293
294     def set_ipv6_dst(self, dst):
295         self.flow.ipv6_dst = dst
296
297     def set_nd_target_masked(self, target, mask):
298         self.wc.nd_target_mask = mask
299         self.flow.nd_target = [x & y for (x, y) in
300                                zip(target, mask)]
301
302     def set_nd_target(self, target):
303         self.flow.nd_target = target
304
305     def set_reg(self, reg_idx, value):
306         self.set_reg_masked(reg_idx, value, 0)
307
308     def set_reg_masked(self, reg_idx, value, mask):
309         self.wc.regs_mask[reg_idx] = mask
310         self.flow.regs[reg_idx] = value
311         self.wc.regs_bits |= (1 << reg_idx)
312
313     def set_pkt_mark_masked(self, pkt_mark, mask):
314         self.flow.pkt_mark = pkt_mark
315         self.wc.pkt_mark_mask = mask
316
317     def set_tcp_flags(self, tcp_flags, mask):
318         self.flow.tcp_flags = tcp_flags
319         self.wc.tcp_flags_mask = mask
320
321     def flow_format(self):
322         # Tunnel ID is only supported by NXM
323         if self.wc.tun_id_mask != 0:
324             return ofproto_v1_0.NXFF_NXM
325
326         # Masking DL_DST is only supported by NXM
327         if self.wc.dl_dst_mask:
328             return ofproto_v1_0.NXFF_NXM
329
330         # Masking DL_SRC is only supported by NXM
331         if self.wc.dl_src_mask:
332             return ofproto_v1_0.NXFF_NXM
333
334         # ECN is only supported by NXM
335         if not self.wc.wildcards & FWW_NW_ECN:
336             return ofproto_v1_0.NXFF_NXM
337
338         if self.wc.regs_bits > 0:
339             return ofproto_v1_0.NXFF_NXM
340
341         if self.flow.tcp_flags > 0:
342             return ofproto_v1_0.NXFF_NXM
343
344         return ofproto_v1_0.NXFF_OPENFLOW10
345
346     def match_tuple(self):
347         """return a tuple which can be used as *args for
348         ofproto_v1_0_parser.OFPMatch.__init__().
349         see Datapath.send_flow_mod.
350         """
351         assert self.flow_format() == ofproto_v1_0.NXFF_OPENFLOW10
352         wildcards = ofproto_v1_0.OFPFW_ALL
353
354         if not self.wc.wildcards & FWW_IN_PORT:
355             wildcards &= ~ofproto_v1_0.OFPFW_IN_PORT
356
357         if self.flow.dl_src != mac.DONTCARE:
358             wildcards &= ~ofproto_v1_0.OFPFW_DL_SRC
359
360         if self.flow.dl_dst != mac.DONTCARE:
361             wildcards &= ~ofproto_v1_0.OFPFW_DL_DST
362
363         if not self.wc.wildcards & FWW_DL_TYPE:
364             wildcards &= ~ofproto_v1_0.OFPFW_DL_TYPE
365
366         if self.flow.dl_vlan != 0:
367             wildcards &= ~ofproto_v1_0.OFPFW_DL_VLAN
368
369         if self.flow.dl_vlan_pcp != 0:
370             wildcards &= ~ofproto_v1_0.OFPFW_DL_VLAN_PCP
371
372         if self.flow.nw_tos != 0:
373             wildcards &= ~ofproto_v1_0.OFPFW_NW_TOS
374
375         if self.flow.nw_proto != 0:
376             wildcards &= ~ofproto_v1_0.OFPFW_NW_PROTO
377
378         if self.wc.nw_src_mask != 0 and "01" not in bin(self.wc.nw_src_mask):
379             wildcards &= ~ofproto_v1_0.OFPFW_NW_SRC_MASK
380             maskbits = (bin(self.wc.nw_src_mask).count("0") - 1)
381             wildcards |= (maskbits << ofproto_v1_0.OFPFW_NW_SRC_SHIFT)
382
383         if self.wc.nw_dst_mask != 0 and "01" not in bin(self.wc.nw_dst_mask):
384             wildcards &= ~ofproto_v1_0.OFPFW_NW_DST_MASK
385             maskbits = (bin(self.wc.nw_dst_mask).count("0") - 1)
386             wildcards |= (maskbits << ofproto_v1_0.OFPFW_NW_DST_SHIFT)
387
388         if self.flow.tp_src != 0:
389             wildcards &= ~ofproto_v1_0.OFPFW_TP_SRC
390
391         if self.flow.tp_dst != 0:
392             wildcards &= ~ofproto_v1_0.OFPFW_TP_DST
393
394         return (wildcards, self.flow.in_port, self.flow.dl_src,
395                 self.flow.dl_dst, self.flow.dl_vlan, self.flow.dl_vlan_pcp,
396                 self.flow.dl_type, self.flow.nw_tos & IP_DSCP_MASK,
397                 self.flow.nw_proto, self.flow.nw_src, self.flow.nw_dst,
398                 self.flow.tp_src, self.flow.tp_dst)
399
400
401 def _set_nxm_headers(nxm_headers):
402     '''Annotate corresponding NXM header'''
403
404     def _set_nxm_headers_dec(self):
405         self.nxm_headers = nxm_headers
406         return self
407     return _set_nxm_headers_dec
408
409
410 def _register_make(cls):
411     '''class decorator to Register mf make'''
412     assert cls.nxm_headers is not None
413     assert cls.nxm_headers is not []
414     for nxm_header in cls.nxm_headers:
415         assert nxm_header not in _MF_FIELDS
416         _MF_FIELDS[nxm_header] = cls.make
417     return cls
418
419
420 def mf_from_nxm_header(nxm_header):
421     if nxm_header not in _MF_FIELDS:
422         return None
423     make = _MF_FIELDS.get(nxm_header)
424     assert make is not None
425     return make(nxm_header)
426
427
428 class MFField(object):
429     _FIELDS_HEADERS = {}
430
431     @staticmethod
432     def register_field_header(headers):
433         def _register_field_header(cls):
434             for header in headers:
435                 MFField._FIELDS_HEADERS[header] = cls
436             return cls
437         return _register_field_header
438
439     def __init__(self, nxm_header, pack_str):
440         self.nxm_header = nxm_header
441         self.pack_str = pack_str
442         self.n_bytes = struct.calcsize(pack_str)
443         self.n_bits = self.n_bytes * 8
444
445     @classmethod
446     def parser(cls, buf, offset):
447         (header,) = struct.unpack_from('!I', buf, offset)
448
449         cls_ = MFField._FIELDS_HEADERS.get(header)
450
451         if cls_:
452             field = cls_.field_parser(header, buf, offset)
453         else:
454             # print 'unknown field type'
455             raise
456         field.length = (header & 0xff) + 4
457
458         return field
459
460     @classmethod
461     def field_parser(cls, header, buf, offset):
462         hasmask = (header >> 8) & 1
463         mask = None
464         if hasmask:
465             pack_str = '!' + cls.pack_str[1:] * 2
466             (value, mask) = struct.unpack_from(pack_str, buf,
467                                                offset + 4)
468         else:
469             (value,) = struct.unpack_from(cls.pack_str, buf,
470                                           offset + 4)
471         return cls(header, value, mask)
472
473     def _put(self, buf, offset, value):
474         msg_pack_into(self.pack_str, buf, offset, value)
475         return self.n_bytes
476
477     def putw(self, buf, offset, value, mask):
478         len_ = self._put(buf, offset, value)
479         return len_ + self._put(buf, offset + len_, mask)
480
481     def _is_all_ones(self, value):
482         return value == (1 << self.n_bits) - 1
483
484     def putm(self, buf, offset, value, mask):
485         if mask == 0:
486             return 0
487         elif self._is_all_ones(mask):
488             return self._put(buf, offset, value)
489         else:
490             return self.putw(buf, offset, value, mask)
491
492     def _putv6(self, buf, offset, value):
493         msg_pack_into(self.pack_str, buf, offset, *value)
494         return self.n_bytes
495
496     def putv6(self, buf, offset, value, mask):
497         len_ = self._putv6(buf, offset, value)
498         if len(mask):
499             return len_ + self._putv6(buf, offset + len_, mask)
500         return len_
501
502
503 @_register_make
504 @_set_nxm_headers([ofproto_v1_0.NXM_OF_IN_PORT])
505 @MFField.register_field_header([ofproto_v1_0.NXM_OF_IN_PORT])
506 class MFInPort(MFField):
507     pack_str = MF_PACK_STRING_BE16
508
509     def __init__(self, header, value, mask=None):
510         super(MFInPort, self).__init__(header, MFInPort.pack_str)
511         self.value = value
512
513     @classmethod
514     def make(cls, header):
515         return cls(header, MFInPort.pack_str)
516
517     def put(self, buf, offset, rule):
518         return self._put(buf, offset, rule.flow.in_port)
519
520
521 @_register_make
522 @_set_nxm_headers([ofproto_v1_0.NXM_OF_ETH_DST, ofproto_v1_0.NXM_OF_ETH_DST_W])
523 @MFField.register_field_header([ofproto_v1_0.NXM_OF_ETH_DST,
524                                 ofproto_v1_0.NXM_OF_ETH_DST_W])
525 class MFEthDst(MFField):
526     pack_str = MF_PACK_STRING_MAC
527
528     def __init__(self, header, value, mask=None):
529         super(MFEthDst, self).__init__(header, MFEthDst.pack_str)
530         self.value = value
531
532     @classmethod
533     def make(cls, header):
534         return cls(header, MFEthDst.pack_str)
535
536     def put(self, buf, offset, rule):
537         if rule.wc.dl_dst_mask:
538             return self.putw(buf, offset, rule.flow.dl_dst,
539                              rule.wc.dl_dst_mask)
540         else:
541             return self._put(buf, offset, rule.flow.dl_dst)
542
543
544 @_register_make
545 @_set_nxm_headers([ofproto_v1_0.NXM_OF_ETH_SRC, ofproto_v1_0.NXM_OF_ETH_SRC_W])
546 @MFField.register_field_header([ofproto_v1_0.NXM_OF_ETH_SRC,
547                                 ofproto_v1_0.NXM_OF_ETH_SRC_W])
548 class MFEthSrc(MFField):
549     pack_str = MF_PACK_STRING_MAC
550
551     def __init__(self, header, value, mask=None):
552         super(MFEthSrc, self).__init__(header, MFEthSrc.pack_str)
553         self.value = value
554
555     @classmethod
556     def make(cls, header):
557         return cls(header, MFEthSrc.pack_str)
558
559     def put(self, buf, offset, rule):
560         if rule.wc.dl_src_mask:
561             return self.putw(buf, offset, rule.flow.dl_src,
562                              rule.wc.dl_src_mask)
563         else:
564             return self._put(buf, offset, rule.flow.dl_src)
565
566
567 @_register_make
568 @_set_nxm_headers([ofproto_v1_0.NXM_OF_ETH_TYPE])
569 @MFField.register_field_header([ofproto_v1_0.NXM_OF_ETH_TYPE])
570 class MFEthType(MFField):
571     pack_str = MF_PACK_STRING_BE16
572
573     def __init__(self, header, value, mask=None):
574         super(MFEthType, self).__init__(header, MFEthType.pack_str)
575         self.value = value
576
577     @classmethod
578     def make(cls, header):
579         return cls(header, MFEthType.pack_str)
580
581     def put(self, buf, offset, rule):
582         return self._put(buf, offset, rule.flow.dl_type)
583
584
585 @_register_make
586 @_set_nxm_headers([ofproto_v1_0.NXM_OF_VLAN_TCI,
587                    ofproto_v1_0.NXM_OF_VLAN_TCI_W])
588 @MFField.register_field_header([ofproto_v1_0.NXM_OF_VLAN_TCI,
589                                 ofproto_v1_0.NXM_OF_VLAN_TCI_W])
590 class MFVlan(MFField):
591     pack_str = MF_PACK_STRING_BE16
592
593     def __init__(self, header, value, mask=None):
594         super(MFVlan, self).__init__(header, MFVlan.pack_str)
595         self.value = value
596
597     @classmethod
598     def make(cls, header):
599         return cls(header, MFVlan.pack_str)
600
601     def put(self, buf, offset, rule):
602         return self.putm(buf, offset, rule.flow.vlan_tci,
603                          rule.wc.vlan_tci_mask)
604
605
606 @_register_make
607 @_set_nxm_headers([ofproto_v1_0.NXM_OF_IP_TOS])
608 @MFField.register_field_header([ofproto_v1_0.NXM_OF_IP_TOS])
609 class MFIPDSCP(MFField):
610     pack_str = MF_PACK_STRING_8
611
612     def __init__(self, header, value, mask=None):
613         super(MFIPDSCP, self).__init__(header, MFIPDSCP.pack_str)
614         self.value = value
615
616     @classmethod
617     def make(cls, header):
618         return cls(header, MFIPDSCP.pack_str)
619
620     def put(self, buf, offset, rule):
621         return self._put(buf, offset,
622                          rule.flow.nw_tos & IP_DSCP_MASK)
623
624
625 @_register_make
626 @_set_nxm_headers([ofproto_v1_0.NXM_NX_TUN_ID,
627                    ofproto_v1_0.NXM_NX_TUN_ID_W])
628 @MFField.register_field_header([ofproto_v1_0.NXM_NX_TUN_ID,
629                                 ofproto_v1_0.NXM_NX_TUN_ID_W])
630 class MFTunId(MFField):
631     pack_str = MF_PACK_STRING_BE64
632
633     def __init__(self, header, value, mask=None):
634         super(MFTunId, self).__init__(header, MFTunId.pack_str)
635         self.value = value
636
637     @classmethod
638     def make(cls, header):
639         return cls(header, MFTunId.pack_str)
640
641     def put(self, buf, offset, rule):
642         return self.putm(buf, offset, rule.flow.tun_id, rule.wc.tun_id_mask)
643
644
645 @_register_make
646 @_set_nxm_headers([ofproto_v1_0.NXM_OF_IP_SRC, ofproto_v1_0.NXM_OF_IP_SRC_W])
647 @MFField.register_field_header([ofproto_v1_0.NXM_OF_IP_SRC,
648                                 ofproto_v1_0.NXM_OF_IP_SRC_W])
649 class MFIPSrc(MFField):
650     pack_str = MF_PACK_STRING_BE32
651
652     def __init__(self, header, value, mask=None):
653         super(MFIPSrc, self).__init__(header, MFIPSrc.pack_str)
654         self.value = value
655         self.mask = mask
656
657     @classmethod
658     def make(cls, header):
659         return cls(header, MFIPSrc.pack_str)
660
661     def put(self, buf, offset, rule):
662         return self.putm(buf, offset, rule.flow.nw_src, rule.wc.nw_src_mask)
663
664
665 @_register_make
666 @_set_nxm_headers([ofproto_v1_0.NXM_OF_IP_DST, ofproto_v1_0.NXM_OF_IP_DST_W])
667 @MFField.register_field_header([ofproto_v1_0.NXM_OF_IP_DST,
668                                 ofproto_v1_0.NXM_OF_IP_DST_W])
669 class MFIPDst(MFField):
670     pack_str = MF_PACK_STRING_BE32
671
672     def __init__(self, header, value, mask=None):
673         super(MFIPDst, self).__init__(header, MFIPDst.pack_str)
674         self.value = value
675         self.mask = mask
676
677     @classmethod
678     def make(cls, header):
679         return cls(header, MFIPDst.pack_str)
680
681     def put(self, buf, offset, rule):
682         return self.putm(buf, offset, rule.flow.nw_dst, rule.wc.nw_dst_mask)
683
684
685 @_register_make
686 @_set_nxm_headers([ofproto_v1_0.NXM_NX_IP_ECN])
687 class MFIPECN(MFField):
688     @classmethod
689     def make(cls, header):
690         return cls(header, MF_PACK_STRING_8)
691
692     def put(self, buf, offset, rule):
693         return self._put(buf, offset,
694                          rule.flow.nw_tos & IP_ECN_MASK)
695
696
697 @_register_make
698 @_set_nxm_headers([ofproto_v1_0.NXM_NX_IP_TTL])
699 class MFIPTTL(MFField):
700     @classmethod
701     def make(cls, header):
702         return cls(header, MF_PACK_STRING_8)
703
704     def put(self, buf, offset, rule):
705         return self._put(buf, offset, rule.flow.nw_ttl)
706
707
708 @_register_make
709 @_set_nxm_headers([ofproto_v1_0.NXM_OF_IP_PROTO])
710 class MFIPProto(MFField):
711     @classmethod
712     def make(cls, header):
713         return cls(header, MF_PACK_STRING_8)
714
715     def put(self, buf, offset, rule):
716         return self._put(buf, offset, rule.flow.nw_proto)
717
718
719 @_register_make
720 @_set_nxm_headers([ofproto_v1_0.NXM_OF_TCP_SRC, ofproto_v1_0.NXM_OF_TCP_SRC_W,
721                    ofproto_v1_0.NXM_OF_UDP_SRC, ofproto_v1_0.NXM_OF_UDP_SRC_W])
722 class MFTPSRC(MFField):
723     @classmethod
724     def make(cls, header):
725         return cls(header, MF_PACK_STRING_BE16)
726
727     def put(self, buf, offset, rule):
728         return self.putm(buf, offset, rule.flow.tp_src, rule.wc.tp_src_mask)
729
730
731 @_register_make
732 @_set_nxm_headers([ofproto_v1_0.NXM_OF_TCP_DST, ofproto_v1_0.NXM_OF_TCP_DST_W,
733                    ofproto_v1_0.NXM_OF_UDP_DST, ofproto_v1_0.NXM_OF_UDP_DST_W])
734 class MFTPDST(MFField):
735     @classmethod
736     def make(cls, header):
737         return cls(header, MF_PACK_STRING_BE16)
738
739     def put(self, buf, offset, rule):
740         return self.putm(buf, offset, rule.flow.tp_dst, rule.wc.tp_dst_mask)
741
742
743 @_register_make
744 @_set_nxm_headers([ofproto_v1_0.NXM_OF_ARP_SPA, ofproto_v1_0.NXM_OF_ARP_SPA_W])
745 class MFArpSpa(MFField):
746     @classmethod
747     def make(cls, header):
748         return cls(header, MF_PACK_STRING_BE32)
749
750     def put(self, buf, offset, rule):
751         return self.putm(buf, offset, rule.flow.arp_spa, rule.wc.arp_spa_mask)
752
753
754 @_register_make
755 @_set_nxm_headers([ofproto_v1_0.NXM_OF_ARP_TPA, ofproto_v1_0.NXM_OF_ARP_TPA_W])
756 class MFArpTpa(MFField):
757     @classmethod
758     def make(cls, header):
759         return cls(header, MF_PACK_STRING_BE32)
760
761     def put(self, buf, offset, rule):
762         return self.putm(buf, offset, rule.flow.arp_tpa, rule.wc.arp_tpa_mask)
763
764
765 @_register_make
766 @_set_nxm_headers([ofproto_v1_0.NXM_NX_ARP_SHA])
767 class MFArpSha(MFField):
768     @classmethod
769     def make(cls, header):
770         return cls(header, MF_PACK_STRING_MAC)
771
772     def put(self, buf, offset, rule):
773         return self._put(buf, offset, rule.flow.arp_sha)
774
775
776 class MFIPV6(object):
777     pack_str = MF_PACK_STRING_IPV6
778
779     @classmethod
780     def field_parser(cls, header, buf, offset):
781         hasmask = (header >> 8) & 1
782         if hasmask:
783             pack_string = '!' + cls.pack_str[1:] * 2
784             value = struct.unpack_from(pack_string, buf, offset + 4)
785             return cls(header, list(value[:8]), list(value[8:]))
786         else:
787             value = struct.unpack_from(cls.pack_str, buf, offset + 4)
788             return cls(header, list(value))
789
790
791 @_register_make
792 @_set_nxm_headers([ofproto_v1_0.NXM_NX_IPV6_SRC,
793                    ofproto_v1_0.NXM_NX_IPV6_SRC_W])
794 @MFField.register_field_header([ofproto_v1_0.NXM_NX_IPV6_SRC,
795                                 ofproto_v1_0.NXM_NX_IPV6_SRC_W])
796 class MFIPV6Src(MFIPV6, MFField):
797     def __init__(self, header, value, mask=None):
798         super(MFIPV6Src, self).__init__(header, MFIPV6Src.pack_str)
799         self.value = value
800         self.mask = mask
801
802     @classmethod
803     def make(cls, header):
804         return cls(header, cls.pack_str)
805
806     def put(self, buf, offset, rule):
807         return self.putv6(buf, offset,
808                           rule.flow.ipv6_src,
809                           rule.wc.ipv6_src_mask)
810
811
812 @_register_make
813 @_set_nxm_headers([ofproto_v1_0.NXM_NX_IPV6_DST,
814                    ofproto_v1_0.NXM_NX_IPV6_DST_W])
815 @MFField.register_field_header([ofproto_v1_0.NXM_NX_IPV6_DST,
816                                 ofproto_v1_0.NXM_NX_IPV6_DST_W])
817 class MFIPV6Dst(MFIPV6, MFField):
818     def __init__(self, header, value, mask=None):
819         super(MFIPV6Dst, self).__init__(header, MFIPV6Dst.pack_str)
820         self.value = value
821         self.mask = mask
822
823     @classmethod
824     def make(cls, header):
825         return cls(header, cls.pack_str)
826
827     def put(self, buf, offset, rule):
828         return self.putv6(buf, offset,
829                           rule.flow.ipv6_dst,
830                           rule.wc.ipv6_dst_mask)
831
832
833 @_register_make
834 @_set_nxm_headers([ofproto_v1_0.NXM_NX_ND_TARGET,
835                    ofproto_v1_0.NXM_NX_ND_TARGET_W])
836 class MFNdTarget(MFField):
837     @classmethod
838     def make(cls, header):
839         return cls(header, '!4I')
840
841     def put(self, buf, offset, rule):
842         return self.putv6(buf, offset,
843                           rule.flow.nd_target,
844                           rule.wc.nd_target_mask)
845
846
847 @_register_make
848 @_set_nxm_headers([ofproto_v1_0.NXM_NX_IP_FRAG,
849                    ofproto_v1_0.NXM_NX_IP_FRAG_W])
850 class MFIpFrag(MFField):
851     @classmethod
852     def make(cls, header):
853         return cls(header, '!B')
854
855     def put(self, buf, offset, rule):
856         if rule.wc.nw_frag_mask == FLOW_NW_FRAG_MASK:
857             return self._put(buf, offset, rule.flow.nw_frag)
858         else:
859             return self.putw(buf, offset, rule.flow.nw_frag,
860                              rule.wc.nw_frag_mask & FLOW_NW_FRAG_MASK)
861
862
863 @_register_make
864 @_set_nxm_headers([ofproto_v1_0.NXM_NX_ARP_THA])
865 class MFArpTha(MFField):
866     @classmethod
867     def make(cls, header):
868         return cls(header, MF_PACK_STRING_MAC)
869
870     def put(self, buf, offset, rule):
871         return self._put(buf, offset, rule.flow.arp_tha)
872
873
874 @_register_make
875 @_set_nxm_headers([ofproto_v1_0.NXM_OF_ICMP_TYPE])
876 class MFICMPType(MFField):
877     @classmethod
878     def make(cls, header):
879         return cls(header, MF_PACK_STRING_8)
880
881     def put(self, buf, offset, rule):
882         return self._put(buf, offset, rule.flow.tp_src)
883
884
885 @_register_make
886 @_set_nxm_headers([ofproto_v1_0.NXM_OF_ICMP_CODE])
887 class MFICMPCode(MFField):
888     @classmethod
889     def make(cls, header):
890         return cls(header, MF_PACK_STRING_8)
891
892     def put(self, buf, offset, rule):
893         return self._put(buf, offset, rule.flow.tp_dst)
894
895
896 @_register_make
897 @_set_nxm_headers([ofproto_v1_0.NXM_NX_ICMPV6_TYPE])
898 class MFICMPV6Type(MFField):
899     @classmethod
900     def make(cls, header):
901         return cls(header, MF_PACK_STRING_8)
902
903     def put(self, buf, offset, rule):
904         return self._put(buf, offset, rule.flow.tp_src)
905
906
907 @_register_make
908 @_set_nxm_headers([ofproto_v1_0.NXM_NX_ICMPV6_CODE])
909 class MFICMPV6Code(MFField):
910     @classmethod
911     def make(cls, header):
912         return cls(header, MF_PACK_STRING_8)
913
914     def put(self, buf, offset, rule):
915         return self._put(buf, offset, rule.flow.tp_dst)
916
917
918 @_register_make
919 @_set_nxm_headers([ofproto_v1_0.NXM_NX_IPV6_LABEL])
920 class MFICMPV6Label(MFField):
921     @classmethod
922     def make(cls, header):
923         return cls(header, MF_PACK_STRING_BE32)
924
925     def put(self, buf, offset, rule):
926         return self._put(buf, offset, rule.flow.ipv6_label)
927
928
929 @_register_make
930 @_set_nxm_headers([ofproto_v1_0.nxm_nx_reg(i) for i in range(FLOW_N_REGS)]
931                   + [ofproto_v1_0.nxm_nx_reg_w(i) for i in range(FLOW_N_REGS)])
932 class MFRegister(MFField):
933     @classmethod
934     def make(cls, header):
935         return cls(header, MF_PACK_STRING_BE32)
936
937     def put(self, buf, offset, rule):
938         for i in range(FLOW_N_REGS):
939             if (ofproto_v1_0.nxm_nx_reg(i) == self.nxm_header or
940                     ofproto_v1_0.nxm_nx_reg_w(i) == self.nxm_header):
941                 if rule.wc.regs_mask[i]:
942                     return self.putm(buf, offset, rule.flow.regs[i],
943                                      rule.wc.regs_mask[i])
944                 else:
945                     return self._put(buf, offset, rule.flow.regs[i])
946
947
948 @_register_make
949 @_set_nxm_headers([ofproto_v1_0.NXM_NX_PKT_MARK,
950                    ofproto_v1_0.NXM_NX_PKT_MARK_W])
951 class MFPktMark(MFField):
952     @classmethod
953     def make(cls, header):
954         return cls(header, MF_PACK_STRING_BE32)
955
956     def put(self, buf, offset, rule):
957         return self.putm(buf, offset, rule.flow.pkt_mark,
958                          rule.wc.pkt_mark_mask)
959
960
961 @_register_make
962 @_set_nxm_headers([ofproto_v1_0.NXM_NX_TCP_FLAGS,
963                    ofproto_v1_0.NXM_NX_TCP_FLAGS_W])
964 class MFTcpFlags(MFField):
965     @classmethod
966     def make(cls, header):
967         return cls(header, MF_PACK_STRING_BE16)
968
969     def put(self, buf, offset, rule):
970         return self.putm(buf, offset, rule.flow.tcp_flags,
971                          rule.wc.tcp_flags_mask)
972
973
974 def serialize_nxm_match(rule, buf, offset):
975     old_offset = offset
976
977     if not rule.wc.wildcards & FWW_IN_PORT:
978         offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_IN_PORT, rule)
979
980     # Ethernet.
981     if rule.flow.dl_dst != mac.DONTCARE:
982         if rule.wc.dl_dst_mask:
983             header = ofproto_v1_0.NXM_OF_ETH_DST_W
984         else:
985             header = ofproto_v1_0.NXM_OF_ETH_DST
986         offset += nxm_put(buf, offset, header, rule)
987
988     if rule.flow.dl_src != mac.DONTCARE:
989         if rule.wc.dl_src_mask:
990             header = ofproto_v1_0.NXM_OF_ETH_SRC_W
991         else:
992             header = ofproto_v1_0.NXM_OF_ETH_SRC
993         offset += nxm_put(buf, offset, header, rule)
994
995     if not rule.wc.wildcards & FWW_DL_TYPE:
996         offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_ETH_TYPE, rule)
997
998     # 802.1Q
999     if rule.wc.vlan_tci_mask != 0:
1000         if rule.wc.vlan_tci_mask == UINT16_MAX:
1001             header = ofproto_v1_0.NXM_OF_VLAN_TCI
1002         else:
1003             header = ofproto_v1_0.NXM_OF_VLAN_TCI_W
1004         offset += nxm_put(buf, offset, header, rule)
1005
1006     # L3
1007     if not rule.wc.wildcards & FWW_NW_DSCP:
1008         offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_IP_TOS, rule)
1009     if not rule.wc.wildcards & FWW_NW_ECN:
1010         offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_IP_ECN, rule)
1011     if not rule.wc.wildcards & FWW_NW_TTL:
1012         offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_IP_TTL, rule)
1013     if not rule.wc.wildcards & FWW_NW_PROTO:
1014         offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_IP_PROTO, rule)
1015
1016     if not rule.wc.wildcards & FWW_NW_PROTO and (rule.flow.nw_proto
1017                                                  == inet.IPPROTO_ICMP):
1018         if rule.wc.tp_src_mask != 0:
1019             offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_ICMP_TYPE, rule)
1020         if rule.wc.tp_dst_mask != 0:
1021             offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_ICMP_CODE, rule)
1022
1023     if rule.flow.tp_src != 0:
1024         if rule.flow.nw_proto == 6:
1025             if rule.wc.tp_src_mask == UINT16_MAX:
1026                 header = ofproto_v1_0.NXM_OF_TCP_SRC
1027             else:
1028                 header = ofproto_v1_0.NXM_OF_TCP_SRC_W
1029         elif rule.flow.nw_proto == 17:
1030             if rule.wc.tp_src_mask == UINT16_MAX:
1031                 header = ofproto_v1_0.NXM_OF_UDP_SRC
1032             else:
1033                 header = ofproto_v1_0.NXM_OF_UDP_SRC_W
1034         else:
1035             header = 0
1036         if header != 0:
1037             offset += nxm_put(buf, offset, header, rule)
1038
1039     if rule.flow.tp_dst != 0:
1040         if rule.flow.nw_proto == 6:
1041             if rule.wc.tp_dst_mask == UINT16_MAX:
1042                 header = ofproto_v1_0.NXM_OF_TCP_DST
1043             else:
1044                 header = ofproto_v1_0.NXM_OF_TCP_DST_W
1045         elif rule.flow.nw_proto == 17:
1046             if rule.wc.tp_dst_mask == UINT16_MAX:
1047                 header = ofproto_v1_0.NXM_OF_UDP_DST
1048             else:
1049                 header = ofproto_v1_0.NXM_OF_UDP_DST_W
1050         else:
1051             header = 0
1052         if header != 0:
1053             offset += nxm_put(buf, offset, header, rule)
1054
1055     if rule.flow.tcp_flags != 0:
1056         # TCP Flags can only be used if the ethernet type is IPv4 or IPv6
1057         if rule.flow.dl_type in (ether.ETH_TYPE_IP, ether.ETH_TYPE_IPV6):
1058             # TCP Flags can only be used if the ip protocol is TCP
1059             if rule.flow.nw_proto == inet.IPPROTO_TCP:
1060                 if rule.wc.tcp_flags_mask == UINT16_MAX:
1061                     header = ofproto_v1_0.NXM_NX_TCP_FLAGS
1062                 else:
1063                     header = ofproto_v1_0.NXM_NX_TCP_FLAGS_W
1064             else:
1065                 header = 0
1066         else:
1067             header = 0
1068         if header != 0:
1069             offset += nxm_put(buf, offset, header, rule)
1070
1071     # IP Source and Destination
1072     if rule.flow.nw_src != 0:
1073         if rule.wc.nw_src_mask == UINT32_MAX:
1074             header = ofproto_v1_0.NXM_OF_IP_SRC
1075         else:
1076             header = ofproto_v1_0.NXM_OF_IP_SRC_W
1077         offset += nxm_put(buf, offset, header, rule)
1078
1079     if rule.flow.nw_dst != 0:
1080         if rule.wc.nw_dst_mask == UINT32_MAX:
1081             header = ofproto_v1_0.NXM_OF_IP_DST
1082         else:
1083             header = ofproto_v1_0.NXM_OF_IP_DST_W
1084         offset += nxm_put(buf, offset, header, rule)
1085
1086     # IPv6
1087     if not rule.wc.wildcards & FWW_NW_PROTO and (rule.flow.nw_proto
1088                                                  == inet.IPPROTO_ICMPV6):
1089         if rule.wc.tp_src_mask != 0:
1090             offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_ICMPV6_TYPE,
1091                               rule)
1092         if rule.wc.tp_dst_mask != 0:
1093             offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_ICMPV6_CODE,
1094                               rule)
1095
1096     if not rule.wc.wildcards & FWW_IPV6_LABEL:
1097         offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_IPV6_LABEL, rule)
1098
1099     if len(rule.flow.ipv6_src):
1100         if len(rule.wc.ipv6_src_mask):
1101             header = ofproto_v1_0.NXM_NX_IPV6_SRC_W
1102         else:
1103             header = ofproto_v1_0.NXM_NX_IPV6_SRC
1104         offset += nxm_put(buf, offset, header, rule)
1105
1106     if len(rule.flow.ipv6_dst):
1107         if len(rule.wc.ipv6_dst_mask):
1108             header = ofproto_v1_0.NXM_NX_IPV6_DST_W
1109         else:
1110             header = ofproto_v1_0.NXM_NX_IPV6_DST
1111         offset += nxm_put(buf, offset, header, rule)
1112
1113     if len(rule.flow.nd_target):
1114         if len(rule.wc.nd_target_mask):
1115             header = ofproto_v1_0.NXM_NX_ND_TARGET_W
1116         else:
1117             header = ofproto_v1_0.NXM_NX_ND_TARGET
1118         offset += nxm_put(buf, offset, header, rule)
1119
1120     # ARP
1121     if rule.flow.arp_spa != 0:
1122         if rule.wc.arp_spa_mask == UINT32_MAX:
1123             header = ofproto_v1_0.NXM_OF_ARP_SPA
1124         else:
1125             header = ofproto_v1_0.NXM_OF_ARP_SPA_W
1126         offset += nxm_put(buf, offset, header, rule)
1127
1128     if rule.flow.arp_tpa != 0:
1129         if rule.wc.arp_tpa_mask == UINT32_MAX:
1130             header = ofproto_v1_0.NXM_OF_ARP_TPA
1131         else:
1132             header = ofproto_v1_0.NXM_OF_ARP_TPA_W
1133         offset += nxm_put(buf, offset, header, rule)
1134
1135     if not rule.wc.wildcards & FWW_ARP_SHA:
1136         offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_ARP_SHA, rule)
1137     if not rule.wc.wildcards & FWW_ARP_THA:
1138         offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_ARP_THA, rule)
1139
1140     if rule.flow.nw_frag:
1141         if rule.wc.nw_frag_mask == FLOW_NW_FRAG_MASK:
1142             header = ofproto_v1_0.NXM_NX_IP_FRAG
1143         else:
1144             header = ofproto_v1_0.NXM_NX_IP_FRAG_W
1145         offset += nxm_put(buf, offset, header, rule)
1146
1147     if rule.flow.pkt_mark != 0:
1148         if rule.wc.pkt_mark_mask == UINT32_MAX:
1149             header = ofproto_v1_0.NXM_NX_PKT_MARK
1150         else:
1151             header = ofproto_v1_0.NXM_NX_PKT_MARK_W
1152         offset += nxm_put(buf, offset, header, rule)
1153
1154     # Tunnel Id
1155     if rule.wc.tun_id_mask != 0:
1156         if rule.wc.tun_id_mask == UINT64_MAX:
1157             header = ofproto_v1_0.NXM_NX_TUN_ID
1158         else:
1159             header = ofproto_v1_0.NXM_NX_TUN_ID_W
1160         offset += nxm_put(buf, offset, header, rule)
1161
1162     # XXX: Cookie
1163
1164     for i in range(FLOW_N_REGS):
1165         if rule.wc.regs_bits & (1 << i):
1166             if rule.wc.regs_mask[i]:
1167                 header = ofproto_v1_0.nxm_nx_reg_w(i)
1168             else:
1169                 header = ofproto_v1_0.nxm_nx_reg(i)
1170             offset += nxm_put(buf, offset, header, rule)
1171
1172     # Pad
1173     pad_len = round_up(offset) - offset
1174     msg_pack_into("%dx" % pad_len, buf, offset)
1175
1176     # The returned length, the match_len, does not include the pad
1177     return offset - old_offset
1178
1179
1180 def nxm_put(buf, offset, header, rule):
1181     nxm = NXMatch(header)
1182     len_ = nxm.put_header(buf, offset)
1183     mf = mf_from_nxm_header(nxm.header)
1184     return len_ + mf.put(buf, offset + len_, rule)
1185
1186
1187 def round_up(length):
1188     return (length + 7) // 8 * 8  # Round up to a multiple of 8
1189
1190
1191 class NXMatch(object):
1192     def __init__(self, header):
1193         self.header = header
1194
1195     @classmethod
1196     def parser(cls, buf, offset, match_len):
1197         if match_len < 4:
1198             raise exception.OFPMalformedMessage
1199         (header,) = struct.unpack_from(ofproto_v1_0.NXM_HEADER_PACK_STRING,
1200                                        buf, offset)
1201         instance = cls(header)
1202         payload_len = instance.length()
1203         if payload_len == 0 or match_len < payload_len + 4:
1204             raise exception.OFPMalformedMessage
1205         return instance
1206
1207     def vendor(self):
1208         return self.header >> 16
1209
1210     def field(self):
1211         return (self.header >> 9) % 0x7f
1212
1213     def type(self):
1214         return (self.header >> 9) % 0x7fffff
1215
1216     def hasmask(self):
1217         return (self.header >> 8) & 1
1218
1219     def length(self):
1220         return self.header & 0xff
1221
1222     def show(self):
1223         return ('%08x (vendor=%x, field=%x, hasmask=%x len=%x)' %
1224                 (self.header, self.vendor(), self.field(),
1225                  self.hasmask(), self.length()))
1226
1227     def put_header(self, buf, offset):
1228         msg_pack_into(ofproto_v1_0.NXM_HEADER_PACK_STRING,
1229                       buf, offset, self.header)
1230         return struct.calcsize(ofproto_v1_0.NXM_HEADER_PACK_STRING)