1 # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 from . import packet_base
18 from ryu.lib import addrconv
20 # Slow Protocol Multicast destination
21 SLOW_PROTOCOL_MULTICAST = '01:80:c2:00:00:02'
23 # Slow Protocol SubType
24 SLOW_SUBTYPE_LACP = 0x01
25 SLOW_SUBTYPE_MARKER = 0x02
26 SLOW_SUBTYPE_OAM = 0x03
27 SLOW_SUBTYPE_OSSP = 0x0a
30 class slow(packet_base.PacketBase):
31 """Slow Protocol header decoder class.
32 This class has only the parser method.
34 http://standards.ieee.org/getieee802/download/802.3-2012_section5.pdf
36 Slow Protocols Subtypes
38 +---------------+--------------------------------------------------+
39 | Subtype Value | Protocol Name |
40 +===============+==================================================+
41 | 0 | Unused - Illegal Value |
42 +---------------+--------------------------------------------------+
43 | 1 | Link Aggregation Control Protocol(LACP) |
44 +---------------+--------------------------------------------------+
45 | 2 | Link Aggregation - Marker Protocol |
46 +---------------+--------------------------------------------------+
47 | 3 | Operations, Administration, and Maintenance(OAM) |
48 +---------------+--------------------------------------------------+
49 | 4 - 9 | Reserved for future use |
50 +---------------+--------------------------------------------------+
51 | 10 | Organization Specific Slow Protocol(OSSP) |
52 +---------------+--------------------------------------------------+
53 | 11 - 255 | Unused - Illegal values |
54 +---------------+--------------------------------------------------+
60 (subtype, ) = struct.unpack_from(cls._PACK_STR, buf)
62 SLOW_SUBTYPE_LACP: lacp,
63 # TODO: make parsers of other subtypes.
64 SLOW_SUBTYPE_MARKER: None,
65 SLOW_SUBTYPE_OAM: None,
66 SLOW_SUBTYPE_OSSP: None,
68 cls_ = switch.get(subtype)
70 return cls_.parser(buf)
72 return None, None, buf
75 class lacp(packet_base.PacketBase):
76 """Link Aggregation Control Protocol(LACP, IEEE 802.1AX)
77 header encoder/decoder class.
79 http://standards.ieee.org/getieee802/download/802.1AX-2008.pdf
83 +------------------------------------------------+--------+
84 | LACPDU structure | Octets |
85 +================================================+========+
86 | Subtype = LACP | 1 |
87 +------------------------------------------------+--------+
88 | Version Number | 1 |
89 +------------+-----------------------------------+--------+
90 | TLV | TLV_type = Actor Information | 1 |
92 +------------+-----------------------------------+--------+
93 | | Actor_Information_Length = 20 | 1 |
94 +------------+-----------------------------------+--------+
95 | | Actor_System_Priority | 2 |
96 +------------+-----------------------------------+--------+
97 | | Actor_System | 6 |
98 +------------+-----------------------------------+--------+
100 +------------+-----------------------------------+--------+
101 | | Actor_Port_Priority | 2 |
102 +------------+-----------------------------------+--------+
104 +------------+-----------------------------------+--------+
105 | | Actor_State | 1 |
106 +------------+-----------------------------------+--------+
108 +------------+-----------------------------------+--------+
109 | TLV | TLV_type = Partner Information | 1 |
111 +------------+-----------------------------------+--------+
112 | | Partner_Information_Length = 20 | 1 |
113 +------------+-----------------------------------+--------+
114 | | Partner_System_Priority | 2 |
115 +------------+-----------------------------------+--------+
116 | | Partner_System | 6 |
117 +------------+-----------------------------------+--------+
118 | | Partner_Key | 2 |
119 +------------+-----------------------------------+--------+
120 | | Partner_Port_Priority | 2 |
121 +------------+-----------------------------------+--------+
122 | | Partner_Port | 2 |
123 +------------+-----------------------------------+--------+
124 | | Partner_State | 1 |
125 +------------+-----------------------------------+--------+
127 +------------+-----------------------------------+--------+
128 | TLV | TLV_type = Collector Information | 1 |
130 +------------+-----------------------------------+--------+
131 | | Collector_Information_Length = 16 | 1 |
132 +------------+-----------------------------------+--------+
133 | | Collector_Max_Delay | 2 |
134 +------------+-----------------------------------+--------+
136 +------------+-----------------------------------+--------+
137 | TLV | TLV_type = Terminator | 1 |
139 +------------+-----------------------------------+--------+
140 | | Terminator_Length = 0 | 1 |
141 +------------+-----------------------------------+--------+
143 +------------+-----------------------------------+--------+
146 Terminator information uses a length value of 0 (0x00).
148 NOTE--The use of a Terminator_Length of 0 is intentional.
149 In TLV encoding schemes it is common practice
150 for the terminator encoding to be 0 both
151 for the type and the length.
153 Actor_State and Partner_State encoded as individual bits within
154 a single octet as follows:
156 +------+------+------+------+------+------+------+------+
157 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
158 +======+======+======+======+======+======+======+======+
159 | EXPR | DFLT | DIST | CLCT | SYNC | AGGR | TMO | ACT |
160 +------+------+------+------+------+------+------+------+
164 about the activity control value with regard to this link.
167 about the timeout control value with regard to this link.
170 about how the system regards this link from the point of view
174 about how the system regards this link from the point of view
175 of the synchronization.
178 about collecting of incoming frames.
181 about distributing of outgoing frames.
184 about the opposite system information which the system use.
187 about the expire state of the system.
189 An instance has the following attributes at least.
190 Most of them are same to the on-wire counterparts but in host byte
192 __init__ takes the corresponding args in this order.
194 .. tabularcolumns:: |l|L|
196 =============================== ====================================
197 Attribute Description
198 =============================== ====================================
199 version LACP version. This parameter must be
200 set to LACP_VERSION_NUMBER(i.e. 1).
202 actor_system_priority The priority assigned to this
205 actor_system The Actor's System ID, encoded as
208 actor_key The operational Key value assigned
209 to the port by the Actor.
211 actor_port_priority The priority assigned to this port.
213 actor_port The port number assigned to the
216 actor_state_activity .. _lacp_activity:
218 about the activity control value
219 with regard to this link.
223 LACP_STATE_PASSIVE(0)
225 actor_state_timeout .. _lacp_timeout:
227 about the timeout control value
228 with regard to this link.
230 LACP_STATE_SHORT_TIMEOUT(1)
232 LACP_STATE_LONG_TIMEOUT(0)
234 actor_state_aggregation .. _lacp_aggregation:
236 about how the system regards this
237 link from the point of view of the
240 LACP_STATE_AGGREGATEABLE(1)
242 LACP_STATE_INDIVIDUAL(0)
244 actor_state_synchronization .. _lacp_synchronization:
246 about how the system regards this
247 link from the point of view of the
250 LACP_STATE_IN_SYNC(1)
252 LACP_STATE_OUT_OF_SYNC(0)
254 actor_state_collecting .. _lacp_collecting:
256 about collecting of incoming frames.
258 LACP_STATE_COLLECTING_ENABLED(1)
260 LACP_STATE_COLLECTING_DISABLED(0)
262 actor_state_distributing .. _lacp_distributing:
264 about distributing of outgoing frames.
266 LACP_STATE_DISTRIBUTING_ENABLED(1)
268 LACP_STATE_DISTRIBUTING_DISABLED(0)
270 actor_state_defaulted .. _lacp_defaulted:
272 about the Partner information
273 which the the Actor use.
275 LACP_STATE_DEFAULTED_PARTNER(1)
277 LACP_STATE_OPERATIONAL_PARTNER(0)
279 actor_state_expired .. _lacp_expired:
281 about the state of the Actor.
283 LACP_STATE_EXPIRED(1)
285 LACP_STATE_NOT_EXPIRED(0)
287 partner_system_priority The priority assigned to the
290 partner_system The Partner's System ID, encoded
293 partner_key The operational Key value assigned
294 to the port by the Partner.
296 partner_port_priority The priority assigned to this port
299 partner_port The port number assigned to the
302 partner_state_activity See :ref:`actor_state_activity\
305 partner_state_timeout See :ref:`actor_state_timeout\
308 partner_state_aggregation See :ref:`actor_state_aggregation\
311 partner_state_synchronization See
312 :ref:`actor_state_synchronization\
313 <lacp_synchronization>`.
315 partner_state_collecting See :ref:`actor_state_collecting\
318 partner_state_distributing See :ref:`actor_state_distributing\
319 <lacp_distributing>`.
321 partner_state_defaulted See :ref:`actor_state_defaulted\
324 partner_state_expired See :ref:`actor_state_expired\
327 collector_max_delay the maximum time that the Frame
329 =============================== ====================================
332 LACP_VERSION_NUMBER = 1
335 LACP_TLV_TYPE_ACTOR = 1
336 LACP_TLV_TYPE_PARTNER = 2
337 LACP_TLV_TYPE_COLLECTOR = 3
338 LACP_TLV_TYPE_TERMINATOR = 0
340 # LACP state(LACP_Activity)
341 LACP_STATE_ACTIVE = 1
342 LACP_STATE_PASSIVE = 0
343 # LACP state(LACP_Timeout)
344 LACP_STATE_SHORT_TIMEOUT = 1
345 LACP_STATE_LONG_TIMEOUT = 0
346 # LACP state(Aggregation)
347 LACP_STATE_AGGREGATEABLE = 1
348 LACP_STATE_INDIVIDUAL = 0
349 # LACP state(Synchronization)
350 LACP_STATE_IN_SYNC = 1
351 LACP_STATE_OUT_OF_SYNC = 0
352 # LACP state(Collecting)
353 LACP_STATE_COLLECTING_ENABLED = 1
354 LACP_STATE_COLELCTING_DISABLED = 0
355 # LACP state(Distributing)
356 LACP_STATE_DISTRIBUTING_ENABLED = 1
357 LACP_STATE_DISTRIBUTING_DISABLED = 0
358 # LACP state(Defaulted)
359 LACP_STATE_DEFAULED_PARTNER = 1
360 LACP_STATE_OPERATIONAL_PARTNER = 0
361 # LACP state(Expired)
362 LACP_STATE_EXPIRED = 1
363 LACP_STATE_NOT_EXPIRED = 0
365 # The number of seconds between periodic transmissions using
367 FAST_PERIODIC_TIME = 1
368 # The number of seconds between periodic transmissions using
370 SLOW_PERIODIC_TIME = 30
371 # The number of seconds before invalidating received LACPDU
372 # information when using Short Timeouts(3 x Fast_Periodic_Time).
373 SHORT_TIMEOUT_TIME = 3 * FAST_PERIODIC_TIME
374 # The number of seconds before invalidating received LACPDU
375 # information when using Long Timeouts (3 x Slow_Periodic_Time).
376 LONG_TIMEOUT_TIME = 3 * SLOW_PERIODIC_TIME
378 _HLEN_PACK_STR = '!BB'
379 _HLEN_PACK_LEN = struct.calcsize(_HLEN_PACK_STR)
380 _ACTPRT_INFO_PACK_STR = '!BBH6sHHHB3x'
381 _ACTPRT_INFO_PACK_LEN = struct.calcsize(_ACTPRT_INFO_PACK_STR)
382 _COL_INFO_PACK_STR = '!BBH12x'
383 _COL_INFO_PACK_LEN = struct.calcsize(_COL_INFO_PACK_STR)
384 _TRM_PACK_STR = '!BB50x'
385 _TRM_PACK_LEN = struct.calcsize(_TRM_PACK_STR)
386 _ALL_PACK_LEN = _HLEN_PACK_LEN + _ACTPRT_INFO_PACK_LEN * 2 + \
387 _COL_INFO_PACK_LEN + _TRM_PACK_LEN
389 _MIN_LEN = _ALL_PACK_LEN
393 'actor_system', 'partner_system'
397 def __init__(self, version=LACP_VERSION_NUMBER,
398 actor_system_priority=0,
399 actor_system='00:00:00:00:00:00',
400 actor_key=0, actor_port_priority=0, actor_port=0,
401 actor_state_activity=0, actor_state_timeout=0,
402 actor_state_aggregation=0,
403 actor_state_synchronization=0,
404 actor_state_collecting=0, actor_state_distributing=0,
405 actor_state_defaulted=0, actor_state_expired=0,
406 partner_system_priority=0,
407 partner_system='00:00:00:00:00:00',
408 partner_key=0, partner_port_priority=0, partner_port=0,
409 partner_state_activity=0, partner_state_timeout=0,
410 partner_state_aggregation=0,
411 partner_state_synchronization=0,
412 partner_state_collecting=0,
413 partner_state_distributing=0,
414 partner_state_defaulted=0, partner_state_expired=0,
415 collector_max_delay=0):
416 super(lacp, self).__init__()
418 assert (1 == actor_state_activity | 1)
419 assert (1 == actor_state_timeout | 1)
420 assert (1 == actor_state_aggregation | 1)
421 assert (1 == actor_state_synchronization | 1)
422 assert (1 == actor_state_collecting | 1)
423 assert (1 == actor_state_distributing | 1)
424 assert (1 == actor_state_defaulted | 1)
425 assert (1 == actor_state_expired | 1)
426 assert (1 == partner_state_activity | 1)
427 assert (1 == partner_state_timeout | 1)
428 assert (1 == partner_state_aggregation | 1)
429 assert (1 == partner_state_synchronization | 1)
430 assert (1 == partner_state_collecting | 1)
431 assert (1 == partner_state_distributing | 1)
432 assert (1 == partner_state_defaulted | 1)
433 assert (1 == partner_state_expired | 1)
434 # ------------------------------
436 # ------------------------------
437 self._subtype = SLOW_SUBTYPE_LACP
438 self.version = version
439 # ------------------------------
441 # ------------------------------
442 self._actor_tag = self.LACP_TLV_TYPE_ACTOR
443 self._actor_length = self._ACTPRT_INFO_PACK_LEN
444 self.actor_system_priority = actor_system_priority
445 self.actor_system = actor_system
446 self.actor_key = actor_key
447 self.actor_port_priority = actor_port_priority
448 self.actor_port = actor_port
449 self.actor_state_activity = actor_state_activity
450 self.actor_state_timeout = actor_state_timeout
451 self.actor_state_aggregation = actor_state_aggregation
452 self.actor_state_synchronization = actor_state_synchronization
453 self.actor_state_collecting = actor_state_collecting
454 self.actor_state_distributing = actor_state_distributing
455 self.actor_state_defaulted = actor_state_defaulted
456 self.actor_state_expired = actor_state_expired
457 self._actor_state = (
458 (self.actor_state_activity << 0) |
459 (self.actor_state_timeout << 1) |
460 (self.actor_state_aggregation << 2) |
461 (self.actor_state_synchronization << 3) |
462 (self.actor_state_collecting << 4) |
463 (self.actor_state_distributing << 5) |
464 (self.actor_state_defaulted << 6) |
465 (self.actor_state_expired << 7))
466 # ------------------------------
467 # Partner Information
468 # ------------------------------
469 self._partner_tag = self.LACP_TLV_TYPE_PARTNER
470 self._partner_length = self._ACTPRT_INFO_PACK_LEN
471 self.partner_system_priority = partner_system_priority
472 self.partner_system = partner_system
473 self.partner_key = partner_key
474 self.partner_port_priority = partner_port_priority
475 self.partner_port = partner_port
476 self.partner_state_activity = partner_state_activity
477 self.partner_state_timeout = partner_state_timeout
478 self.partner_state_aggregation = partner_state_aggregation
479 self.partner_state_synchronization = \
480 partner_state_synchronization
481 self.partner_state_collecting = partner_state_collecting
482 self.partner_state_distributing = partner_state_distributing
483 self.partner_state_defaulted = partner_state_defaulted
484 self.partner_state_expired = partner_state_expired
485 self._partner_state = (
486 (self.partner_state_activity << 0) |
487 (self.partner_state_timeout << 1) |
488 (self.partner_state_aggregation << 2) |
489 (self.partner_state_synchronization << 3) |
490 (self.partner_state_collecting << 4) |
491 (self.partner_state_distributing << 5) |
492 (self.partner_state_defaulted << 6) |
493 (self.partner_state_expired << 7))
494 # ------------------------------
495 # Collector Information
496 # ------------------------------
497 self._collector_tag = self.LACP_TLV_TYPE_COLLECTOR
498 self._collector_length = self._COL_INFO_PACK_LEN
499 self.collector_max_delay = collector_max_delay
500 # ------------------------------
502 # ------------------------------
503 self._terminator_tag = self.LACP_TLV_TYPE_TERMINATOR
504 self._terminator_length = 0
507 def parser(cls, buf):
508 assert cls._ALL_PACK_LEN == len(buf)
510 # ------------------------------
512 # ------------------------------
514 ) = struct.unpack_from(cls._HLEN_PACK_STR, buf, offset)
515 assert SLOW_SUBTYPE_LACP == subtype
516 assert cls.LACP_VERSION_NUMBER == version
517 offset += cls._HLEN_PACK_LEN
518 # ------------------------------
520 # ------------------------------
521 (actor_tag, actor_length, actor_system_priority, actor_system,
522 actor_key, actor_port_priority, actor_port, actor_state
523 ) = struct.unpack_from(cls._ACTPRT_INFO_PACK_STR, buf, offset)
524 assert cls.LACP_TLV_TYPE_ACTOR == actor_tag
525 assert cls._ACTPRT_INFO_PACK_LEN == actor_length
526 offset += cls._ACTPRT_INFO_PACK_LEN
527 actor_state_activity = (actor_state >> 0) & 1
528 actor_state_timeout = (actor_state >> 1) & 1
529 actor_state_aggregation = (actor_state >> 2) & 1
530 actor_state_synchronization = (actor_state >> 3) & 1
531 actor_state_collecting = (actor_state >> 4) & 1
532 actor_state_distributing = (actor_state >> 5) & 1
533 actor_state_defaulted = (actor_state >> 6) & 1
534 actor_state_expired = (actor_state >> 7) & 1
535 # ------------------------------
536 # Partner Information
537 # ------------------------------
538 (partner_tag, partner_length, partner_system_priority,
539 partner_system, partner_key, partner_port_priority,
540 partner_port, partner_state
541 ) = struct.unpack_from(cls._ACTPRT_INFO_PACK_STR, buf, offset)
542 assert cls.LACP_TLV_TYPE_PARTNER == partner_tag
543 assert cls._ACTPRT_INFO_PACK_LEN == partner_length
544 offset += cls._ACTPRT_INFO_PACK_LEN
545 partner_state_activity = (partner_state >> 0) & 1
546 partner_state_timeout = (partner_state >> 1) & 1
547 partner_state_aggregation = (partner_state >> 2) & 1
548 partner_state_synchronization = (partner_state >> 3) & 1
549 partner_state_collecting = (partner_state >> 4) & 1
550 partner_state_distributing = (partner_state >> 5) & 1
551 partner_state_defaulted = (partner_state >> 6) & 1
552 partner_state_expired = (partner_state >> 7) & 1
553 # ------------------------------
554 # Collector Information
555 # ------------------------------
556 (collector_tag, collector_length, collector_max_delay
557 ) = struct.unpack_from(cls._COL_INFO_PACK_STR, buf, offset)
558 assert cls.LACP_TLV_TYPE_COLLECTOR == collector_tag
559 assert cls._COL_INFO_PACK_LEN == collector_length
560 offset += cls._COL_INFO_PACK_LEN
561 # ------------------------------
562 # Terminator Information
563 # ------------------------------
564 (terminator_tag, terminator_length
565 ) = struct.unpack_from(cls._TRM_PACK_STR, buf, offset)
566 assert cls.LACP_TLV_TYPE_TERMINATOR == terminator_tag
567 assert 0 == terminator_length
569 actor_system_priority,
570 addrconv.mac.bin_to_text(actor_system),
571 actor_key, actor_port_priority,
572 actor_port, actor_state_activity,
573 actor_state_timeout, actor_state_aggregation,
574 actor_state_synchronization, actor_state_collecting,
575 actor_state_distributing, actor_state_defaulted,
576 actor_state_expired, partner_system_priority,
577 addrconv.mac.bin_to_text(partner_system),
578 partner_key, partner_port_priority,
579 partner_port, partner_state_activity,
580 partner_state_timeout, partner_state_aggregation,
581 partner_state_synchronization,
582 partner_state_collecting, partner_state_distributing,
583 partner_state_defaulted, partner_state_expired,
584 collector_max_delay), None, buf[lacp._ALL_PACK_LEN:]
586 def serialize(self, payload, prev):
587 header = struct.pack(self._HLEN_PACK_STR, self._subtype,
589 actor = struct.pack(self._ACTPRT_INFO_PACK_STR,
590 self._actor_tag, self._actor_length,
591 self.actor_system_priority,
592 addrconv.mac.text_to_bin(self.actor_system),
594 self.actor_port_priority, self.actor_port,
596 partner = struct.pack(self._ACTPRT_INFO_PACK_STR,
597 self._partner_tag, self._partner_length,
598 self.partner_system_priority,
599 addrconv.mac.text_to_bin(self.partner_system),
601 self.partner_port_priority,
602 self.partner_port, self._partner_state)
603 collector = struct.pack(self._COL_INFO_PACK_STR,
605 self._collector_length,
606 self.collector_max_delay)
607 terminator = struct.pack(self._TRM_PACK_STR,
608 self._terminator_tag,
609 self._terminator_length)
610 return header + actor + partner + collector + terminator