1 # Copyright (c) 2009-2013, Exa Networks Limited
2 # Copyright (c) 2009-2013, Thomas Mangin
3 # Copyright (c) 2015-2017 Cumulus Networks, Inc.
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are met:
9 # Redistributions of source code must retain the above copyright notice, this
10 # list of conditions and the following disclaimer.
12 # Redistributions in binary form must reproduce the above copyright notice,
13 # this list of conditions and the following disclaimer in the documentation
14 # and/or other materials provided with the distribution.
16 # The names of the Exa Networks Limited, Cumulus Networks, Inc. nor the names
17 # of its contributors may be used to endorse or promote products derived from
18 # this software without specific prior written permission.
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
26 # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 from ipaddr
import IPv4Address
, IPv6Address
, IPAddress
34 from binascii
import hexlify
35 from pprint
import pformat
36 from socket
import AF_UNSPEC
, AF_INET
, AF_INET6
, AF_BRIDGE
, htons
37 from string
import printable
38 from struct
import pack
, unpack
, calcsize
40 log
= logging
.getLogger(__name__
)
41 SYSLOG_EXTRA_DEBUG
= 5
44 # Interface name buffer size #define IFNAMSIZ 16 (kernel source)
45 IF_NAME_SIZE
= 15 # 15 because python doesn't have \0
47 # Netlink message types
53 RTM_NEWLINK
= 0x10 # Create a new network interface
54 RTM_DELLINK
= 0x11 # Destroy a network interface
55 RTM_GETLINK
= 0x12 # Retrieve information about a network interface(ifinfomsg)
77 # Netlink message flags
78 NLM_F_REQUEST
= 0x01 # It is query message.
79 NLM_F_MULTI
= 0x02 # Multipart message, terminated by NLMSG_DONE
80 NLM_F_ACK
= 0x04 # Reply with ack, with zero or error code
81 NLM_F_ECHO
= 0x08 # Echo this query
83 # Modifiers to GET query
84 NLM_F_ROOT
= 0x100 # specify tree root
85 NLM_F_MATCH
= 0x200 # return all matching
86 NLM_F_DUMP
= NLM_F_ROOT | NLM_F_MATCH
87 NLM_F_ATOMIC
= 0x400 # atomic GET
89 # Modifiers to NEW query
90 NLM_F_REPLACE
= 0x100 # Override existing
91 NLM_F_EXCL
= 0x200 # Do not touch, if it exists
92 NLM_F_CREATE
= 0x400 # Create, if it does not exist
93 NLM_F_APPEND
= 0x800 # Add to end of list
96 NLA_F_NET_BYTEORDER
= 0x4000
97 NLA_TYPE_MASK
= ~
(NLA_F_NESTED | NLA_F_NET_BYTEORDER
)
104 RTMGRP_IPV4_IFADDR
= 0x10
105 RTMGRP_IPV4_MROUTE
= 0x20
106 RTMGRP_IPV4_ROUTE
= 0x40
107 RTMGRP_IPV4_RULE
= 0x80
108 RTMGRP_IPV6_IFADDR
= 0x100
109 RTMGRP_IPV6_MROUTE
= 0x200
110 RTMGRP_IPV6_ROUTE
= 0x400
111 RTMGRP_IPV6_IFINFO
= 0x800
112 RTMGRP_DECnet_IFADDR
= 0x1000
113 RTMGRP_DECnet_ROUTE
= 0x4000
114 RTMGRP_IPV6_PREFIX
= 0x20000
116 RTMGRP_ALL
= (RTMGRP_LINK | RTMGRP_NOTIFY | RTMGRP_NEIGH | RTMGRP_TC |
117 RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_MROUTE | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_RULE |
118 RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_MROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFINFO |
119 RTMGRP_DECnet_IFADDR | RTMGRP_DECnet_ROUTE |
129 for family
in [attr
for attr
in dir(socket
) if attr
.startswith('AF_')]:
130 AF_FAMILY
[getattr(socket
, family
)] = family
132 AF_FAMILY
[AF_MPLS
] = 'AF_MPLS'
135 def get_family_str(family
):
136 return AF_FAMILY
.get(family
, 'UNKNOWN')
144 value_to_bool_dict
= {
162 def set_log_level(level
):
166 def zfilled_hex(value
, digits
):
167 return '0x' + hex(value
)[2:].zfill(digits
)
170 def remove_trailing_null(line
):
172 Remove the last character if it is a NULL...having that NULL
173 causes python to print a garbage character
176 if ord(line
[-1]) == 0:
182 def mac_int_to_str(mac_int
):
184 Return an integer in MAC string format
187 # [2:] to remove the leading 0x, then fill out to 12 zeroes, then uppercase
188 all_caps
= hex(int(mac_int
))[2:].zfill(12).upper()
190 if all_caps
[-1] == 'L':
191 all_caps
= all_caps
[:-1]
192 all_caps
= all_caps
.zfill(12).upper()
194 return "%s.%s.%s" % (all_caps
[0:4], all_caps
[4:8], all_caps
[8:12])
197 def data_to_color_text(line_number
, color
, data
, extra
=''):
198 (c1
, c2
, c3
, c4
) = unpack('BBBB', data
[0:4])
201 for c
in (c1
, c2
, c3
, c4
):
204 if char_c
in printable
[:-5]:
205 in_ascii
.append(char_c
)
210 return ' %2d: \033[%dm0x%02x%02x%02x%02x\033[0m %s %s' % (line_number
, color
, c1
, c2
, c3
, c4
, ''.join(in_ascii
), extra
)
212 return ' %2d: 0x%02x%02x%02x%02x %s %s' % (line_number
, c1
, c2
, c3
, c4
, ''.join(in_ascii
), extra
)
215 def padded_length(length
):
216 return int((length
+ 3) / 4) * 4
219 class Attribute(object):
221 def __init__(self
, atype
, string
, logger
):
224 self
.HEADER_PACK
= '=HH'
225 self
.HEADER_LEN
= calcsize(self
.HEADER_PACK
)
230 self
.net_byteorder
= False
236 def set_value(self
, value
):
239 def set_nested(self
, nested
):
242 def set_net_byteorder(self
, net_byteorder
):
243 self
.net_byteorder
= net_byteorder
245 def pad_bytes_needed(self
, length
):
247 Return the number of bytes that should be added to align on a 4-byte boundry
249 remainder
= length
% 4
256 def pad(self
, length
, raw
):
257 pad
= self
.pad_bytes_needed(length
)
267 raise Exception('Please define an encode() method in your child attribute class, or do not use AttributeGeneric')
269 length
= self
.HEADER_LEN
+ self
.LEN
270 attr_type_with_flags
= self
.atype
273 attr_type_with_flags
= attr_type_with_flags | NLA_F_NESTED
275 if self
.net_byteorder
:
276 attr_type_with_flags
= attr_type_with_flags | NLA_F_NET_BYTEORDER
278 raw
= pack(self
.HEADER_PACK
, length
, attr_type_with_flags
) + pack(self
.PACK
, self
.value
)
279 raw
= self
.pad(length
, raw
)
282 def decode_length_type(self
, data
):
284 The first two bytes of an attribute are the length, the next two bytes are the type
287 prev_atype
= self
.atype
288 (data1
, data2
) = unpack(self
.HEADER_PACK
, data
[:self
.HEADER_LEN
])
289 self
.length
= int(data1
)
290 self
.atype
= int(data2
)
291 self
.attr_end
= padded_length(self
.length
)
293 self
.nested
= True if self
.atype
& NLA_F_NESTED
else False
294 self
.net_byteorder
= True if self
.atype
& NLA_F_NET_BYTEORDER
else False
295 self
.atype
= self
.atype
& NLA_TYPE_MASK
297 # Should never happen
298 assert self
.atype
== prev_atype
, "This object changes attribute type from %d to %d, this is bad" % (prev_atype
, self
.atype
)
300 def dump_first_line(self
, dump_buffer
, line_number
, color
):
302 Add the "Length....Type..." line to the dump buffer
304 if self
.attr_end
== self
.length
:
307 padded_to
= ' padded to %d, ' % self
.attr_end
309 extra
= 'Length %s (%d)%sType %s%s%s (%d) %s' % \
310 (zfilled_hex(self
.length
, 4), self
.length
,
312 zfilled_hex(self
.atype
, 4),
313 " (NLA_F_NESTED set)" if self
.nested
else "",
314 " (NLA_F_NET_BYTEORDER set)" if self
.net_byteorder
else "",
318 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[0:4], extra
))
319 return line_number
+ 1
321 def dump_lines(self
, dump_buffer
, line_number
, color
):
322 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
324 for x
in xrange(1, self
.attr_end
/4):
327 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], ''))
332 def get_pretty_value(self
, obj
=None):
333 if obj
and callable(obj
):
334 return obj(self
.value
)
338 class AttributeFourByteList(Attribute
):
340 def __init__(self
, atype
, string
, family
, logger
):
341 Attribute
.__init
__(self
, atype
, string
, logger
)
343 def decode(self
, parent_msg
, data
):
344 self
.decode_length_type(data
)
345 wordcount
= (self
.attr_end
- 4)/4
346 self
.PACK
= '=%dL' % wordcount
347 self
.LEN
= calcsize(self
.PACK
)
350 self
.value
= unpack(self
.PACK
, self
.data
[4:])
352 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
355 def dump_lines(self
, dump_buffer
, line_number
, color
):
356 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
358 for val
in self
.value
:
359 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4*idx
:4*(idx
+1)], val
))
365 class AttributeFourByteValue(Attribute
):
367 def __init__(self
, atype
, string
, family
, logger
):
368 Attribute
.__init
__(self
, atype
, string
, logger
)
370 self
.LEN
= calcsize(self
.PACK
)
372 def decode(self
, parent_msg
, data
):
373 self
.decode_length_type(data
)
374 assert self
.attr_end
== 8, "Attribute length for %s must be 8, it is %d" % (self
, self
.attr_end
)
377 self
.value
= int(unpack(self
.PACK
, self
.data
[4:])[0])
379 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
382 def dump_lines(self
, dump_buffer
, line_number
, color
):
383 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
384 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
385 return line_number
+ 1
388 class AttributeTwoByteValue(Attribute
):
390 def __init__(self
, atype
, string
, family
, logger
):
391 Attribute
.__init
__(self
, atype
, string
, logger
)
393 self
.LEN
= calcsize(self
.PACK
)
395 def decode(self
, parent_msg
, data
):
396 self
.decode_length_type(data
)
397 assert self
.attr_end
== 8, "Attribute length for %s must be 8, it is %d" % (self
, self
.attr_end
)
400 self
.value
= int(unpack(self
.PACK
, self
.data
[4:8])[0])
402 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:6])))
406 length
= self
.HEADER_LEN
+ self
.LEN
407 raw
= pack(self
.HEADER_PACK
, length
-2, self
.atype
) + pack(self
.PACK
, self
.value
)
408 raw
= self
.pad(length
, raw
)
411 def dump_lines(self
, dump_buffer
, line_number
, color
):
412 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
413 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
414 return line_number
+ 1
417 class AttributeString(Attribute
):
419 def __init__(self
, atype
, string
, family
, logger
):
420 Attribute
.__init
__(self
, atype
, string
, logger
)
425 # some interface names come from JSON as unicode strings
426 # and cannot be packed as is so we must convert them to strings
427 if isinstance(self
.value
, unicode):
428 self
.value
= str(self
.value
)
429 self
.PACK
= '%ds' % len(self
.value
)
430 self
.LEN
= calcsize(self
.PACK
)
432 length
= self
.HEADER_LEN
+ self
.LEN
433 raw
= pack(self
.HEADER_PACK
, length
, self
.atype
) + pack(self
.PACK
, self
.value
)
434 raw
= self
.pad(length
, raw
)
437 def decode(self
, parent_msg
, data
):
438 self
.decode_length_type(data
)
439 self
.PACK
= '%ds' % (self
.length
- 4)
440 self
.LEN
= calcsize(self
.PACK
)
443 self
.value
= remove_trailing_null(unpack(self
.PACK
, self
.data
[4:self
.length
])[0])
445 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:self
.length
])))
449 class AttributeStringInterfaceName(AttributeString
):
451 def __init__(self
, atype
, string
, family
, logger
):
452 AttributeString
.__init
__(self
, atype
, string
, family
, logger
)
454 def set_value(self
, value
):
455 if value
and len(value
) > IF_NAME_SIZE
:
456 raise Exception('interface name exceeds max length of %d' % IF_NAME_SIZE
)
460 class AttributeIPAddress(Attribute
):
462 def __init__(self
, atype
, string
, family
, logger
):
463 Attribute
.__init
__(self
, atype
, string
, logger
)
464 self
.value_int
= None
465 self
.value_int_str
= None
468 if self
.family
== AF_INET
:
471 elif self
.family
== AF_INET6
:
474 elif self
.family
== AF_BRIDGE
:
478 raise Exception("%s is not a supported address family" % self
.family
)
480 self
.LEN
= calcsize(self
.PACK
)
482 def set_value(self
, value
):
486 self
.value
= IPAddress(value
)
488 def decode(self
, parent_msg
, data
):
489 self
.decode_length_type(data
)
492 if self
.family
== AF_INET
:
493 self
.value
= IPv4Address(unpack(self
.PACK
, self
.data
[4:])[0])
495 elif self
.family
== AF_INET6
:
496 (data1
, data2
) = unpack(self
.PACK
, self
.data
[4:])
497 self
.value
= IPv6Address(data1
<< 64 | data2
)
499 elif self
.family
== AF_BRIDGE
:
500 self
.value
= IPv4Address(unpack(self
.PACK
, self
.data
[4:])[0])
502 self
.value_int
= int(self
.value
)
503 self
.value_int_str
= str(self
.value_int
)
507 self
.value_int
= None
508 self
.value_int_str
= None
509 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
513 length
= self
.HEADER_LEN
+ self
.LEN
515 if self
.family
not in [AF_INET
, AF_INET6
, AF_BRIDGE
]:
516 raise Exception("%s is not a supported address family" % self
.family
)
518 raw
= pack(self
.HEADER_PACK
, length
, self
.atype
) + self
.value
.packed
519 raw
= self
.pad(length
, raw
)
522 def dump_lines(self
, dump_buffer
, line_number
, color
):
523 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
525 if self
.family
== AF_INET
:
526 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
529 elif self
.family
== AF_INET6
:
531 for x
in xrange(1, self
.attr_end
/4):
534 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], self
.value
))
537 elif self
.family
== AF_BRIDGE
:
538 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
544 class AttributeMACAddress(Attribute
):
546 def __init__(self
, atype
, string
, family
, logger
):
547 Attribute
.__init
__(self
, atype
, string
, logger
)
549 self
.LEN
= calcsize(self
.PACK
)
551 def decode(self
, parent_msg
, data
):
552 self
.decode_length_type(data
)
554 # IFLA_ADDRESS and IFLA_BROADCAST attributes for all interfaces has been a
555 # 6-byte MAC address. But the GRE interface uses a 4-byte IP address and
556 # GREv6 uses a 16-byte IPv6 address for this attribute.
558 # GRE interface uses a 4-byte IP address for this attribute
560 self
.value
= IPv4Address(unpack('>L', self
.data
[4:])[0])
561 self
.value_int
= int(self
.value
)
562 self
.value_int_str
= str(self
.value_int
)
564 elif self
.length
== 10:
565 (data1
, data2
) = unpack(self
.PACK
, self
.data
[4:])
566 self
.value
= mac_int_to_str(data1
<< 16 | data2
)
567 # GREv6 interface uses a 16-byte IP address for this attribute
568 elif self
.length
== 20:
569 self
.value
= IPv6Address(unpack('>L', self
.data
[16:])[0])
570 self
.value_int
= int(self
.value
)
571 self
.value_int_str
= str(self
.value_int
)
573 raise Exception("Length of MACAddress attribute not supported: %d" % self
.length
)
576 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
580 length
= self
.HEADER_LEN
+ self
.LEN
581 mac_raw
= int(self
.value
.replace('.', '').replace(':', ''), 16)
582 raw
= pack(self
.HEADER_PACK
, length
-2, self
.atype
) + pack(self
.PACK
, mac_raw
>> 16, mac_raw
& 0x0000FFFF)
583 raw
= self
.pad(length
, raw
)
586 def dump_lines(self
, dump_buffer
, line_number
, color
):
587 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
588 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
590 if len(self
.data
) >= 12:
591 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[8:12]))
596 class AttributeMplsLabel(Attribute
):
598 def __init__(self
, atype
, string
, family
, logger
):
599 Attribute
.__init
__(self
, atype
, string
, logger
)
600 self
.value_int
= None
601 self
.value_int_str
= None
605 def decode(self
, parent_msg
, data
):
606 self
.decode_length_type(data
)
609 (label_high
, label_low_tc_s
, self
.ttl
) = unpack(self
.PACK
, self
.data
[4:])
610 self
.s_bit
= label_low_tc_s
& 0x1
611 self
.traffic_class
= ((label_low_tc_s
& 0xf) >> 1)
612 self
.label
= (label_high
<< 4) |
(label_low_tc_s
>> 4)
613 self
.value
= self
.label
614 self
.value_int
= self
.value
615 self
.value_int_str
= str(self
.value_int
)
619 self
.value_int
= None
620 self
.value_int_str
= None
621 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
624 def dump_lines(self
, dump_buffer
, line_number
, color
):
625 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
626 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8],
627 'label %s, TC %s, bottom-of-stack %s, TTL %d' %
628 (self
.label
, self
.traffic_class
, self
.s_bit
, self
.ttl
)))
634 class AttributeGeneric(Attribute
):
636 def __init__(self
, atype
, string
, family
, logger
):
637 Attribute
.__init
__(self
, atype
, string
, logger
)
641 def decode(self
, parent_msg
, data
):
642 self
.decode_length_type(data
)
643 wordcount
= (self
.attr_end
- 4)/4
644 self
.PACK
= '=%dL' % wordcount
645 self
.LEN
= calcsize(self
.PACK
)
648 self
.value
= ''.join(map(str, unpack(self
.PACK
, self
.data
[4:])))
650 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
654 class AttributeOneByteValue(AttributeGeneric
):
656 def __init__(self
, atype
, string
, family
, logger
):
657 AttributeGeneric
.__init
__(self
, atype
, string
, family
, logger
)
659 self
.LEN
= calcsize(self
.PACK
)
661 def decode(self
, parent_msg
, data
):
662 self
.decode_length_type(data
)
663 assert self
.attr_end
== 8, "Attribute length for %s must be 8, it is %d" % (self
, self
.attr_end
)
666 self
.value
= int(unpack(self
.PACK
, self
.data
[4:8])[0])
668 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:5])))
672 length
= self
.HEADER_LEN
+ self
.LEN
673 raw
= pack(self
.HEADER_PACK
, length
-3, self
.atype
) + pack(self
.PACK
, self
.value
)
674 raw
= self
.pad(length
, raw
)
677 def dump_lines(self
, dump_buffer
, line_number
, color
):
678 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
679 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
680 return line_number
+ 1
683 class AttributeIFLA_AF_SPEC(Attribute
):
685 value will be a dictionary such as:
687 Link.IFLA_BRIDGE_FLAGS: flags,
688 Link.IFLA_BRIDGE_VLAN_INFO: (vflags, vlanid)
691 def __init__(self
, atype
, string
, family
, logger
):
692 Attribute
.__init
__(self
, atype
, string
, logger
)
696 pack_layout
= [self
.HEADER_PACK
]
697 payload
= [0, self
.atype | NLA_F_NESTED
]
698 attr_length_index
= 0
700 # For now this assumes that all data will be packed in the native endian
701 # order (=). If a field is added that needs to be packed via network
702 # order (>) then some smarts will need to be added to split the pack_layout
703 # string at the >, split the payload and make the needed pack() calls.
705 # Until we cross that bridge though we will keep things nice and simple and
706 # pack everything via a single pack() call.
709 for (sub_attr_type
, sub_attr_value
) in self
.value
.iteritems():
711 if sub_attr_type
== Link
.IFLA_BRIDGE_FLAGS
:
712 sub_attr_to_add
.append((sub_attr_type
, sub_attr_value
))
714 elif sub_attr_type
== Link
.IFLA_BRIDGE_VLAN_INFO
:
715 for (vlan_flag
, vlan_id
) in sub_attr_value
:
716 sub_attr_to_add
.append((sub_attr_type
, (vlan_flag
, vlan_id
)))
719 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_AF_SPEC sub-attribute type %d' % sub_attr_type
)
722 for (sub_attr_type
, sub_attr_value
) in sub_attr_to_add
:
723 sub_attr_pack_layout
= ['=', 'HH']
724 sub_attr_payload
= [0, sub_attr_type
]
725 sub_attr_length_index
= 0
727 if sub_attr_type
== Link
.IFLA_BRIDGE_FLAGS
:
728 sub_attr_pack_layout
.append('H')
729 sub_attr_payload
.append(sub_attr_value
)
731 elif sub_attr_type
== Link
.IFLA_BRIDGE_VLAN_INFO
:
732 sub_attr_pack_layout
.append('HH')
733 sub_attr_payload
.append(sub_attr_value
[0])
734 sub_attr_payload
.append(sub_attr_value
[1])
736 sub_attr_length
= calcsize(''.join(sub_attr_pack_layout
))
737 sub_attr_payload
[sub_attr_length_index
] = sub_attr_length
740 for x
in xrange(self
.pad_bytes_needed(sub_attr_length
)):
741 sub_attr_pack_layout
.append('x')
743 # The [1:] is to remove the leading = so that when we do the ''.join() later
744 # we do not end up with an = in the middle of the pack layout string. There
745 # will be an = at the beginning via self.HEADER_PACK
746 sub_attr_pack_layout
= sub_attr_pack_layout
[1:]
748 # Now extend the ovarall attribute pack_layout/payload to include this sub-attribute
749 pack_layout
.extend(sub_attr_pack_layout
)
750 payload
.extend(sub_attr_payload
)
752 pack_layout
= ''.join(pack_layout
)
754 # Fill in the length field
755 length
= calcsize(pack_layout
)
756 payload
[attr_length_index
] = length
758 raw
= pack(pack_layout
, *payload
)
759 raw
= self
.pad(length
, raw
)
762 def decode(self
, parent_msg
, data
):
764 value is a dictionary such as:
766 Link.IFLA_BRIDGE_FLAGS: flags,
767 Link.IFLA_BRIDGE_VLAN_INFO: (vflags, vlanid)
771 The encoding of the IFLA_AF_SPEC attribute varies depending on the family
772 used for the request (RTM_GETLINK) message. For AF_UNSPEC the encoding
773 has another level of nesting for each address family with the type encoded
775 af_spec = nla_nest_start(skb, IFLA_AF_SPEC)
777 af = nla_nest_start(skb, af_ops->family)
778 af_ops->fill_link_af(skb, dev, ext_filter_mask)
782 This allows the parser to find the address family by looking at the first
785 Whereas AF_BRIDGE encoding is just:
786 af_spec = nla_nest_start(skb, IFLA_AF_SPEC)
787 br_fill_ifvlaninfo{_compressed}(skb, vg)
790 which means the parser can not use the attribute itself to know the family
791 to which the attribute belongs.
793 /include/uapi/linux/if_link.h
796 * Contains nested attributes for address family specific attributes.
797 * Each address family may create a attribute with the address family
798 * number as type and create its own attribute structure in it.
803 * [IFLA_INET_CONF] = ...,
806 * [IFLA_INET6_FLAGS] = ...,
807 * [IFLA_INET6_CONF] = ...,
813 self
.decode_length_type(data
)
819 (sub_attr_length
, sub_attr_type
) = unpack('=HH', data
[:4])
820 sub_attr_end
= padded_length(sub_attr_length
)
822 if not sub_attr_length
:
823 self
.log
.error('parsed a zero length sub-attr')
826 sub_attr_data
= data
[4:sub_attr_end
]
828 if self
.family
== AF_BRIDGE
:
829 if sub_attr_type
== Link
.IFLA_BRIDGE_FLAGS
:
830 self
.value
[Link
.IFLA_BRIDGE_FLAGS
] = unpack("=H", sub_attr_data
[0:2])[0]
832 elif sub_attr_type
== Link
.IFLA_BRIDGE_VLAN_INFO
:
833 if Link
.IFLA_BRIDGE_VLAN_INFO
not in self
.value
:
834 self
.value
[Link
.IFLA_BRIDGE_VLAN_INFO
] = []
835 self
.value
[Link
.IFLA_BRIDGE_VLAN_INFO
].append(tuple(unpack("=HH", sub_attr_data
[0:4])))
838 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_AF_SPEC sub-attribute '
839 'type %s (%d), length %d, padded to %d' %
840 (parent_msg
.get_ifla_bridge_af_spec_to_string(sub_attr_type
),
841 sub_attr_type
, sub_attr_length
, sub_attr_end
))
843 elif self
.family
== AF_UNSPEC
:
845 if sub_attr_type
== AF_INET6
:
849 (inet6_attr_length
, inet6_attr_type
) = unpack('=HH', sub_attr_data
[:4])
850 inet6_attr_end
= padded_length(inet6_attr_length
)
853 if inet6_attr_type
== Link
.IFLA_INET6_ADDR_GEN_MODE
:
854 inet6_attr
[inet6_attr_type
] = unpack('=B', sub_attr_data
[4])[0]
855 # nlmanager doesn't support multiple kernel version
856 # all the other attributes like IFLA_INET6_CONF are
857 # based on DEVCONF_MAX from _UAPI_IPV6_H.
858 # we can opti the code and break this loop once we
859 # found the attribute that we are interested in.
860 # It's not really worth going through all the other
861 # attributes to log that we don't support them yet
866 'Add support for decoding AF_INET6 IFLA_AF_SPEC '
867 'sub-attribute type %s (%d), length %d, padded to %d'
869 parent_msg
.get_ifla_inet6_af_spec_to_string(inet6_attr_type
),
870 inet6_attr_type
, inet6_attr_length
, inet6_attr_end
874 sub_attr_data
= sub_attr_data
[inet6_attr_end
:]
875 self
.value
[AF_INET6
] = inet6_attr
877 self
.value
[sub_attr_type
] = {}
879 # Uncomment the following block to implement the AF_INET attributes
880 # see Link.get_ifla_inet_af_spec_to_string (dict)
881 #elif sub_attr_type == AF_INET:
884 # while sub_attr_data:
885 # (inet_attr_length, inet_attr_type) = unpack('=HH', sub_attr_data[:4])
886 # inet_attr_end = padded_length(inet_attr_length)
889 # # SYSLOG_EXTRA_DEBUG,
890 # 'Add support for decoding AF_INET IFLA_AF_SPEC '
891 # 'sub-attribute type %s (%d), length %d, padded to %d'
893 # parent_msg.get_ifla_inet_af_spec_to_string(inet_attr_type),
894 # inet_attr_type, inet_attr_length, inet_attr_end
898 # sub_attr_data = sub_attr_data[inet_attr_end:]
900 # self.value[AF_INET] = inet_attr
902 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_AF_SPEC sub-attribute '
903 'family %d, length %d, padded to %d'
904 % (self
.family
, sub_attr_length
, sub_attr_end
))
906 data
= data
[sub_attr_end
:]
908 def dump_lines(self
, dump_buffer
, line_number
, color
):
909 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
912 next_sub_attr_line
= 0
915 for x
in xrange(1, self
.attr_end
/4):
919 if line_number
== next_sub_attr_line
:
923 sub_attr_line
= False
925 (sub_attr_length
, sub_attr_type
) = unpack('=HH', self
.data
[start
:start
+4])
926 sub_attr_end
= padded_length(sub_attr_length
)
928 next_sub_attr_line
= line_number
+ (sub_attr_end
/4)
930 if sub_attr_end
== sub_attr_length
:
933 padded_to
= ' padded to %d,' % sub_attr_end
935 if self
.family
== AF_BRIDGE
:
936 extra
= 'Nested Attribute - Length %s (%d)%s Type %s (%d) %s' % \
937 (zfilled_hex(sub_attr_length
, 4), sub_attr_length
,
939 zfilled_hex(sub_attr_type
, 4), sub_attr_type
,
940 Link
.ifla_bridge_af_spec_to_string
.get(sub_attr_type
))
941 elif self
.family
== AF_UNSPEC
:
942 if sub_attr_type
== AF_INET6
:
944 elif sub_attr_type
== AF_INET
:
947 family
= 'Unsupported family %d' % sub_attr_type
949 extra
= 'Nested Attribute Structure for %s - Length %s (%d)%s Type %s (%d)' % (
950 family
, zfilled_hex(sub_attr_length
, 4), sub_attr_length
, padded_to
,
951 zfilled_hex(sub_attr_type
, 4), sub_attr_type
,
956 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], extra
))
961 def get_pretty_value(self
, obj
=None):
963 if obj
and callable(obj
):
964 return obj(self
.value
)
966 # We do this so we can print a more human readable dictionary
967 # with the names of the nested keys instead of their numbers
970 if self
.family
== AF_BRIDGE
:
971 for (sub_key
, sub_value
) in self
.value
.iteritems():
972 sub_key_pretty
= "(%2d) %s" % (sub_key
, Link
.ifla_bridge_af_spec_to_string
.get(sub_key
))
973 value_pretty
[sub_key_pretty
] = sub_value
974 elif self
.family
== AF_UNSPEC
:
975 for (family
, family_attr
) in self
.value
.iteritems():
976 family_value_pretty
= {}
978 if family
== AF_INET6
:
979 family_af_spec_to_string
= Link
.ifla_inet6_af_spec_to_string
980 elif family
== AF_INET
:
981 family_af_spec_to_string
= Link
.ifla_inet_af_spec_to_string
983 continue # log error?
985 for (sub_key
, sub_value
) in family_attr
.iteritems():
986 sub_key_pretty
= "(%2d) %s" % (sub_key
, family_af_spec_to_string
.get(sub_key
))
987 family_value_pretty
[sub_key_pretty
] = sub_value
988 value_pretty
= family_value_pretty
994 class AttributeRTA_MULTIPATH(Attribute
):
996 /* RTA_MULTIPATH --- array of struct rtnexthop.
998 * "struct rtnexthop" describes all necessary nexthop information,
999 * i.e. parameters of path to a destination via this nexthop.
1001 * At the moment it is impossible to set different prefsrc, mtu, window
1002 * and rtt for different paths from multipath.
1006 unsigned short rtnh_len;
1007 unsigned char rtnh_flags;
1008 unsigned char rtnh_hops;
1013 def __init__(self
, atype
, string
, family
, logger
):
1014 Attribute
.__init
__(self
, atype
, string
, logger
)
1015 self
.family
= family
1018 self
.RTNH_PACK
= '=HBBL' # rtnh_len, flags, hops, ifindex
1019 self
.RTNH_LEN
= calcsize(self
.RTNH_PACK
)
1025 # Calculate the length
1026 if self
.family
== AF_INET
:
1027 ip_len
= self
.IPV4_LEN
1028 elif self
.family
== AF_INET6
:
1029 ip_len
= self
.IPV6_LEN
1032 length
= self
.HEADER_LEN
+ ((self
.RTNH_LEN
+ self
.HEADER_LEN
+ ip_len
) * len(self
.value
))
1033 raw
= pack(self
.HEADER_PACK
, length
, self
.atype
)
1037 rtnh_len
= self
.RTNH_LEN
+ self
.HEADER_LEN
+ ip_len
1039 for (nexthop
, rtnh_ifindex
) in self
.value
:
1042 raw
+= pack(self
.RTNH_PACK
, rtnh_len
, rtnh_flags
, rtnh_hops
, rtnh_ifindex
)
1045 raw
+= pack(self
.HEADER_PACK
, self
.HEADER_LEN
+ ip_len
, Route
.RTA_GATEWAY
)
1047 if self
.family
== AF_INET
:
1048 raw
+= pack('>L', nexthop
)
1049 elif self
.family
== AF_INET6
:
1050 raw
+= pack('>QQ', nexthop
>> 64, nexthop
& 0x0000000000000000FFFFFFFFFFFFFFFF)
1052 raw
= self
.pad(length
, raw
)
1055 def decode(self
, parent_msg
, data
):
1056 self
.decode_length_type(data
)
1059 data
= self
.data
[4:]
1062 (rtnh_len
, rtnh_flags
, rtnh_hops
, rtnh_ifindex
) = unpack(self
.RTNH_PACK
, data
[:self
.RTNH_LEN
])
1063 data
= data
[self
.RTNH_LEN
:]
1065 (attr_type
, attr_length
) = unpack(self
.HEADER_PACK
, self
.data
[:self
.HEADER_LEN
])
1066 data
= data
[self
.HEADER_LEN
:]
1068 if self
.family
== AF_INET
:
1069 if len(data
) < self
.IPV4_LEN
:
1071 nexthop
= IPv4Address(unpack('>L', data
[:self
.IPV4_LEN
])[0])
1072 self
.value
.append((nexthop
, rtnh_ifindex
, rtnh_flags
, rtnh_hops
))
1074 elif self
.family
== AF_INET6
:
1075 if len(data
) < self
.IPV6_LEN
:
1077 (data1
, data2
) = unpack('>QQ', data
[:self
.IPV6_LEN
])
1078 nexthop
= IPv6Address(data1
<< 64 | data2
)
1079 self
.value
.append((nexthop
, rtnh_ifindex
, rtnh_flags
, rtnh_hops
))
1081 data
= data
[(rtnh_len
-self
.RTNH_LEN
-self
.HEADER_LEN
):]
1083 self
.value
= tuple(self
.value
)
1086 class AttributeIFLA_LINKINFO(Attribute
):
1088 value is a dictionary such as:
1091 Link.IFLA_INFO_KIND : 'vlan',
1092 Link.IFLA_INFO_DATA : {
1093 Link.IFLA_VLAN_ID : vlanid,
1097 def __init__(self
, atype
, string
, family
, logger
):
1098 Attribute
.__init
__(self
, atype
, string
, logger
)
1101 pack_layout
= [self
.HEADER_PACK
]
1102 payload
= [0, self
.atype | NLA_F_NESTED
]
1103 attr_length_index
= 0
1105 kind
= self
.value
.get(Link
.IFLA_INFO_KIND
)
1106 slave_kind
= self
.value
.get(Link
.IFLA_INFO_SLAVE_KIND
)
1108 if not slave_kind
and kind
not in ('vlan', 'macvlan', 'vxlan', 'bond', 'bridge', 'xfrm'):
1109 raise Exception('Unsupported IFLA_INFO_KIND %s' % kind
)
1110 elif not kind
and slave_kind
!= 'bridge':
1111 # only support brport for now.
1112 raise Exception('Unsupported IFLA_INFO_SLAVE_KIND %s' % slave_kind
)
1114 # For now this assumes that all data will be packed in the native endian
1115 # order (=). If a field is added that needs to be packed via network
1116 # order (>) then some smarts will need to be added to split the pack_layout
1117 # string at the >, split the payload and make the needed pack() calls.
1119 # Until we cross that bridge though we will keep things nice and simple and
1120 # pack everything via a single pack() call.
1121 for (sub_attr_type
, sub_attr_value
) in self
.value
.iteritems():
1122 sub_attr_pack_layout
= ['=', 'HH']
1123 sub_attr_payload
= [0, sub_attr_type
]
1124 sub_attr_length_index
= 0
1126 if sub_attr_type
== Link
.IFLA_INFO_KIND
:
1127 sub_attr_pack_layout
.append('%ds' % len(sub_attr_value
))
1128 sub_attr_payload
.append(sub_attr_value
)
1130 elif sub_attr_type
== Link
.IFLA_INFO_DATA
:
1132 sub_attr_payload
= [0, sub_attr_type | NLA_F_NESTED
]
1134 for (info_data_type
, info_data_value
) in sub_attr_value
.iteritems():
1137 if info_data_type
== Link
.IFLA_VLAN_ID
:
1138 sub_attr_pack_layout
.append('HH')
1139 sub_attr_payload
.append(6) # length
1140 sub_attr_payload
.append(info_data_type
)
1143 sub_attr_pack_layout
.append('H')
1144 sub_attr_payload
.append(info_data_value
)
1147 sub_attr_pack_layout
.extend('xx')
1149 elif info_data_type
== Link
.IFLA_VLAN_PROTOCOL
:
1150 sub_attr_pack_layout
.append('HH')
1151 sub_attr_payload
.append(6) # length
1152 sub_attr_payload
.append(info_data_type
)
1155 vlan_protocol
= Link
.ifla_vlan_protocol_dict
.get(info_data_value
)
1156 if not vlan_protocol
:
1157 raise NotImplementedError('vlan protocol %s not implemented' % info_data_value
)
1159 sub_attr_pack_layout
.append('H')
1160 sub_attr_payload
.append(htons(vlan_protocol
))
1163 sub_attr_pack_layout
.extend('xx')
1165 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA vlan sub-attribute type %d' % info_data_type
)
1167 elif kind
== 'macvlan':
1168 if info_data_type
== Link
.IFLA_MACVLAN_MODE
:
1169 sub_attr_pack_layout
.append('HH')
1170 sub_attr_payload
.append(8) # length
1171 sub_attr_payload
.append(info_data_type
)
1174 sub_attr_pack_layout
.append('L')
1175 sub_attr_payload
.append(info_data_value
)
1178 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA macvlan sub-attribute type %d' % info_data_type
)
1180 elif kind
== 'xfrm':
1181 if info_data_type
in (Link
.IFLA_XFRM_IF_ID
, Link
.IFLA_XFRM_LINK
):
1182 sub_attr_pack_layout
.append('HH')
1183 sub_attr_payload
.append(8) # length
1184 sub_attr_payload
.append(info_data_type
)
1186 sub_attr_pack_layout
.append('L')
1187 sub_attr_payload
.append(info_data_value
)
1189 elif kind
== 'vxlan':
1190 if info_data_type
in (Link
.IFLA_VXLAN_ID
,
1191 Link
.IFLA_VXLAN_LINK
,
1192 Link
.IFLA_VXLAN_AGEING
,
1193 Link
.IFLA_VXLAN_LIMIT
,
1194 Link
.IFLA_VXLAN_PORT_RANGE
):
1195 sub_attr_pack_layout
.append('HH')
1196 sub_attr_payload
.append(8) # length
1197 sub_attr_payload
.append(info_data_type
)
1199 sub_attr_pack_layout
.append('L')
1200 sub_attr_payload
.append(info_data_value
)
1202 elif info_data_type
in (Link
.IFLA_VXLAN_GROUP
,
1203 Link
.IFLA_VXLAN_LOCAL
):
1204 sub_attr_pack_layout
.append('HH')
1205 sub_attr_payload
.append(8) # length
1206 sub_attr_payload
.append(info_data_type
)
1208 sub_attr_pack_layout
.append('L')
1210 reorder
= unpack('<L', IPv4Address(info_data_value
).packed
)[0]
1211 sub_attr_payload
.append(IPv4Address(reorder
))
1213 elif info_data_type
in (Link
.IFLA_VXLAN_PORT
,):
1214 sub_attr_pack_layout
.append('HH')
1215 sub_attr_payload
.append(6)
1216 sub_attr_payload
.append(info_data_type
)
1218 sub_attr_pack_layout
.append('H')
1221 swaped
= pack(">H", info_data_value
)
1222 sub_attr_payload
.append(unpack("<H", swaped
)[0])
1224 sub_attr_pack_layout
.extend('xx')
1226 elif info_data_type
in (Link
.IFLA_VXLAN_TTL
,
1227 Link
.IFLA_VXLAN_TOS
,
1228 Link
.IFLA_VXLAN_LEARNING
,
1229 Link
.IFLA_VXLAN_PROXY
,
1230 Link
.IFLA_VXLAN_RSC
,
1231 Link
.IFLA_VXLAN_L2MISS
,
1232 Link
.IFLA_VXLAN_L3MISS
,
1233 Link
.IFLA_VXLAN_UDP_CSUM
,
1234 Link
.IFLA_VXLAN_UDP_ZERO_CSUM6_TX
,
1235 Link
.IFLA_VXLAN_UDP_ZERO_CSUM6_RX
,
1236 Link
.IFLA_VXLAN_REMCSUM_TX
,
1237 Link
.IFLA_VXLAN_REMCSUM_RX
,
1238 Link
.IFLA_VXLAN_REPLICATION_TYPE
):
1239 sub_attr_pack_layout
.append('HH')
1240 sub_attr_payload
.append(5)
1241 sub_attr_payload
.append(info_data_type
)
1243 sub_attr_pack_layout
.append('B')
1244 sub_attr_payload
.append(info_data_value
)
1245 sub_attr_pack_layout
.extend('xxx')
1248 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA vxlan sub-attribute type %d' % info_data_type
)
1250 elif kind
== 'bond':
1251 if info_data_type
in (Link
.IFLA_BOND_AD_ACTOR_SYSTEM
, ):
1252 sub_attr_pack_layout
.append('HH')
1253 sub_attr_payload
.append(10) # length
1254 sub_attr_payload
.append(info_data_type
)
1256 sub_attr_pack_layout
.append('6B')
1257 for mbyte
in info_data_value
.replace('.', ' ').replace(':', ' ').split():
1258 sub_attr_payload
.append(int(mbyte
, 16))
1259 sub_attr_pack_layout
.extend('xx')
1261 elif info_data_type
== Link
.IFLA_BOND_AD_ACTOR_SYS_PRIO
:
1262 sub_attr_pack_layout
.append('HH')
1263 sub_attr_payload
.append(6) # length
1264 sub_attr_payload
.append(info_data_type
)
1267 sub_attr_pack_layout
.append('H')
1268 sub_attr_payload
.append(int(info_data_value
))
1271 sub_attr_pack_layout
.extend('xx')
1273 elif info_data_type
== Link
.IFLA_BOND_NUM_PEER_NOTIF
:
1274 sub_attr_pack_layout
.append('HH')
1275 sub_attr_payload
.append(5) # length
1276 sub_attr_payload
.append(info_data_type
)
1279 sub_attr_pack_layout
.append('B')
1280 sub_attr_payload
.append(int(info_data_value
))
1283 sub_attr_pack_layout
.extend('xxx')
1286 elif info_data_type
in (Link
.IFLA_BOND_AD_LACP_RATE
,
1287 Link
.IFLA_BOND_AD_LACP_BYPASS
,
1288 Link
.IFLA_BOND_USE_CARRIER
):
1289 # converts yes/no/on/off/0/1 strings to boolean value
1290 bool_value
= self
.get_bool_value(info_data_value
)
1292 sub_attr_pack_layout
.append('HH')
1293 sub_attr_payload
.append(5) # length
1294 sub_attr_payload
.append(info_data_type
)
1297 sub_attr_pack_layout
.append('B')
1298 sub_attr_payload
.append(bool_value
)
1301 sub_attr_pack_layout
.extend('xxx')
1303 elif info_data_type
== Link
.IFLA_BOND_XMIT_HASH_POLICY
:
1304 index
= self
.get_index(Link
.ifla_bond_xmit_hash_policy_tbl
,
1305 'bond xmit hash policy',
1308 sub_attr_pack_layout
.append('HH')
1309 sub_attr_payload
.append(5) # length
1310 sub_attr_payload
.append(info_data_type
)
1313 sub_attr_pack_layout
.append('B')
1314 sub_attr_payload
.append(index
)
1317 sub_attr_pack_layout
.extend('xxx')
1319 elif info_data_type
== Link
.IFLA_BOND_MODE
:
1320 index
= self
.get_index(Link
.ifla_bond_mode_tbl
,
1324 sub_attr_pack_layout
.append('HH')
1325 sub_attr_payload
.append(5) # length
1326 sub_attr_payload
.append(info_data_type
)
1329 sub_attr_pack_layout
.append('B')
1330 sub_attr_payload
.append(index
)
1333 sub_attr_pack_layout
.extend('xxx')
1335 elif info_data_type
in (Link
.IFLA_BOND_MIIMON
,
1336 Link
.IFLA_BOND_UPDELAY
,
1337 Link
.IFLA_BOND_DOWNDELAY
,
1338 Link
.IFLA_BOND_MIN_LINKS
):
1339 sub_attr_pack_layout
.append('HH')
1340 sub_attr_payload
.append(8) # length
1341 sub_attr_payload
.append(info_data_type
)
1343 sub_attr_pack_layout
.append('L')
1344 sub_attr_payload
.append(int(info_data_value
))
1347 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA bond sub-attribute type %d' % info_data_type
)
1349 elif kind
== 'bridge':
1350 if info_data_type
== Link
.IFLA_BR_VLAN_PROTOCOL
:
1351 sub_attr_pack_layout
.append('HH')
1352 sub_attr_payload
.append(6) # length
1353 sub_attr_payload
.append(info_data_type
)
1356 vlan_protocol
= Link
.ifla_vlan_protocol_dict
.get(info_data_value
)
1357 if not vlan_protocol
:
1358 raise NotImplementedError('vlan protocol %s not implemented' % info_data_value
)
1360 sub_attr_pack_layout
.append('H')
1361 sub_attr_payload
.append(htons(vlan_protocol
))
1364 sub_attr_pack_layout
.extend('xx')
1367 elif info_data_type
in (Link
.IFLA_BR_VLAN_FILTERING
,
1368 Link
.IFLA_BR_TOPOLOGY_CHANGE
,
1369 Link
.IFLA_BR_TOPOLOGY_CHANGE_DETECTED
,
1370 Link
.IFLA_BR_MCAST_ROUTER
,
1371 Link
.IFLA_BR_MCAST_SNOOPING
,
1372 Link
.IFLA_BR_MCAST_QUERY_USE_IFADDR
,
1373 Link
.IFLA_BR_MCAST_QUERIER
,
1374 Link
.IFLA_BR_NF_CALL_IPTABLES
,
1375 Link
.IFLA_BR_NF_CALL_IP6TABLES
,
1376 Link
.IFLA_BR_NF_CALL_ARPTABLES
,
1377 Link
.IFLA_BR_VLAN_STATS_ENABLED
,
1378 Link
.IFLA_BR_MCAST_STATS_ENABLED
,
1379 Link
.IFLA_BR_MCAST_IGMP_VERSION
,
1380 Link
.IFLA_BR_MCAST_MLD_VERSION
):
1381 sub_attr_pack_layout
.append('HH')
1382 sub_attr_payload
.append(5) # length
1383 sub_attr_payload
.append(info_data_type
)
1386 sub_attr_pack_layout
.append('B')
1387 sub_attr_payload
.append(int(info_data_value
))
1390 sub_attr_pack_layout
.extend('xxx')
1393 elif info_data_type
in (Link
.IFLA_BR_PRIORITY
,
1394 Link
.IFLA_BR_GROUP_FWD_MASK
,
1395 Link
.IFLA_BR_ROOT_PORT
,
1396 Link
.IFLA_BR_VLAN_DEFAULT_PVID
):
1397 sub_attr_pack_layout
.append('HH')
1398 sub_attr_payload
.append(6) # length
1399 sub_attr_payload
.append(info_data_type
)
1402 sub_attr_pack_layout
.append('H')
1403 sub_attr_payload
.append(int(info_data_value
))
1406 sub_attr_pack_layout
.extend('xx')
1409 elif info_data_type
in (Link
.IFLA_BR_FORWARD_DELAY
,
1410 Link
.IFLA_BR_HELLO_TIME
,
1411 Link
.IFLA_BR_MAX_AGE
,
1412 Link
.IFLA_BR_AGEING_TIME
,
1413 Link
.IFLA_BR_STP_STATE
,
1414 Link
.IFLA_BR_ROOT_PATH_COST
,
1415 Link
.IFLA_BR_MCAST_QUERIER
,
1416 Link
.IFLA_BR_MCAST_HASH_ELASTICITY
,
1417 Link
.IFLA_BR_MCAST_HASH_MAX
,
1418 Link
.IFLA_BR_MCAST_LAST_MEMBER_CNT
,
1419 Link
.IFLA_BR_MCAST_STARTUP_QUERY_CNT
):
1420 sub_attr_pack_layout
.append('HH')
1421 sub_attr_payload
.append(8) # length
1422 sub_attr_payload
.append(info_data_type
)
1424 sub_attr_pack_layout
.append('L')
1425 sub_attr_payload
.append(int(info_data_value
))
1428 elif info_data_type
in (Link
.IFLA_BR_MCAST_LAST_MEMBER_INTVL
,
1429 Link
.IFLA_BR_MCAST_MEMBERSHIP_INTVL
,
1430 Link
.IFLA_BR_MCAST_QUERIER_INTVL
,
1431 Link
.IFLA_BR_MCAST_QUERY_INTVL
,
1432 Link
.IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
,
1433 Link
.IFLA_BR_MCAST_STARTUP_QUERY_INTVL
):
1434 sub_attr_pack_layout
.append('HH')
1435 sub_attr_payload
.append(12) # length
1436 sub_attr_payload
.append(info_data_type
)
1438 sub_attr_pack_layout
.append('Q')
1439 sub_attr_payload
.append(int(info_data_value
))
1442 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA bridge sub-attribute type %d' % info_data_type
)
1444 elif sub_attr_type
== Link
.IFLA_INFO_SLAVE_DATA
:
1446 sub_attr_payload
= [0, sub_attr_type | NLA_F_NESTED
]
1448 for (info_slave_data_type
, info_slave_data_value
) in sub_attr_value
.iteritems():
1450 if slave_kind
== 'bridge':
1453 if info_slave_data_type
in (Link
.IFLA_BRPORT_STATE
,
1454 Link
.IFLA_BRPORT_MODE
,
1455 Link
.IFLA_BRPORT_GUARD
,
1456 Link
.IFLA_BRPORT_PROTECT
,
1457 Link
.IFLA_BRPORT_FAST_LEAVE
,
1458 Link
.IFLA_BRPORT_LEARNING
,
1459 Link
.IFLA_BRPORT_UNICAST_FLOOD
,
1460 Link
.IFLA_BRPORT_PROXYARP
,
1461 Link
.IFLA_BRPORT_LEARNING_SYNC
,
1462 Link
.IFLA_BRPORT_PROXYARP_WIFI
,
1463 Link
.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
,
1464 Link
.IFLA_BRPORT_CONFIG_PENDING
,
1465 Link
.IFLA_BRPORT_MULTICAST_ROUTER
,
1466 Link
.IFLA_BRPORT_MCAST_FLOOD
,
1467 Link
.IFLA_BRPORT_MCAST_TO_UCAST
,
1468 Link
.IFLA_BRPORT_VLAN_TUNNEL
,
1469 Link
.IFLA_BRPORT_BCAST_FLOOD
,
1470 Link
.IFLA_BRPORT_PEER_LINK
,
1471 Link
.IFLA_BRPORT_DUAL_LINK
,
1472 Link
.IFLA_BRPORT_ARP_SUPPRESS
,
1473 Link
.IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
):
1474 sub_attr_pack_layout
.append('HH')
1475 sub_attr_payload
.append(5) # length
1476 sub_attr_payload
.append(info_slave_data_type
)
1479 sub_attr_pack_layout
.append('B')
1480 sub_attr_payload
.append(int(info_slave_data_value
))
1483 sub_attr_pack_layout
.extend('xxx')
1486 elif info_slave_data_type
in (Link
.IFLA_BRPORT_PRIORITY
,
1487 Link
.IFLA_BRPORT_DESIGNATED_PORT
,
1488 Link
.IFLA_BRPORT_DESIGNATED_COST
,
1489 Link
.IFLA_BRPORT_ID
,
1490 Link
.IFLA_BRPORT_NO
,
1491 Link
.IFLA_BRPORT_GROUP_FWD_MASK
,
1492 Link
.IFLA_BRPORT_GROUP_FWD_MASKHI
):
1493 sub_attr_pack_layout
.append('HH')
1494 sub_attr_payload
.append(6) # length
1495 sub_attr_payload
.append(info_slave_data_type
)
1498 sub_attr_pack_layout
.append('H')
1499 sub_attr_payload
.append(int(info_slave_data_value
))
1502 sub_attr_pack_layout
.extend('xx')
1505 elif info_slave_data_type
== Link
.IFLA_BRPORT_COST
:
1506 sub_attr_pack_layout
.append('HH')
1507 sub_attr_payload
.append(8) # length
1508 sub_attr_payload
.append(info_slave_data_type
)
1510 sub_attr_pack_layout
.append('L')
1511 sub_attr_payload
.append(int(info_slave_data_value
))
1514 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_SLAVE_DATA bond sub-attribute type %d' % info_slave_data_type
)
1517 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_LINKINFO kind %s' % slave_kind
)
1520 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_LINKINFO sub-attribute type %d' % sub_attr_type
)
1523 sub_attr_length
= calcsize(''.join(sub_attr_pack_layout
))
1524 sub_attr_payload
[sub_attr_length_index
] = sub_attr_length
1527 for x
in xrange(self
.pad_bytes_needed(sub_attr_length
)):
1528 sub_attr_pack_layout
.append('x')
1530 # The [1:] is to remove the leading = so that when we do the ''.join() later
1531 # we do not end up with an = in the middle of the pack layout string. There
1532 # will be an = at the beginning via self.HEADER_PACK
1533 sub_attr_pack_layout
= sub_attr_pack_layout
[1:]
1535 # Now extend the ovarall attribute pack_layout/payload to include this sub-attribute
1536 pack_layout
.extend(sub_attr_pack_layout
)
1537 payload
.extend(sub_attr_payload
)
1539 pack_layout
= ''.join(pack_layout
)
1541 # Fill in the length field
1542 length
= calcsize(pack_layout
)
1543 payload
[attr_length_index
] = length
1545 raw
= pack(pack_layout
, *payload
)
1546 raw
= self
.pad(length
, raw
)
1549 def get_bool_value(self
, value
, default
=None):
1551 return value_to_bool_dict
[value
]
1553 self
.log
.debug('%s: unsupported boolean value' % value
)
1556 def get_index(self
, tbl
, attr
, value
, default
=None):
1560 self
.log
.debug('unsupported %s value %s (%s)' % (attr
, value
, tbl
.keys()))
1563 def decode(self
, parent_msg
, data
):
1565 value is a dictionary such as:
1568 Link.IFLA_INFO_KIND : 'vlan',
1569 Link.IFLA_INFO_DATA : {
1570 Link.IFLA_VLAN_ID : vlanid,
1574 self
.decode_length_type(data
)
1577 data
= self
.data
[4:]
1579 # IFLA_MACVLAN_MODE and IFLA_VLAN_ID both have a value of 1 and both are
1580 # valid IFLA_INFO_DATA entries :( The sender must TX IFLA_INFO_KIND
1581 # first in order for us to know if "1" is IFLA_MACVLAN_MODE vs IFLA_VLAN_ID.
1584 (sub_attr_length
, sub_attr_type
) = unpack('=HH', data
[:4])
1585 sub_attr_end
= padded_length(sub_attr_length
)
1587 if not sub_attr_length
:
1588 self
.log
.error('parsed a zero length sub-attr')
1591 if sub_attr_type
in (Link
.IFLA_INFO_KIND
, Link
.IFLA_INFO_SLAVE_KIND
):
1592 self
.value
[sub_attr_type
] = remove_trailing_null(unpack('%ds' % (sub_attr_length
- 4), data
[4:sub_attr_length
])[0])
1594 elif sub_attr_type
== Link
.IFLA_INFO_SLAVE_DATA
:
1595 sub_attr_data
= data
[4:sub_attr_end
]
1597 ifla_info_slave_data
= dict()
1598 ifla_info_slave_kind
= self
.value
.get(Link
.IFLA_INFO_SLAVE_KIND
)
1600 if not ifla_info_slave_kind
:
1601 self
.log
.warning('IFLA_INFO_SLAVE_KIND is not known...we cannot parse IFLA_INFO_SLAVE_DATA')
1603 while sub_attr_data
:
1604 (info_data_length
, info_data_type
) = unpack('=HH', sub_attr_data
[:4])
1605 info_data_end
= padded_length(info_data_length
)
1607 if ifla_info_slave_kind
== 'bridge':
1609 if info_data_type
in (Link
.IFLA_BRPORT_STATE
,
1610 Link
.IFLA_BRPORT_MODE
,
1611 Link
.IFLA_BRPORT_GUARD
,
1612 Link
.IFLA_BRPORT_PROTECT
,
1613 Link
.IFLA_BRPORT_FAST_LEAVE
,
1614 Link
.IFLA_BRPORT_LEARNING
,
1615 Link
.IFLA_BRPORT_UNICAST_FLOOD
,
1616 Link
.IFLA_BRPORT_PROXYARP
,
1617 Link
.IFLA_BRPORT_LEARNING_SYNC
,
1618 Link
.IFLA_BRPORT_PROXYARP_WIFI
,
1619 Link
.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
,
1620 Link
.IFLA_BRPORT_CONFIG_PENDING
,
1621 Link
.IFLA_BRPORT_MULTICAST_ROUTER
,
1622 Link
.IFLA_BRPORT_MCAST_FLOOD
,
1623 Link
.IFLA_BRPORT_MCAST_TO_UCAST
,
1624 Link
.IFLA_BRPORT_VLAN_TUNNEL
,
1625 Link
.IFLA_BRPORT_PEER_LINK
,
1626 Link
.IFLA_BRPORT_DUAL_LINK
,
1627 Link
.IFLA_BRPORT_ARP_SUPPRESS
,
1628 Link
.IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
):
1629 ifla_info_slave_data
[info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1632 elif info_data_type
in (Link
.IFLA_BRPORT_PRIORITY
,
1633 Link
.IFLA_BRPORT_DESIGNATED_PORT
,
1634 Link
.IFLA_BRPORT_DESIGNATED_COST
,
1635 Link
.IFLA_BRPORT_ID
,
1636 Link
.IFLA_BRPORT_NO
,
1637 Link
.IFLA_BRPORT_GROUP_FWD_MASK
,
1638 Link
.IFLA_BRPORT_GROUP_FWD_MASKHI
):
1639 ifla_info_slave_data
[info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1642 elif info_data_type
== Link
.IFLA_BRPORT_COST
:
1643 ifla_info_slave_data
[info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1645 elif ifla_info_slave_kind
== 'bond':
1648 if info_data_type
in (
1649 Link
.IFLA_BOND_SLAVE_STATE
,
1650 Link
.IFLA_BOND_SLAVE_MII_STATUS
,
1651 Link
.IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE
,
1652 Link
.IFLA_BOND_SLAVE_AD_RX_BYPASS
,
1654 ifla_info_slave_data
[info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1657 elif info_data_type
in (
1658 Link
.IFLA_BOND_SLAVE_QUEUE_ID
,
1659 Link
.IFLA_BOND_SLAVE_AD_AGGREGATOR_ID
1661 ifla_info_slave_data
[info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1664 elif info_data_type
== (
1665 Link
.IFLA_BOND_SLAVE_PERM_HWADDR
,
1666 Link
.IFLA_BOND_SLAVE_LINK_FAILURE_COUNT
1668 ifla_info_slave_data
[info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1670 except Exception as e
:
1671 self
.log
.debug('%s: attribute %s: %s'
1672 % (self
.value
[Link
.IFLA_INFO_SLAVE_KIND
],
1675 sub_attr_data
= sub_attr_data
[info_data_end
:]
1677 self
.value
[Link
.IFLA_INFO_SLAVE_DATA
] = ifla_info_slave_data
1679 elif sub_attr_type
== Link
.IFLA_INFO_DATA
:
1680 sub_attr_data
= data
[4:sub_attr_end
]
1681 self
.value
[Link
.IFLA_INFO_DATA
] = {}
1683 ifla_info_kind
= self
.value
.get(Link
.IFLA_INFO_KIND
)
1684 if not ifla_info_kind
:
1685 self
.log
.warning('IFLA_INFO_KIND is not known...we cannot parse IFLA_INFO_DATA')
1687 while sub_attr_data
:
1688 (info_data_length
, info_data_type
) = unpack('=HH', sub_attr_data
[:4])
1689 info_data_end
= padded_length(info_data_length
)
1691 if ifla_info_kind
== 'vlan':
1692 if info_data_type
== Link
.IFLA_VLAN_ID
:
1693 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1695 elif info_data_type
== Link
.IFLA_VLAN_PROTOCOL
:
1696 hex_value
= '0x%s' % sub_attr_data
[4:6].encode('hex')
1697 vlan_protocol
= Link
.ifla_vlan_protocol_dict
.get(int(hex_value
, base
=16))
1700 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = vlan_protocol
1702 self
.log
.warning('IFLA_VLAN_PROTOCOL: cannot decode vlan protocol %s' % hex_value
)
1705 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND vlan type %s (%d), length %d, padded to %d' %
1706 (parent_msg
.get_ifla_vlan_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1708 elif ifla_info_kind
== 'macvlan':
1709 if info_data_type
== Link
.IFLA_MACVLAN_MODE
:
1710 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1712 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND macvlan type %s (%d), length %d, padded to %d' %
1713 (parent_msg
.get_ifla_macvlan_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1715 elif ifla_info_kind
== 'xfrm':
1717 if info_data_type
in (Link
.IFLA_XFRM_IF_ID
, Link
.IFLA_XFRM_LINK
):
1718 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1720 elif ifla_info_kind
== 'vxlan':
1723 if info_data_type
in (Link
.IFLA_VXLAN_GROUP
,
1724 Link
.IFLA_VXLAN_LOCAL
):
1725 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = IPv4Address(unpack('>L', sub_attr_data
[4:8])[0])
1728 elif info_data_type
in (Link
.IFLA_VXLAN_ID
,
1729 Link
.IFLA_VXLAN_LINK
,
1730 Link
.IFLA_VXLAN_AGEING
,
1731 Link
.IFLA_VXLAN_LIMIT
,
1732 Link
.IFLA_VXLAN_PORT_RANGE
):
1733 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1736 elif info_data_type
in (Link
.IFLA_VXLAN_PORT
, ):
1737 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('!H', sub_attr_data
[4:6])[0]
1738 # The form '!' is available for those poor souls who claim they can't
1739 # remember whether network byte order is big-endian or little-endian.
1742 elif info_data_type
in (Link
.IFLA_VXLAN_TTL
,
1743 Link
.IFLA_VXLAN_TOS
,
1744 Link
.IFLA_VXLAN_LEARNING
,
1745 Link
.IFLA_VXLAN_PROXY
,
1746 Link
.IFLA_VXLAN_RSC
,
1747 Link
.IFLA_VXLAN_L2MISS
,
1748 Link
.IFLA_VXLAN_L3MISS
,
1749 Link
.IFLA_VXLAN_UDP_CSUM
,
1750 Link
.IFLA_VXLAN_UDP_ZERO_CSUM6_TX
,
1751 Link
.IFLA_VXLAN_UDP_ZERO_CSUM6_RX
,
1752 Link
.IFLA_VXLAN_REMCSUM_TX
,
1753 Link
.IFLA_VXLAN_REMCSUM_RX
,
1754 Link
.IFLA_VXLAN_REPLICATION_TYPE
):
1755 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1758 # sub_attr_end = padded_length(sub_attr_length)
1759 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND vxlan type %s (%d), length %d, padded to %d' %
1760 (parent_msg
.get_ifla_vxlan_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1762 elif ifla_info_kind
== 'bond':
1764 if info_data_type
in (Link
.IFLA_BOND_AD_INFO
, ):
1765 ad_attr_data
= sub_attr_data
[4:info_data_end
]
1766 self
.value
[Link
.IFLA_INFO_DATA
][Link
.IFLA_BOND_AD_INFO
] = {}
1769 (ad_data_length
, ad_data_type
) = unpack('=HH', ad_attr_data
[:4])
1770 ad_data_end
= padded_length(ad_data_length
)
1772 if ad_data_type
in (Link
.IFLA_BOND_AD_INFO_PARTNER_MAC
,):
1773 (data1
, data2
) = unpack('>LHxx', ad_attr_data
[4:12])
1774 self
.value
[Link
.IFLA_INFO_DATA
][Link
.IFLA_BOND_AD_INFO
][ad_data_type
] = mac_int_to_str(data1
<< 16 | data2
)
1776 ad_attr_data
= ad_attr_data
[ad_data_end
:]
1779 elif info_data_type
in (Link
.IFLA_BOND_MODE
,
1780 Link
.IFLA_BOND_USE_CARRIER
,
1781 Link
.IFLA_BOND_AD_LACP_RATE
,
1782 Link
.IFLA_BOND_AD_LACP_BYPASS
,
1783 Link
.IFLA_BOND_XMIT_HASH_POLICY
,
1784 Link
.IFLA_BOND_NUM_PEER_NOTIF
):
1785 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1788 elif info_data_type
== Link
.IFLA_BOND_AD_ACTOR_SYS_PRIO
:
1789 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1792 elif info_data_type
in (Link
.IFLA_BOND_MIIMON
,
1793 Link
.IFLA_BOND_UPDELAY
,
1794 Link
.IFLA_BOND_DOWNDELAY
,
1795 Link
.IFLA_BOND_MIN_LINKS
):
1796 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1799 elif info_data_type
in (Link
.IFLA_BOND_AD_ACTOR_SYSTEM
, ):
1800 (data1
, data2
) = unpack('>LHxx', sub_attr_data
[4:12])
1801 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = mac_int_to_str(data1
<< 16 | data2
)
1804 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND bond type %s (%d), length %d, padded to %d' %
1805 (parent_msg
.get_ifla_bond_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1807 elif ifla_info_kind
== 'bridge':
1809 if info_data_type
in (Link
.IFLA_BR_AGEING_TIME
,
1810 Link
.IFLA_BR_FORWARD_DELAY
,
1811 Link
.IFLA_BR_HELLO_TIME
,
1812 Link
.IFLA_BR_MAX_AGE
,
1813 Link
.IFLA_BR_STP_STATE
,
1814 Link
.IFLA_BR_ROOT_PATH_COST
,
1815 Link
.IFLA_BR_MCAST_HASH_ELASTICITY
,
1816 Link
.IFLA_BR_MCAST_HASH_MAX
,
1817 Link
.IFLA_BR_MCAST_LAST_MEMBER_CNT
,
1818 Link
.IFLA_BR_MCAST_STARTUP_QUERY_CNT
):
1819 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1822 elif info_data_type
in (Link
.IFLA_BR_PRIORITY
,
1823 Link
.IFLA_BR_GROUP_FWD_MASK
,
1824 Link
.IFLA_BR_ROOT_PORT
,
1825 Link
.IFLA_BR_VLAN_DEFAULT_PVID
):
1826 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1828 elif info_data_type
== Link
.IFLA_BR_VLAN_PROTOCOL
:
1829 hex_value
= '0x%s' % sub_attr_data
[4:6].encode('hex')
1830 vlan_protocol
= Link
.ifla_vlan_protocol_dict
.get(int(hex_value
, base
=16))
1833 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = vlan_protocol
1835 self
.log
.warning('IFLA_VLAN_PROTOCOL: cannot decode vlan protocol %s' % hex_value
)
1838 elif info_data_type
in (Link
.IFLA_BR_MCAST_MEMBERSHIP_INTVL
,
1839 Link
.IFLA_BR_MCAST_QUERIER_INTVL
,
1840 Link
.IFLA_BR_MCAST_LAST_MEMBER_INTVL
,
1841 Link
.IFLA_BR_MCAST_MEMBERSHIP_INTVL
,
1842 Link
.IFLA_BR_MCAST_QUERIER_INTVL
,
1843 Link
.IFLA_BR_MCAST_QUERY_INTVL
,
1844 Link
.IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
,
1845 Link
.IFLA_BR_MCAST_STARTUP_QUERY_INTVL
):
1846 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=Q', sub_attr_data
[4:12])[0]
1849 elif info_data_type
in (Link
.IFLA_BR_VLAN_FILTERING
,
1850 Link
.IFLA_BR_TOPOLOGY_CHANGE
,
1851 Link
.IFLA_BR_TOPOLOGY_CHANGE_DETECTED
,
1852 Link
.IFLA_BR_MCAST_ROUTER
,
1853 Link
.IFLA_BR_MCAST_SNOOPING
,
1854 Link
.IFLA_BR_MCAST_QUERY_USE_IFADDR
,
1855 Link
.IFLA_BR_MCAST_QUERIER
,
1856 Link
.IFLA_BR_NF_CALL_IPTABLES
,
1857 Link
.IFLA_BR_NF_CALL_IP6TABLES
,
1858 Link
.IFLA_BR_NF_CALL_ARPTABLES
,
1859 Link
.IFLA_BR_VLAN_STATS_ENABLED
,
1860 Link
.IFLA_BR_MCAST_STATS_ENABLED
,
1861 Link
.IFLA_BR_MCAST_IGMP_VERSION
,
1862 Link
.IFLA_BR_MCAST_MLD_VERSION
):
1863 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1865 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND bridge type %s (%d), length %d, padded to %d' %
1866 (parent_msg
.get_ifla_br_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1868 elif ifla_info_kind
== 'vrf':
1870 if info_data_type
in (Link
.IFLA_VRF_TABLE
,):
1871 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1873 elif ifla_info_kind
in ("gre", "gretap", "erspan", "ip6gre", "ip6gretap", "ip6erspan"):
1876 if info_data_type
in (Link
.IFLA_GRE_TTL
, Link
.IFLA_GRE_TOS
, Link
.IFLA_GRE_PMTUDISC
):
1877 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1880 elif info_data_type
in (
1881 Link
.IFLA_GRE_IFLAGS
,
1882 Link
.IFLA_GRE_OFLAGS
,
1883 Link
.IFLA_GRE_ENCAP_TYPE
,
1884 Link
.IFLA_GRE_ENCAP_SPORT
,
1885 Link
.IFLA_GRE_ENCAP_DPORT
,
1886 Link
.IFLA_GRE_ENCAP_FLAGS
1888 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1891 elif info_data_type
in (Link
.IFLA_GRE_LINK
, Link
.IFLA_GRE_IKEY
, Link
.IFLA_GRE_OKEY
):
1892 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1895 elif info_data_type
in (Link
.IFLA_GRE_LOCAL
, Link
.IFLA_GRE_REMOTE
):
1896 if ifla_info_kind
in ("ip6gre", "ip6gretap", "ip6erspan"):
1897 (data1
, data2
) = unpack(">QQ", sub_attr_data
[4:20])
1898 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = IPv6Address(data1
<< 64 | data2
)
1900 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = IPv4Address(unpack(">L", sub_attr_data
[4:8])[0])
1903 self
.log
.log(SYSLOG_EXTRA_DEBUG
,
1904 'Add support for decoding IFLA_INFO_KIND %s type %s (%d), length %d, padded to %d' %
1905 (ifla_info_kind
, parent_msg
.get_ifla_gre_string(info_data_type
), info_data_type
,
1906 info_data_length
, info_data_end
))
1908 elif ifla_info_kind
in ("ipip", "sit", "ip6tnl"):
1911 if info_data_type
in (Link
.IFLA_IPTUN_TTL
, Link
.IFLA_IPTUN_TOS
, Link
.IFLA_IPTUN_PMTUDISC
):
1912 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1915 elif info_data_type
in (Link
.IFLA_IPTUN_ENCAP_TYPE
, Link
.IFLA_IPTUN_ENCAP_SPORT
, Link
.IFLA_IPTUN_ENCAP_DPORT
, Link
.IFLA_IPTUN_ENCAP_FLAGS
):
1916 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=H', sub_attr_data
[4:6])[
1920 elif info_data_type
== Link
.IFLA_IPTUN_LINK
:
1921 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[
1925 elif info_data_type
in (Link
.IFLA_IPTUN_LOCAL
, Link
.IFLA_IPTUN_REMOTE
):
1926 if ifla_info_kind
== "ip6tnl":
1927 (data1
, data2
) = unpack(">QQ", sub_attr_data
[4:20])
1928 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = IPv6Address(data1
<< 64 | data2
)
1930 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = IPv4Address(unpack(">L", sub_attr_data
[4:8])[0])
1933 self
.log
.log(SYSLOG_EXTRA_DEBUG
,
1934 'Add support for decoding IFLA_INFO_KIND %s type %s (%d), length %d, padded to %d' %
1935 (ifla_info_kind
, parent_msg
.get_ifla_iptun_string(info_data_type
), info_data_type
,
1936 info_data_length
, info_data_end
))
1938 elif ifla_info_kind
in ("vti", "vti6"):
1940 if info_data_type
in (Link
.IFLA_VTI_LINK
, Link
.IFLA_VTI_IKEY
, Link
.IFLA_VTI_OKEY
):
1941 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1944 elif info_data_type
in (Link
.IFLA_VTI_LOCAL
, Link
.IFLA_VTI_REMOTE
):
1945 if ifla_info_kind
== "vti6":
1946 (data1
, data2
) = unpack(">QQ", sub_attr_data
[4:20])
1947 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = IPv6Address(data1
<< 64 | data2
)
1949 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = IPv4Address(unpack(">L", sub_attr_data
[4:8])[0])
1952 self
.log
.log(SYSLOG_EXTRA_DEBUG
,
1953 'Add support for decoding IFLA_INFO_KIND %s type %s (%d), length %d, padded to %d' %
1954 (ifla_info_kind
, parent_msg
.get_ifla_vti_string(info_data_type
), info_data_type
,
1955 info_data_length
, info_data_end
))
1958 self
.log
.log(SYSLOG_EXTRA_DEBUG
, "Add support for decoding IFLA_INFO_KIND %s (%d), length %d, padded to %d" %
1959 (ifla_info_kind
, info_data_type
, info_data_length
, info_data_end
))
1961 except Exception as e
:
1962 self
.log
.debug('%s: attribute %s: %s'
1963 % (self
.value
[Link
.IFLA_INFO_KIND
],
1966 sub_attr_data
= sub_attr_data
[info_data_end
:]
1969 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_LINKINFO sub-attribute type %s (%d), length %d, padded to %d' %
1970 (parent_msg
.get_ifla_info_string(sub_attr_type
), sub_attr_type
, sub_attr_length
, sub_attr_end
))
1972 data
= data
[sub_attr_end
:]
1974 # self.log.info('IFLA_LINKINFO values %s' % pformat(self.value))
1976 def dump_lines(self
, dump_buffer
, line_number
, color
):
1977 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
1980 next_sub_attr_line
= 0
1981 sub_attr_line
= True
1983 for x
in xrange(1, self
.attr_end
/4):
1987 if line_number
== next_sub_attr_line
:
1988 sub_attr_line
= True
1991 sub_attr_line
= False
1993 (sub_attr_length
, sub_attr_type
) = unpack('=HH', self
.data
[start
:start
+4])
1994 sub_attr_end
= padded_length(sub_attr_length
)
1996 next_sub_attr_line
= line_number
+ (sub_attr_end
/4)
1998 if sub_attr_end
== sub_attr_length
:
2001 padded_to
= ' padded to %d, ' % sub_attr_end
2003 extra
= 'Nested Attribute - Length %s (%d)%s Type %s (%d) %s' % \
2004 (zfilled_hex(sub_attr_length
, 4), sub_attr_length
,
2006 zfilled_hex(sub_attr_type
, 4), sub_attr_type
,
2007 Link
.ifla_info_to_string
.get(sub_attr_type
))
2011 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], extra
))
2016 def get_pretty_value(self
, obj
=None):
2018 if obj
and callable(obj
):
2019 return obj(self
.value
)
2021 value_pretty
= self
.value
2022 ifla_info_kind
= self
.value
.get(Link
.IFLA_INFO_KIND
)
2023 ifla_info_slave_kind
= self
.value
.get(Link
.IFLA_INFO_SLAVE_KIND
)
2027 # We do this so we can print a more human readable dictionary
2028 # with the names of the nested keys instead of their numbers
2030 # Most of these are placeholders...we need to add support
2031 # for more human readable dictionaries for bond, bridge, etc
2032 kind_dict
[Link
.IFLA_INFO_DATA
] = {
2033 'bond': Link
.ifla_bond_to_string
,
2034 'vlan': Link
.ifla_vlan_to_string
,
2035 'vxlan': Link
.ifla_vxlan_to_string
,
2036 'bridge': Link
.ifla_br_to_string
,
2037 'macvlan': Link
.ifla_macvlan_to_string
,
2038 'gre': Link
.ifla_gre_to_string
,
2039 'gretap': Link
.ifla_gre_to_string
,
2040 'erspan': Link
.ifla_gre_to_string
,
2041 'ip6gre': Link
.ifla_gre_to_string
,
2042 'ip6gretap': Link
.ifla_gre_to_string
,
2043 'ip6erspan': Link
.ifla_gre_to_string
,
2044 'vti': Link
.ifla_vti_to_string
,
2045 'vti6': Link
.ifla_vti_to_string
,
2046 'ipip': Link
.ifla_iptun_to_string
,
2047 'sit': Link
.ifla_iptun_to_string
,
2048 'ip6tnl': Link
.ifla_iptun_to_string
,
2049 'xfrm': Link
.ifla_xfrm_to_string
2050 }.get(ifla_info_kind
, {})
2052 kind_dict
[Link
.IFLA_INFO_SLAVE_DATA
] = {
2053 'bridge': Link
.ifla_brport_to_string
,
2054 'bond': Link
.ifla_bond_slave_to_string
2055 }.get(ifla_info_slave_kind
, {})
2057 if ifla_info_kind
or ifla_info_slave_kind
:
2060 for (sub_key
, sub_value
) in self
.value
.iteritems():
2061 sub_key_pretty
= "(%2d) %s" % (sub_key
, Link
.ifla_info_to_string
.get(sub_key
, 'UNKNOWN'))
2062 sub_value_pretty
= sub_value
2064 if sub_key
in (Link
.IFLA_INFO_DATA
, Link
.IFLA_INFO_SLAVE_DATA
):
2065 kind_to_string_dict
= kind_dict
.get(sub_key
, {})
2066 sub_value_pretty
= {}
2068 for (sub_sub_key
, sub_sub_value
) in sub_value
.iteritems():
2069 sub_sub_key_pretty
= "(%2d) %s" % (sub_sub_key
, kind_to_string_dict
.get(sub_sub_key
, 'UNKNOWN'))
2070 sub_value_pretty
[sub_sub_key_pretty
] = sub_sub_value
2072 value_pretty
[sub_key_pretty
] = sub_value_pretty
2077 class AttributeIFLA_PROTINFO(Attribute
):
2079 IFLA_PROTINFO nested attributes.
2081 def __init__(self
, atype
, string
, family
, logger
):
2082 Attribute
.__init
__(self
, atype
, string
, logger
)
2083 self
.family
= family
2086 pack_layout
= [self
.HEADER_PACK
]
2087 payload
= [0, self
.atype | NLA_F_NESTED
]
2088 attr_length_index
= 0
2090 if self
.family
not in (AF_BRIDGE
,):
2091 raise Exception('Unsupported IFLA_PROTINFO family %d' % self
.family
)
2093 # For now this assumes that all data will be packed in the native endian
2094 # order (=). If a field is added that needs to be packed via network
2095 # order (>) then some smarts will need to be added to split the pack_layout
2096 # string at the >, split the payload and make the needed pack() calls.
2098 # Until we cross that bridge though we will keep things nice and simple and
2099 # pack everything via a single pack() call.
2100 for (sub_attr_type
, sub_attr_value
) in self
.value
.iteritems():
2101 sub_attr_pack_layout
= ['=', 'HH']
2102 sub_attr_payload
= [0, sub_attr_type
]
2103 sub_attr_length_index
= 0
2105 if self
.family
== AF_BRIDGE
:
2107 if sub_attr_type
in (Link
.IFLA_BRPORT_STATE
,
2108 Link
.IFLA_BRPORT_MODE
,
2109 Link
.IFLA_BRPORT_GUARD
,
2110 Link
.IFLA_BRPORT_PROTECT
,
2111 Link
.IFLA_BRPORT_FAST_LEAVE
,
2112 Link
.IFLA_BRPORT_LEARNING
,
2113 Link
.IFLA_BRPORT_UNICAST_FLOOD
,
2114 Link
.IFLA_BRPORT_PROXYARP
,
2115 Link
.IFLA_BRPORT_LEARNING_SYNC
,
2116 Link
.IFLA_BRPORT_PROXYARP_WIFI
,
2117 Link
.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
,
2118 Link
.IFLA_BRPORT_CONFIG_PENDING
,
2119 Link
.IFLA_BRPORT_FLUSH
,
2120 Link
.IFLA_BRPORT_MULTICAST_ROUTER
,
2121 Link
.IFLA_BRPORT_PEER_LINK
,
2122 Link
.IFLA_BRPORT_DUAL_LINK
,
2123 Link
.IFLA_BRPORT_ARP_SUPPRESS
,
2124 Link
.IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
):
2125 sub_attr_pack_layout
.append('B')
2126 sub_attr_payload
.append(sub_attr_value
)
2127 sub_attr_pack_layout
.extend('xxx')
2130 elif sub_attr_type
in (Link
.IFLA_BRPORT_PRIORITY
,
2131 Link
.IFLA_BRPORT_DESIGNATED_PORT
,
2132 Link
.IFLA_BRPORT_DESIGNATED_COST
,
2133 Link
.IFLA_BRPORT_ID
,
2134 Link
.IFLA_BRPORT_NO
):
2135 sub_attr_pack_layout
.append('H')
2136 sub_attr_payload
.append(sub_attr_value
)
2137 sub_attr_pack_layout
.extend('xx')
2140 elif sub_attr_type
in (Link
.IFLA_BRPORT_COST
,):
2141 sub_attr_pack_layout
.append('L')
2142 sub_attr_payload
.append(sub_attr_value
)
2145 elif sub_attr_type
in (Link
.IFLA_BRPORT_MESSAGE_AGE_TIMER
,
2146 Link
.IFLA_BRPORT_FORWARD_DELAY_TIMER
,
2147 Link
.IFLA_BRPORT_HOLD_TIMER
):
2148 sub_attr_pack_layout
.append('Q')
2149 sub_attr_payload
.append(sub_attr_value
)
2152 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_PROTINFO sub-attribute type %d' % sub_attr_type
)
2154 sub_attr_length
= calcsize(''.join(sub_attr_pack_layout
))
2155 sub_attr_payload
[sub_attr_length_index
] = sub_attr_length
2158 for x
in xrange(self
.pad_bytes_needed(sub_attr_length
)):
2159 sub_attr_pack_layout
.append('x')
2161 # The [1:] is to remove the leading = so that when we do the ''.join() later
2162 # we do not end up with an = in the middle of the pack layout string. There
2163 # will be an = at the beginning via self.HEADER_PACK
2164 sub_attr_pack_layout
= sub_attr_pack_layout
[1:]
2166 # Now extend the ovarall attribute pack_layout/payload to include this sub-attribute
2167 pack_layout
.extend(sub_attr_pack_layout
)
2168 payload
.extend(sub_attr_payload
)
2170 pack_layout
= ''.join(pack_layout
)
2172 # Fill in the length field
2173 length
= calcsize(pack_layout
)
2174 payload
[attr_length_index
] = length
2176 raw
= pack(pack_layout
, *payload
)
2177 raw
= self
.pad(length
, raw
)
2180 def decode(self
, parent_msg
, data
):
2182 value is a dictionary such as:
2184 Link.IFLA_BRPORT_STATE : 3,
2185 Link.IFLA_BRPORT_PRIORITY : 8
2186 Link.IFLA_BRPORT_COST : 2
2190 self
.decode_length_type(data
)
2193 data
= self
.data
[4:]
2196 (sub_attr_length
, sub_attr_type
) = unpack('=HH', data
[:4])
2197 sub_attr_end
= padded_length(sub_attr_length
)
2199 if not sub_attr_length
:
2200 self
.log
.error('parsed a zero length sub-attr')
2203 if self
.family
== AF_BRIDGE
:
2206 if sub_attr_type
in (Link
.IFLA_BRPORT_STATE
,
2207 Link
.IFLA_BRPORT_MODE
,
2208 Link
.IFLA_BRPORT_GUARD
,
2209 Link
.IFLA_BRPORT_PROTECT
,
2210 Link
.IFLA_BRPORT_FAST_LEAVE
,
2211 Link
.IFLA_BRPORT_LEARNING
,
2212 Link
.IFLA_BRPORT_UNICAST_FLOOD
,
2213 Link
.IFLA_BRPORT_PROXYARP
,
2214 Link
.IFLA_BRPORT_LEARNING_SYNC
,
2215 Link
.IFLA_BRPORT_PROXYARP_WIFI
,
2216 Link
.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
,
2217 Link
.IFLA_BRPORT_CONFIG_PENDING
,
2218 Link
.IFLA_BRPORT_FLUSH
,
2219 Link
.IFLA_BRPORT_MULTICAST_ROUTER
,
2220 Link
.IFLA_BRPORT_PEER_LINK
,
2221 Link
.IFLA_BRPORT_DUAL_LINK
,
2222 Link
.IFLA_BRPORT_ARP_SUPPRESS
,
2223 Link
.IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
):
2224 self
.value
[sub_attr_type
] = unpack('=B', data
[4])[0]
2227 elif sub_attr_type
in (Link
.IFLA_BRPORT_PRIORITY
,
2228 Link
.IFLA_BRPORT_DESIGNATED_PORT
,
2229 Link
.IFLA_BRPORT_DESIGNATED_COST
,
2230 Link
.IFLA_BRPORT_ID
,
2231 Link
.IFLA_BRPORT_NO
):
2232 self
.value
[sub_attr_type
] = unpack('=H', data
[4:6])[0]
2235 elif sub_attr_type
in (Link
.IFLA_BRPORT_COST
,):
2236 self
.value
[sub_attr_type
] = unpack('=L', data
[4:8])[0]
2239 elif sub_attr_type
in (Link
.IFLA_BRPORT_MESSAGE_AGE_TIMER
,
2240 Link
.IFLA_BRPORT_FORWARD_DELAY_TIMER
,
2241 Link
.IFLA_BRPORT_HOLD_TIMER
):
2242 self
.value
[sub_attr_type
] = unpack('=Q', data
[4:12])[0]
2245 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_PROTINFO sub-attribute type %s (%d), length %d, padded to %d' %
2246 (parent_msg
.get_ifla_brport_string(sub_attr_type
), sub_attr_type
, sub_attr_length
, sub_attr_end
))
2248 data
= data
[sub_attr_end
:]
2250 def dump_lines(self
, dump_buffer
, line_number
, color
):
2251 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
2254 next_sub_attr_line
= 0
2255 sub_attr_line
= True
2257 for x
in xrange(1, self
.attr_end
/4):
2261 if line_number
== next_sub_attr_line
:
2262 sub_attr_line
= True
2265 sub_attr_line
= False
2267 (sub_attr_length
, sub_attr_type
) = unpack('=HH', self
.data
[start
:start
+4])
2268 sub_attr_end
= padded_length(sub_attr_length
)
2270 next_sub_attr_line
= line_number
+ (sub_attr_end
/4)
2272 if sub_attr_end
== sub_attr_length
:
2275 padded_to
= ' padded to %d, ' % sub_attr_end
2277 extra
= 'Nested Attribute - Length %s (%d)%s Type %s (%d) %s' % \
2278 (zfilled_hex(sub_attr_length
, 4), sub_attr_length
,
2280 zfilled_hex(sub_attr_type
, 4), sub_attr_type
,
2281 Link
.ifla_brport_to_string
.get(sub_attr_type
))
2285 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], extra
))
2290 def get_pretty_value(self
, obj
=None):
2292 if obj
and callable(obj
):
2293 return obj(self
.value
)
2297 for (sub_key
, sub_value
) in self
.value
.iteritems():
2298 sub_key_pretty
= "(%2d) %s" % (sub_key
, Link
.ifla_brport_to_string
.get(sub_key
, 'UNKNOWN'))
2299 sub_value_pretty
= sub_value
2300 value_pretty
[sub_key_pretty
] = sub_value_pretty
2306 class NetlinkPacket(object):
2311 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2312 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2314 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2316 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2318 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2319 | Process ID (PID) |
2320 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2323 header_PACK
= 'IHHII'
2324 header_LEN
= calcsize(header_PACK
)
2326 # Netlink packet types
2327 # /usr/include/linux/rtnetlink.h
2329 NLMSG_NOOP
: 'NLMSG_NOOP',
2330 NLMSG_ERROR
: 'NLMSG_ERROR',
2331 NLMSG_DONE
: 'NLMSG_DONE',
2332 NLMSG_OVERRUN
: 'NLMSG_OVERRUN',
2333 RTM_NEWLINK
: 'RTM_NEWLINK',
2334 RTM_DELLINK
: 'RTM_DELLINK',
2335 RTM_GETLINK
: 'RTM_GETLINK',
2336 RTM_SETLINK
: 'RTM_SETLINK',
2337 RTM_NEWADDR
: 'RTM_NEWADDR',
2338 RTM_DELADDR
: 'RTM_DELADDR',
2339 RTM_GETADDR
: 'RTM_GETADDR',
2340 RTM_NEWNEIGH
: 'RTM_NEWNEIGH',
2341 RTM_DELNEIGH
: 'RTM_DELNEIGH',
2342 RTM_GETNEIGH
: 'RTM_GETNEIGH',
2343 RTM_NEWROUTE
: 'RTM_NEWROUTE',
2344 RTM_DELROUTE
: 'RTM_DELROUTE',
2345 RTM_GETROUTE
: 'RTM_GETROUTE',
2346 RTM_NEWQDISC
: 'RTM_NEWQDISC',
2347 RTM_DELQDISC
: 'RTM_DELQDISC',
2348 RTM_GETQDISC
: 'RTM_GETQDISC',
2349 RTM_NEWNETCONF
: 'RTM_NEWNETCONF',
2350 RTM_GETNETCONF
: 'RTM_GETNETCONF'
2353 af_family_to_string
= {
2358 def __init__(self
, msgtype
, debug
, owner_logger
=None, use_color
=True):
2359 self
.msgtype
= msgtype
2360 self
.attributes
= {}
2361 self
.dump_buffer
= ['']
2362 self
.line_number
= 1
2365 self
.use_color
= use_color
2369 self
.log
= owner_logger
2374 return self
.get_type_string()
2376 def get_string(self
, to_string
, index
):
2378 Used to do lookups in all of the various FOO_to_string dictionaries
2379 but returns 'UNKNOWN' if the key is bogus
2381 if index
in to_string
:
2382 return to_string
[index
]
2385 def get_type_string(self
, msgtype
=None):
2387 msgtype
= self
.msgtype
2388 return self
.get_string(self
.type_to_string
, msgtype
)
2390 def get_flags_string(self
):
2393 for (flag
, flag_string
) in self
.flag_to_string
.iteritems():
2394 if self
.flags
& flag
:
2395 foo
.append(flag_string
)
2397 return ', '.join(foo
)
2399 def decode_packet(self
, length
, flags
, seq
, pid
, data
):
2400 self
.length
= length
2404 self
.header_data
= data
[0:self
.header_LEN
]
2405 self
.msg_data
= data
[self
.header_LEN
:length
]
2407 self
.decode_netlink_header()
2408 self
.decode_service_header()
2410 # NLMSG_ERROR is special case, it does not have attributes to decode
2411 if self
.msgtype
!= NLMSG_ERROR
:
2412 self
.decode_attributes()
2414 def get_netlink_header_flags_string(self
, msg_type
, flags
):
2417 if flags
& NLM_F_REQUEST
:
2418 foo
.append('NLM_F_REQUEST')
2420 if flags
& NLM_F_MULTI
:
2421 foo
.append('NLM_F_MULTI')
2423 if flags
& NLM_F_ACK
:
2424 foo
.append('NLM_F_ACK')
2426 if flags
& NLM_F_ECHO
:
2427 foo
.append('NLM_F_ECHO')
2429 # Modifiers to GET query
2430 if msg_type
in (RTM_GETLINK
, RTM_GETADDR
, RTM_GETNEIGH
, RTM_GETROUTE
, RTM_GETQDISC
, RTM_GETNETCONF
):
2431 if flags
& NLM_F_DUMP
:
2432 foo
.append('NLM_F_DUMP')
2434 if flags
& NLM_F_MATCH
:
2435 foo
.append('NLM_F_MATCH')
2437 if flags
& NLM_F_ROOT
:
2438 foo
.append('NLM_F_ROOT')
2440 if flags
& NLM_F_ATOMIC
:
2441 foo
.append('NLM_F_ATOMIC')
2443 # Modifiers to NEW query
2444 elif msg_type
in (RTM_NEWLINK
, RTM_NEWADDR
, RTM_NEWNEIGH
, RTM_NEWROUTE
, RTM_NEWQDISC
):
2445 if flags
& NLM_F_REPLACE
:
2446 foo
.append('NLM_F_REPLACE')
2448 if flags
& NLM_F_EXCL
:
2449 foo
.append('NLM_F_EXCL')
2451 if flags
& NLM_F_CREATE
:
2452 foo
.append('NLM_F_CREATE')
2454 if flags
& NLM_F_APPEND
:
2455 foo
.append('NLM_F_APPEND')
2457 return ', '.join(foo
)
2459 # When we first RXed the netlink message we had to decode the header to
2460 # determine what type of netlink message we were dealing with. So the
2461 # header has actually already been decoded...what we do here is
2462 # populate the dump_buffer lines with the header content.
2463 def decode_netlink_header(self
):
2468 header_data
= self
.header_data
2470 # Print the netlink header in red
2471 netlink_header_length
= 16
2472 color
= red
if self
.use_color
else None
2473 color_start
= "\033[%dm" % color
if color
else ""
2474 color_end
= "\033[0m" if color
else ""
2475 self
.dump_buffer
.append(" %sNetlink Header%s" % (color_start
, color_end
))
2477 for x
in range(0, netlink_header_length
/4):
2481 if self
.line_number
== 1:
2482 data
= unpack('=L', header_data
[start
:end
])[0]
2483 extra
= "Length %s (%d)" % (zfilled_hex(data
, 8), data
)
2485 elif self
.line_number
== 2:
2486 (data1
, data2
) = unpack('HH', header_data
[start
:end
])
2487 extra
= "Type %s (%d - %s), Flags %s (%s)" % \
2488 (zfilled_hex(data1
, 4), data1
, self
.get_type_string(data1
),
2489 zfilled_hex(data2
, 4), self
.get_netlink_header_flags_string(data1
, data2
))
2491 elif self
.line_number
== 3:
2492 data
= unpack('=L', header_data
[start
:end
])[0]
2493 extra
= "Sequence Number %s (%d)" % (zfilled_hex(data
, 8), data
)
2495 elif self
.line_number
== 4:
2496 data
= unpack('=L', header_data
[start
:end
])[0]
2497 extra
= "Process ID %s (%d)" % (zfilled_hex(data
, 8), data
)
2499 extra
= "Unexpected line number %d" % self
.line_number
2501 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, header_data
[start
:end
], extra
))
2502 self
.line_number
+= 1
2504 def decode_attributes(self
):
2506 Decode the attributes and populate the dump_buffer
2510 self
.dump_buffer
.append(" Attributes")
2511 color
= green
if self
.use_color
else None
2513 data
= self
.msg_data
[self
.LEN
:]
2516 (length
, attr_type
) = unpack('=HH', data
[:4])
2518 # If this is zero we will stay in this loop for forever
2520 self
.log
.error('Length is zero')
2523 if len(data
) < length
:
2524 self
.log
.error("Buffer underrun %d < %d" % (len(data
), length
))
2527 attr
= self
.add_attribute(attr_type
, None)
2529 # Find the end of 'data' for this attribute and decode our section
2530 # of 'data'. attributes are padded for alignment thus the attr_end.
2532 # How the attribute is decoded/unpacked is specific per AttributeXXXX class.
2533 attr_end
= padded_length(length
)
2534 attr
.decode(self
, data
[0:attr_end
])
2537 self
.line_number
= attr
.dump_lines(self
.dump_buffer
, self
.line_number
, color
)
2539 # Alternate back and forth between green and blue
2546 data
= data
[attr_end
:]
2548 def add_attribute(self
, attr_type
, value
):
2549 nested
= True if attr_type
& NLA_F_NESTED
else False
2550 net_byteorder
= True if attr_type
& NLA_F_NET_BYTEORDER
else False
2551 attr_type
= attr_type
& NLA_TYPE_MASK
2553 # Given an attr_type (say RTA_DST) find the type of AttributeXXXX class
2554 # that we will use to store this attribute...AttributeIPAddress in the
2556 if attr_type
in self
.attribute_to_class
:
2557 (attr_string
, attr_class
) = self
.attribute_to_class
[attr_type
]
2560 attribute_to_class is a dictionary where the key is the attr_type, it doesn't
2561 take the family into account. For now we'll handle this as a special case for
2562 MPLS but long term we may need to make key a tuple of the attr_type and family.
2564 if self
.msgtype
not in (RTM_NEWNETCONF
, RTM_GETNETCONF
) and attr_type
== Route
.RTA_DST
and self
.family
== AF_MPLS
:
2565 attr_string
= 'RTA_DST'
2566 attr_class
= AttributeMplsLabel
2569 attr_string
= "UNKNOWN_ATTRIBUTE_%d" % attr_type
2570 attr_class
= AttributeGeneric
2571 self
.log
.debug("Attribute %d is not defined in %s.attribute_to_class, assuming AttributeGeneric" %
2572 (attr_type
, self
.__class
__.__name
__))
2574 attr
= attr_class(attr_type
, attr_string
, self
.family
, self
.log
)
2576 attr
.set_value(value
)
2577 attr
.set_nested(nested
)
2578 attr
.set_net_byteorder(net_byteorder
)
2580 # self.attributes is a dictionary keyed by the attribute type where
2581 # the value is an instance of the corresponding AttributeXXXX class.
2582 self
.attributes
[attr_type
] = attr
2586 def get_attribute_value(self
, attr_type
, default
=None):
2587 if attr_type
not in self
.attributes
:
2590 return self
.attributes
[attr_type
].value
2592 def get_attr_string(self
, attr_type
):
2594 Example: If attr_type is Address.IFA_CACHEINFO return the string 'IFA_CACHEINFO'
2596 if attr_type
in self
.attribute_to_class
:
2597 (attr_string
, attr_class
) = self
.attribute_to_class
[attr_type
]
2599 return str(attr_type
)
2601 def build_message(self
, seq
, pid
):
2606 for attr
in self
.attributes
.itervalues():
2607 attrs
+= attr
.encode()
2609 self
.length
= self
.header_LEN
+ len(self
.body
) + len(attrs
)
2610 self
.header_data
= pack(self
.header_PACK
, self
.length
, self
.msgtype
, self
.flags
, self
.seq
, self
.pid
)
2611 self
.msg_data
= self
.body
+ attrs
2612 self
.message
= self
.header_data
+ self
.msg_data
2615 self
.decode_netlink_header()
2616 self
.decode_service_header()
2617 self
.decode_attributes()
2618 self
.dump("TXed %s, length %d, seq %d, pid %d, flags 0x%x (%s)" %
2619 (self
, self
.length
, self
.seq
, self
.pid
, self
.flags
,
2620 self
.get_netlink_header_flags_string(self
.msgtype
, self
.flags
)))
2622 def pretty_display_dict(self
, dic
, level
):
2623 for k
,v
in dic
.iteritems():
2624 if isinstance(v
, dict):
2625 self
.log
.debug(' '*level
+ str(k
) + ':')
2626 self
.pretty_display_dict(v
, level
+5)
2628 self
.log
.debug(' '*level
+ str(k
) + ': ' + str(v
))
2630 # Print the netlink message in hex. This is only used for debugging.
2631 def dump(self
, desc
=None):
2635 desc
= "RXed %s, length %d, seq %d, pid %d, flags 0x%x" % (self
, self
.length
, self
.seq
, self
.pid
, self
.flags
)
2637 for (attr_type
, attr_obj
) in self
.attributes
.iteritems():
2638 key_string
= "(%2d) %s" % (attr_type
, self
.get_attr_string(attr_type
))
2639 attr_string
[key_string
] = attr_obj
.get_pretty_value()
2642 self
.log
.debug("%s\n%s\n\nAttributes Summary\n%s\n" %
2643 (desc
, '\n'.join(self
.dump_buffer
), pformat(attr_string
)))
2645 # Assume if we are not allowing color output we also don't want embedded
2646 # newline characters in the output. Output each line individually.
2647 self
.log
.debug(desc
)
2648 for line
in self
.dump_buffer
:
2649 self
.log
.debug(line
)
2651 self
.log
.debug("Attributes Summary")
2652 self
.pretty_display_dict(attr_string
, 1)
2655 class Address(NetlinkPacket
):
2659 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2660 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2661 | Family | Length | Flags | Scope |
2662 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2664 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2667 # Address attributes
2668 # /usr/include/linux/if_addr.h
2673 IFA_BROADCAST
= 0x04
2675 IFA_CACHEINFO
= 0x06
2676 IFA_MULTICAST
= 0x07
2679 attribute_to_class
= {
2680 IFA_UNSPEC
: ('IFA_UNSPEC', AttributeGeneric
),
2681 IFA_ADDRESS
: ('IFA_ADDRESS', AttributeIPAddress
),
2682 IFA_LOCAL
: ('IFA_LOCAL', AttributeIPAddress
),
2683 IFA_LABEL
: ('IFA_LABEL', AttributeString
),
2684 IFA_BROADCAST
: ('IFA_BROADCAST', AttributeIPAddress
),
2685 IFA_ANYCAST
: ('IFA_ANYCAST', AttributeIPAddress
),
2686 IFA_CACHEINFO
: ('IFA_CACHEINFO', AttributeGeneric
),
2687 IFA_MULTICAST
: ('IFA_MULTICAST', AttributeIPAddress
),
2688 IFA_FLAGS
: ('IFA_FLAGS', AttributeGeneric
)
2692 # /usr/include/linux/if_addr.h
2693 IFA_F_SECONDARY
= 0x01
2695 IFA_F_OPTIMISTIC
= 0x04
2696 IFA_F_DADFAILED
= 0x08
2697 IFA_F_HOMEADDRESS
= 0x10
2698 IFA_F_DEPRECATED
= 0x20
2699 IFA_F_TENTATIVE
= 0x40
2700 IFA_F_PERMANENT
= 0x80
2703 IFA_F_SECONDARY
: 'IFA_F_SECONDARY',
2704 IFA_F_NODAD
: 'IFA_F_NODAD',
2705 IFA_F_OPTIMISTIC
: 'IFA_F_OPTIMISTIC',
2706 IFA_F_DADFAILED
: 'IFA_F_DADFAILED',
2707 IFA_F_HOMEADDRESS
: 'IFA_F_HOMEADDRESS',
2708 IFA_F_DEPRECATED
: 'IFA_F_DEPRECATED',
2709 IFA_F_TENTATIVE
: 'IFA_F_TENTATIVE',
2710 IFA_F_PERMANENT
: 'IFA_F_PERMANENT'
2713 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
2714 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
2716 self
.LEN
= calcsize(self
.PACK
)
2718 def decode_service_header(self
):
2720 # Nothing to do if the message did not contain a service header
2721 if self
.length
== self
.header_LEN
:
2724 (self
.family
, self
.prefixlen
, self
.flags
, self
.scope
,
2726 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
2729 color
= yellow
if self
.use_color
else None
2730 color_start
= "\033[%dm" % color
if color
else ""
2731 color_end
= "\033[0m" if color
else ""
2732 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
2734 for x
in range(0, self
.LEN
/4):
2735 if self
.line_number
== 5:
2736 extra
= "Family %s (%s:%d), Length %s (%d), Flags %s, Scope %s (%d)" % \
2737 (zfilled_hex(self
.family
, 2), get_family_str(self
.family
), self
.family
,
2738 zfilled_hex(self
.prefixlen
, 2), self
.prefixlen
,
2739 zfilled_hex(self
.flags
, 2),
2740 zfilled_hex(self
.scope
, 2), self
.scope
)
2741 elif self
.line_number
== 6:
2742 extra
= "Interface Index %s (%d)" % (zfilled_hex(self
.ifindex
, 8), self
.ifindex
)
2744 extra
= "Unexpected line number %d" % self
.line_number
2748 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
2749 self
.line_number
+= 1
2752 class Error(NetlinkPacket
):
2755 # /include/netlink/errno.h
2766 NLE_OPNOTSUPP
= 0x0A
2767 NLE_AF_NOSUPPORT
= 0x0B
2768 NLE_OBJ_NOTFOUND
= 0x0C
2770 NLE_MISSING_ATTR
= 0x0E
2771 NLE_AF_MISMATCH
= 0x0F
2772 NLE_SEQ_MISMATCH
= 0x10
2773 NLE_MSG_OVERFLOW
= 0x11
2774 NLE_MSG_TRUNC
= 0x12
2776 NLE_SRCRT_NOSUPPORT
= 0x14
2777 NLE_MSG_TOOSHORT
= 0x15
2778 NLE_MSGTYPE_NOSUPPORT
= 0x16
2779 NLE_OBJ_MISMATCH
= 0x17
2782 NLE_PROTO_MISMATCH
= 0x1A
2785 NLE_PKTLOC_FILE
= 0x1D
2786 NLE_PARSE_ERR
= 0x1E
2788 NLE_IMMUTABLE
= 0x20
2789 NLE_DUMP_INTR
= 0x21
2792 NLE_SUCCESS
: 'NLE_SUCCESS',
2793 NLE_FAILURE
: 'NLE_FAILURE',
2794 NLE_INTR
: 'NLE_INTR',
2795 NLE_BAD_SOCK
: 'NLE_BAD_SOCK',
2796 NLE_AGAIN
: 'NLE_AGAIN',
2797 NLE_NOMEM
: 'NLE_NOMEM',
2798 NLE_EXIST
: 'NLE_EXIST',
2799 NLE_INVAL
: 'NLE_INVAL',
2800 NLE_RANGE
: 'NLE_RANGE',
2801 NLE_MSGSIZE
: 'NLE_MSGSIZE',
2802 NLE_OPNOTSUPP
: 'NLE_OPNOTSUPP',
2803 NLE_AF_NOSUPPORT
: 'NLE_AF_NOSUPPORT',
2804 NLE_OBJ_NOTFOUND
: 'NLE_OBJ_NOTFOUND',
2805 NLE_NOATTR
: 'NLE_NOATTR',
2806 NLE_MISSING_ATTR
: 'NLE_MISSING_ATTR',
2807 NLE_AF_MISMATCH
: 'NLE_AF_MISMATCH',
2808 NLE_SEQ_MISMATCH
: 'NLE_SEQ_MISMATCH',
2809 NLE_MSG_OVERFLOW
: 'NLE_MSG_OVERFLOW',
2810 NLE_MSG_TRUNC
: 'NLE_MSG_TRUNC',
2811 NLE_NOADDR
: 'NLE_NOADDR',
2812 NLE_SRCRT_NOSUPPORT
: 'NLE_SRCRT_NOSUPPORT',
2813 NLE_MSG_TOOSHORT
: 'NLE_MSG_TOOSHORT',
2814 NLE_MSGTYPE_NOSUPPORT
: 'NLE_MSGTYPE_NOSUPPORT',
2815 NLE_OBJ_MISMATCH
: 'NLE_OBJ_MISMATCH',
2816 NLE_NOCACHE
: 'NLE_NOCACHE',
2817 NLE_BUSY
: 'NLE_BUSY',
2818 NLE_PROTO_MISMATCH
: 'NLE_PROTO_MISMATCH',
2819 NLE_NOACCESS
: 'NLE_NOACCESS',
2820 NLE_PERM
: 'NLE_PERM',
2821 NLE_PKTLOC_FILE
: 'NLE_PKTLOC_FILE',
2822 NLE_PARSE_ERR
: 'NLE_PARSE_ERR',
2823 NLE_NODEV
: 'NLE_NODEV',
2824 NLE_IMMUTABLE
: 'NLE_IMMUTABLE',
2825 NLE_DUMP_INTR
: 'NLE_DUMP_INTR'
2828 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
2829 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
2830 self
.PACK
= '=iLHHLL'
2831 self
.LEN
= calcsize(self
.PACK
)
2833 def decode_service_header(self
):
2835 # Nothing to do if the message did not contain a service header
2836 if self
.length
== self
.header_LEN
:
2839 (self
.negative_errno
, self
.bad_msg_len
, self
.bad_msg_type
,
2840 self
.bad_msg_flag
, self
.bad_msg_seq
, self
.bad_msg_pid
) =\
2841 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
2844 color
= yellow
if self
.use_color
else None
2845 color_start
= "\033[%dm" % color
if color
else ""
2846 color_end
= "\033[0m" if color
else ""
2847 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
2849 for x
in range(0, self
.LEN
/4):
2851 if self
.line_number
== 5:
2852 extra
= "Error Number %s is %s" % (self
.negative_errno
, self
.error_to_string
.get(abs(self
.negative_errno
)))
2853 # zfilled_hex(self.negative_errno, 2)
2855 elif self
.line_number
== 6:
2856 extra
= "Length %s (%d)" % (zfilled_hex(self
.bad_msg_len
, 8), self
.bad_msg_len
)
2858 elif self
.line_number
== 7:
2859 extra
= "Type %s (%d - %s), Flags %s (%s)" % \
2860 (zfilled_hex(self
.bad_msg_type
, 4), self
.bad_msg_type
, self
.get_type_string(self
.bad_msg_type
),
2861 zfilled_hex(self
.bad_msg_flag
, 4), self
.get_netlink_header_flags_string(self
.bad_msg_type
, self
.bad_msg_flag
))
2863 elif self
.line_number
== 8:
2864 extra
= "Sequence Number %s (%d)" % (zfilled_hex(self
.bad_msg_seq
, 8), self
.bad_msg_seq
)
2866 elif self
.line_number
== 9:
2867 extra
= "Process ID %s (%d)" % (zfilled_hex(self
.bad_msg_pid
, 8), self
.bad_msg_pid
)
2870 extra
= "Unexpected line number %d" % self
.line_number
2874 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
2875 self
.line_number
+= 1
2878 class Link(NetlinkPacket
):
2883 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2884 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2885 | Family | Reserved | Device Type |
2886 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2888 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2890 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2892 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2896 # /usr/include/linux/if_link.h
2916 IFLA_NET_NS_PID
= 19
2919 IFLA_VFINFO_LIST
= 22
2927 IFLA_PROMISCUITY
= 30
2928 IFLA_NUM_TX_QUEUES
= 31
2929 IFLA_NUM_RX_QUEUES
= 32
2931 IFLA_PHYS_PORT_ID
= 34
2932 IFLA_CARRIER_CHANGES
= 35
2933 IFLA_PHYS_SWITCH_ID
= 36
2934 IFLA_LINK_NETNSID
= 37
2935 IFLA_PHYS_PORT_NAME
= 38
2936 IFLA_PROTO_DOWN
= 39
2937 IFLA_GSO_MAX_SEGS
= 40
2938 IFLA_GSO_MAX_SIZE
= 41
2940 attribute_to_class
= {
2941 IFLA_UNSPEC
: ('IFLA_UNSPEC', AttributeGeneric
),
2942 IFLA_ADDRESS
: ('IFLA_ADDRESS', AttributeMACAddress
),
2943 IFLA_BROADCAST
: ('IFLA_BROADCAST', AttributeMACAddress
),
2944 IFLA_IFNAME
: ('IFLA_IFNAME', AttributeStringInterfaceName
),
2945 IFLA_MTU
: ('IFLA_MTU', AttributeFourByteValue
),
2946 IFLA_LINK
: ('IFLA_LINK', AttributeFourByteValue
),
2947 IFLA_QDISC
: ('IFLA_QDISC', AttributeString
),
2948 IFLA_STATS
: ('IFLA_STATS', AttributeGeneric
),
2949 IFLA_COST
: ('IFLA_COST', AttributeGeneric
),
2950 IFLA_PRIORITY
: ('IFLA_PRIORITY', AttributeGeneric
),
2951 IFLA_MASTER
: ('IFLA_MASTER', AttributeFourByteValue
),
2952 IFLA_WIRELESS
: ('IFLA_WIRELESS', AttributeGeneric
),
2953 IFLA_PROTINFO
: ('IFLA_PROTINFO', AttributeIFLA_PROTINFO
),
2954 IFLA_TXQLEN
: ('IFLA_TXQLEN', AttributeFourByteValue
),
2955 IFLA_MAP
: ('IFLA_MAP', AttributeGeneric
),
2956 IFLA_WEIGHT
: ('IFLA_WEIGHT', AttributeGeneric
),
2957 IFLA_OPERSTATE
: ('IFLA_OPERSTATE', AttributeOneByteValue
),
2958 IFLA_LINKMODE
: ('IFLA_LINKMODE', AttributeOneByteValue
),
2959 IFLA_LINKINFO
: ('IFLA_LINKINFO', AttributeIFLA_LINKINFO
),
2960 IFLA_NET_NS_PID
: ('IFLA_NET_NS_PID', AttributeGeneric
),
2961 IFLA_IFALIAS
: ('IFLA_IFALIAS', AttributeGeneric
),
2962 IFLA_NUM_VF
: ('IFLA_NUM_VF', AttributeGeneric
),
2963 IFLA_VFINFO_LIST
: ('IFLA_VFINFO_LIST', AttributeGeneric
),
2964 IFLA_STATS64
: ('IFLA_STATS64', AttributeGeneric
),
2965 IFLA_VF_PORTS
: ('IFLA_VF_PORTS', AttributeGeneric
),
2966 IFLA_PORT_SELF
: ('IFLA_PORT_SELF', AttributeGeneric
),
2967 IFLA_AF_SPEC
: ('IFLA_AF_SPEC', AttributeIFLA_AF_SPEC
),
2968 IFLA_GROUP
: ('IFLA_GROUP', AttributeFourByteValue
),
2969 IFLA_NET_NS_FD
: ('IFLA_NET_NS_FD', AttributeGeneric
),
2970 IFLA_EXT_MASK
: ('IFLA_EXT_MASK', AttributeFourByteValue
),
2971 IFLA_PROMISCUITY
: ('IFLA_PROMISCUITY', AttributeGeneric
),
2972 IFLA_NUM_TX_QUEUES
: ('IFLA_NUM_TX_QUEUES', AttributeGeneric
),
2973 IFLA_NUM_RX_QUEUES
: ('IFLA_NUM_RX_QUEUES', AttributeGeneric
),
2974 IFLA_CARRIER
: ('IFLA_CARRIER', AttributeGeneric
),
2975 IFLA_PHYS_PORT_ID
: ('IFLA_PHYS_PORT_ID', AttributeGeneric
),
2976 IFLA_CARRIER_CHANGES
: ('IFLA_CARRIER_CHANGES', AttributeGeneric
),
2977 IFLA_PHYS_SWITCH_ID
: ('IFLA_PHYS_SWITCH_ID', AttributeGeneric
),
2978 IFLA_LINK_NETNSID
: ('IFLA_LINK_NETNSID', AttributeGeneric
),
2979 IFLA_PHYS_PORT_NAME
: ('IFLA_PHYS_PORT_NAME', AttributeGeneric
),
2980 IFLA_PROTO_DOWN
: ('IFLA_PROTO_DOWN', AttributeOneByteValue
),
2981 IFLA_GSO_MAX_SEGS
: ('IFLA_GSO_MAX_SEGS', AttributeFourByteValue
),
2982 IFLA_GSO_MAX_SIZE
: ('IFLA_GSO_MAX_SIZE', AttributeFourByteValue
)
2986 # /usr/include/linux/if.h
2987 IFF_UP
= 0x0001 # Interface is administratively up.
2988 IFF_BROADCAST
= 0x0002 # Valid broadcast address set.
2989 IFF_DEBUG
= 0x0004 # Internal debugging flag.
2990 IFF_LOOPBACK
= 0x0008 # Interface is a loopback interface.
2991 IFF_POINTOPOINT
= 0x0010 # Interface is a point-to-point link.
2992 IFF_NOTRAILERS
= 0x0020 # Avoid use of trailers.
2993 IFF_RUNNING
= 0x0040 # Interface is operationally up.
2994 IFF_NOARP
= 0x0080 # No ARP protocol needed for this interface.
2995 IFF_PROMISC
= 0x0100 # Interface is in promiscuous mode.
2996 IFF_ALLMULTI
= 0x0200 # Receive all multicast packets.
2997 IFF_MASTER
= 0x0400 # Master of a load balancing bundle.
2998 IFF_SLAVE
= 0x0800 # Slave of a load balancing bundle.
2999 IFF_MULTICAST
= 0x1000 # Supports multicast.
3000 IFF_PORTSEL
= 0x2000 # Is able to select media type via ifmap.
3001 IFF_AUTOMEDIA
= 0x4000 # Auto media selection active.
3002 IFF_DYNAMIC
= 0x8000 # Interface was dynamically created.
3003 IFF_LOWER_UP
= 0x10000 # driver signals L1 up
3004 IFF_DORMANT
= 0x20000 # driver signals dormant
3005 IFF_ECHO
= 0x40000 # echo sent packet
3006 IFF_PROTO_DOWN
= 0x1000000 # protocol is down on the interface
3010 IFF_BROADCAST
: 'IFF_BROADCAST',
3011 IFF_DEBUG
: 'IFF_DEBUG',
3012 IFF_LOOPBACK
: 'IFF_LOOPBACK',
3013 IFF_POINTOPOINT
: 'IFF_POINTOPOINT',
3014 IFF_NOTRAILERS
: 'IFF_NOTRAILERS',
3015 IFF_RUNNING
: 'IFF_RUNNING',
3016 IFF_NOARP
: 'IFF_NOARP',
3017 IFF_PROMISC
: 'IFF_PROMISC',
3018 IFF_ALLMULTI
: 'IFF_ALLMULTI',
3019 IFF_MASTER
: 'IFF_MASTER',
3020 IFF_SLAVE
: 'IFF_SLAVE',
3021 IFF_MULTICAST
: 'IFF_MULTICAST',
3022 IFF_PORTSEL
: 'IFF_PORTSEL',
3023 IFF_AUTOMEDIA
: 'IFF_AUTOMEDIA',
3024 IFF_DYNAMIC
: 'IFF_DYNAMIC',
3025 IFF_LOWER_UP
: 'IFF_LOWER_UP',
3026 IFF_DORMANT
: 'IFF_DORMANT',
3027 IFF_ECHO
: 'IFF_ECHO',
3028 IFF_PROTO_DOWN
: 'IFF_PROTO_DOWN'
3031 # RFC 2863 operational status
3033 IF_OPER_NOTPRESENT
= 1
3035 IF_OPER_LOWERLAYERDOWN
= 3
3041 IF_OPER_UNKNOWN
: 'IF_OPER_UNKNOWN',
3042 IF_OPER_NOTPRESENT
: 'IF_OPER_NOTPRESENT',
3043 IF_OPER_DOWN
: 'IF_OPER_DOWN',
3044 IF_OPER_LOWERLAYERDOWN
: 'IF_OPER_LOWERLAYERDOWN',
3045 IF_OPER_TESTING
: 'IF_OPER_TESTING',
3046 IF_OPER_DORMANT
: 'IF_OPER_DORMANT',
3047 IF_OPER_UP
: 'IF_OPER_UP'
3051 # /usr/include/linux/if_arp.h
3052 # ARP protocol HARDWARE identifiers
3053 ARPHRD_NETROM
= 0 # from KA9Q: NET/ROM pseudo
3054 ARPHRD_ETHER
= 1 # Ethernet 10Mbps
3055 ARPHRD_EETHER
= 2 # Experimental Ethernet
3056 ARPHRD_AX25
= 3 # AX.25 Level 2
3057 ARPHRD_PRONET
= 4 # PROnet token ring
3058 ARPHRD_CHAOS
= 5 # Chaosnet
3059 ARPHRD_IEEE802
= 6 # IEEE 802.2 Ethernet/TR/TB
3060 ARPHRD_ARCNET
= 7 # ARCnet
3061 ARPHRD_APPLETLK
= 8 # APPLEtalk
3062 ARPHRD_DLCI
= 15 # Frame Relay DLCI
3063 ARPHRD_ATM
= 19 # ATM
3064 ARPHRD_METRICOM
= 23 # Metricom STRIP (new IANA id)
3065 ARPHRD_IEEE1394
= 24 # IEEE 1394 IPv4 - RFC 2734
3066 ARPHRD_EUI64
= 27 # EUI-64
3067 ARPHRD_INFINIBAND
= 32 # InfiniBand
3068 # Dummy types for non ARP hardware
3073 ARPHRD_RSRVD
= 260 # Notional KISS type
3076 ARPHRD_X25
= 271 # CCITT X.25
3077 ARPHRD_HWX25
= 272 # Boards with X.25 in firmware
3078 ARPHRD_CAN
= 280 # Controller Area Network
3080 ARPHRD_CISCO
= 513 # Cisco HDLC
3081 ARPHRD_HDLC
= ARPHRD_CISCO
3082 ARPHRD_LAPB
= 516 # LAPB
3083 ARPHRD_DDCMP
= 517 # Digital's DDCMP protocol
3084 ARPHRD_RAWHDLC
= 518 # Raw HDLC
3085 ARPHRD_TUNNEL
= 768 # IPIP tunnel
3086 ARPHRD_TUNNEL6
= 769 # IP6IP6 tunnel
3087 ARPHRD_FRAD
= 770 # Frame Relay Access Device
3088 ARPHRD_SKIP
= 771 # SKIP vif
3089 ARPHRD_LOOPBACK
= 772 # Loopback device
3090 ARPHRD_LOCALTLK
= 773 # Localtalk device
3091 ARPHRD_FDDI
= 774 # Fiber Distributed Data Interface
3092 ARPHRD_BIF
= 775 # AP1000 BIF
3093 ARPHRD_SIT
= 776 # sit0 device - IPv6-in-IPv4
3094 ARPHRD_IPDDP
= 777 # IP over DDP tunneller
3095 ARPHRD_IPGRE
= 778 # GRE over IP
3096 ARPHRD_PIMREG
= 779 # PIMSM register interface
3097 ARPHRD_HIPPI
= 780 # High Performance Parallel Interface
3098 ARPHRD_ASH
= 781 # Nexus 64Mbps Ash
3099 ARPHRD_ECONET
= 782 # Acorn Econet
3100 ARPHRD_IRDA
= 783 # Linux-IrDA
3101 ARPHRD_FCPP
= 784 # Point to point fibrechannel
3102 ARPHRD_FCAL
= 785 # Fibrechannel arbitrated loop
3103 ARPHRD_FCPL
= 786 # Fibrechannel public loop
3104 ARPHRD_FCFABRIC
= 787 # Fibrechannel fabric
3105 # 787->799 reserved for fibrechannel media types
3106 ARPHRD_IEEE802_TR
= 800 # Magic type ident for TR
3107 ARPHRD_IEEE80211
= 801 # IEEE 802.11
3108 ARPHRD_IEEE80211_PRISM
= 802 # IEEE 802.11 + Prism2 header
3109 ARPHRD_IEEE80211_RADIOTAP
= 803 # IEEE 802.11 + radiotap header
3110 ARPHRD_IEEE802154
= 804
3111 ARPHRD_PHONET
= 820 # PhoNet media type
3112 ARPHRD_PHONET_PIPE
= 821 # PhoNet pipe header
3113 ARPHRD_CAIF
= 822 # CAIF media type
3114 ARPHRD_VOID
= 0xFFFF # Void type, nothing is known
3115 ARPHRD_NONE
= 0xFFFE # zero header length
3117 link_type_to_string
= {
3118 ARPHRD_NETROM
: 'ARPHRD_NETROM',
3119 ARPHRD_ETHER
: 'ARPHRD_ETHER',
3120 ARPHRD_EETHER
: 'ARPHRD_EETHER',
3121 ARPHRD_AX25
: 'ARPHRD_AX25',
3122 ARPHRD_PRONET
: 'ARPHRD_PRONET',
3123 ARPHRD_CHAOS
: 'ARPHRD_CHAOS',
3124 ARPHRD_IEEE802
: 'ARPHRD_IEEE802',
3125 ARPHRD_ARCNET
: 'ARPHRD_ARCNET',
3126 ARPHRD_APPLETLK
: 'ARPHRD_APPLETLK',
3127 ARPHRD_DLCI
: 'ARPHRD_DLCI',
3128 ARPHRD_ATM
: 'ARPHRD_ATM',
3129 ARPHRD_METRICOM
: 'ARPHRD_METRICOM',
3130 ARPHRD_IEEE1394
: 'ARPHRD_IEEE1394',
3131 ARPHRD_EUI64
: 'ARPHRD_EUI64',
3132 ARPHRD_INFINIBAND
: 'ARPHRD_INFINIBAND',
3133 ARPHRD_SLIP
: 'ARPHRD_SLIP',
3134 ARPHRD_CSLIP
: 'ARPHRD_CSLIP',
3135 ARPHRD_SLIP6
: 'ARPHRD_SLIP6',
3136 ARPHRD_CSLIP6
: 'ARPHRD_CSLIP6',
3137 ARPHRD_RSRVD
: 'ARPHRD_RSRVD',
3138 ARPHRD_ADAPT
: 'ARPHRD_ADAPT',
3139 ARPHRD_ROSE
: 'ARPHRD_ROSE',
3140 ARPHRD_X25
: 'ARPHRD_X25',
3141 ARPHRD_HWX25
: 'ARPHRD_HWX25',
3142 ARPHRD_CAN
: 'ARPHRD_CAN',
3143 ARPHRD_PPP
: 'ARPHRD_PPP',
3144 ARPHRD_CISCO
: 'ARPHRD_CISCO',
3145 ARPHRD_HDLC
: 'ARPHRD_HDLC',
3146 ARPHRD_LAPB
: 'ARPHRD_LAPB',
3147 ARPHRD_DDCMP
: 'ARPHRD_DDCMP',
3148 ARPHRD_RAWHDLC
: 'ARPHRD_RAWHDLC',
3149 ARPHRD_TUNNEL
: 'ARPHRD_TUNNEL',
3150 ARPHRD_TUNNEL6
: 'ARPHRD_TUNNEL6',
3151 ARPHRD_FRAD
: 'ARPHRD_FRAD',
3152 ARPHRD_SKIP
: 'ARPHRD_SKIP',
3153 ARPHRD_LOOPBACK
: 'ARPHRD_LOOPBACK',
3154 ARPHRD_LOCALTLK
: 'ARPHRD_LOCALTLK',
3155 ARPHRD_FDDI
: 'ARPHRD_FDDI',
3156 ARPHRD_BIF
: 'ARPHRD_BIF',
3157 ARPHRD_SIT
: 'ARPHRD_SIT',
3158 ARPHRD_IPDDP
: 'ARPHRD_IPDDP',
3159 ARPHRD_IPGRE
: 'ARPHRD_IPGRE',
3160 ARPHRD_PIMREG
: 'ARPHRD_PIMREG',
3161 ARPHRD_HIPPI
: 'ARPHRD_HIPPI',
3162 ARPHRD_ASH
: 'ARPHRD_ASH',
3163 ARPHRD_ECONET
: 'ARPHRD_ECONET',
3164 ARPHRD_IRDA
: 'ARPHRD_IRDA',
3165 ARPHRD_FCPP
: 'ARPHRD_FCPP',
3166 ARPHRD_FCAL
: 'ARPHRD_FCAL',
3167 ARPHRD_FCPL
: 'ARPHRD_FCPL',
3168 ARPHRD_FCFABRIC
: 'ARPHRD_FCFABRIC',
3169 ARPHRD_IEEE802_TR
: 'ARPHRD_IEEE802_TR',
3170 ARPHRD_IEEE80211
: 'ARPHRD_IEEE80211',
3171 ARPHRD_IEEE80211_PRISM
: 'ARPHRD_IEEE80211_PRISM',
3172 ARPHRD_IEEE80211_RADIOTAP
: 'ARPHRD_IEEE80211_RADIOTAP',
3173 ARPHRD_IEEE802154
: 'ARPHRD_IEEE802154',
3174 ARPHRD_PHONET
: 'ARPHRD_PHONET',
3175 ARPHRD_PHONET_PIPE
: 'ARPHRD_PHONET_PIPE',
3176 ARPHRD_CAIF
: 'ARPHRD_CAIF',
3177 ARPHRD_VOID
: 'ARPHRD_VOID',
3178 ARPHRD_NONE
: 'ARPHRD_NONE'
3181 # =========================================
3182 # IFLA_LINKINFO attributes
3183 # =========================================
3184 IFLA_INFO_UNSPEC
= 0
3187 IFLA_INFO_XSTATS
= 3
3188 IFLA_INFO_SLAVE_KIND
= 4
3189 IFLA_INFO_SLAVE_DATA
= 5
3192 ifla_info_to_string
= {
3193 IFLA_INFO_UNSPEC
: 'IFLA_INFO_UNSPEC',
3194 IFLA_INFO_KIND
: 'IFLA_INFO_KIND',
3195 IFLA_INFO_DATA
: 'IFLA_INFO_DATA',
3196 IFLA_INFO_XSTATS
: 'IFLA_INFO_XSTATS',
3197 IFLA_INFO_SLAVE_KIND
: 'IFLA_INFO_SLAVE_KIND',
3198 IFLA_INFO_SLAVE_DATA
: 'IFLA_INFO_SLAVE_DATA',
3199 IFLA_INFO_MAX
: 'IFLA_INFO_MAX'
3202 # =========================================
3203 # IFLA_INFO_DATA attributes for vlan
3204 # =========================================
3205 IFLA_VLAN_UNSPEC
= 0
3208 IFLA_VLAN_EGRESS_QOS
= 3
3209 IFLA_VLAN_INGRESS_QOS
= 4
3210 IFLA_VLAN_PROTOCOL
= 5
3212 ifla_vlan_to_string
= {
3213 IFLA_VLAN_UNSPEC
: 'IFLA_VLAN_UNSPEC',
3214 IFLA_VLAN_ID
: 'IFLA_VLAN_ID',
3215 IFLA_VLAN_FLAGS
: 'IFLA_VLAN_FLAGS',
3216 IFLA_VLAN_EGRESS_QOS
: 'IFLA_VLAN_EGRESS_QOS',
3217 IFLA_VLAN_INGRESS_QOS
: 'IFLA_VLAN_INGRESS_QOS',
3218 IFLA_VLAN_PROTOCOL
: 'IFLA_VLAN_PROTOCOL'
3221 ifla_vlan_protocol_dict
= {
3234 # =========================================
3235 # IFLA_INFO_DATA attributes for macvlan
3236 # =========================================
3237 IFLA_MACVLAN_UNSPEC
= 0
3238 IFLA_MACVLAN_MODE
= 1
3240 ifla_macvlan_to_string
= {
3241 IFLA_MACVLAN_UNSPEC
: 'IFLA_MACVLAN_UNSPEC',
3242 IFLA_MACVLAN_MODE
: 'IFLA_MACVLAN_MODE'
3246 MACVLAN_MODE_PRIVATE
= 1
3247 MACVLAN_MODE_VEPA
= 2
3248 MACVLAN_MODE_BRIDGE
= 3
3249 MACVLAN_MODE_PASSTHRU
= 4
3251 macvlan_mode_to_string
= {
3252 MACVLAN_MODE_PRIVATE
: 'MACVLAN_MODE_PRIVATE',
3253 MACVLAN_MODE_VEPA
: 'MACVLAN_MODE_VEPA',
3254 MACVLAN_MODE_BRIDGE
: 'MACVLAN_MODE_BRIDGE',
3255 MACVLAN_MODE_PASSTHRU
: 'MACVLAN_MODE_PASSTHRU'
3258 # =========================================
3259 # IFLA_INFO_DATA attributes for xfrm
3260 # =========================================
3261 IFLA_XFRM_UNSPEC
= 0
3265 ifla_xfrm_to_string
= {
3266 IFLA_XFRM_UNSPEC
: 'IFLA_XFRM_UNSPEC',
3267 IFLA_XFRM_LINK
: 'IFLA_XFRM_LINK',
3268 IFLA_XFRM_IF_ID
: 'IFLA_XFRM_IF_ID'
3271 # =========================================
3272 # IFLA_INFO_DATA attributes for vxlan
3273 # =========================================
3274 IFLA_VXLAN_UNSPEC
= 0
3276 IFLA_VXLAN_GROUP
= 2
3278 IFLA_VXLAN_LOCAL
= 4
3281 IFLA_VXLAN_LEARNING
= 7
3282 IFLA_VXLAN_AGEING
= 8
3283 IFLA_VXLAN_LIMIT
= 9
3284 IFLA_VXLAN_PORT_RANGE
= 10
3285 IFLA_VXLAN_PROXY
= 11
3287 IFLA_VXLAN_L2MISS
= 13
3288 IFLA_VXLAN_L3MISS
= 14
3289 IFLA_VXLAN_PORT
= 15
3290 IFLA_VXLAN_GROUP6
= 16
3291 IFLA_VXLAN_LOCAL6
= 17
3292 IFLA_VXLAN_UDP_CSUM
= 18
3293 IFLA_VXLAN_UDP_ZERO_CSUM6_TX
= 19
3294 IFLA_VXLAN_UDP_ZERO_CSUM6_RX
= 20
3295 IFLA_VXLAN_REMCSUM_TX
= 21
3296 IFLA_VXLAN_REMCSUM_RX
= 22
3298 IFLA_VXLAN_REMCSUM_NOPARTIAL
= 24
3299 IFLA_VXLAN_COLLECT_METADATA
= 25
3300 IFLA_VXLAN_REPLICATION_NODE
= 253
3301 IFLA_VXLAN_REPLICATION_TYPE
= 254
3303 ifla_vxlan_to_string
= {
3304 IFLA_VXLAN_UNSPEC
: 'IFLA_VXLAN_UNSPEC',
3305 IFLA_VXLAN_ID
: 'IFLA_VXLAN_ID',
3306 IFLA_VXLAN_GROUP
: 'IFLA_VXLAN_GROUP',
3307 IFLA_VXLAN_LINK
: 'IFLA_VXLAN_LINK',
3308 IFLA_VXLAN_LOCAL
: 'IFLA_VXLAN_LOCAL',
3309 IFLA_VXLAN_TTL
: 'IFLA_VXLAN_TTL',
3310 IFLA_VXLAN_TOS
: 'IFLA_VXLAN_TOS',
3311 IFLA_VXLAN_LEARNING
: 'IFLA_VXLAN_LEARNING',
3312 IFLA_VXLAN_AGEING
: 'IFLA_VXLAN_AGEING',
3313 IFLA_VXLAN_LIMIT
: 'IFLA_VXLAN_LIMIT',
3314 IFLA_VXLAN_PORT_RANGE
: 'IFLA_VXLAN_PORT_RANGE',
3315 IFLA_VXLAN_PROXY
: 'IFLA_VXLAN_PROXY',
3316 IFLA_VXLAN_RSC
: 'IFLA_VXLAN_RSC',
3317 IFLA_VXLAN_L2MISS
: 'IFLA_VXLAN_L2MISS',
3318 IFLA_VXLAN_L3MISS
: 'IFLA_VXLAN_L3MISS',
3319 IFLA_VXLAN_PORT
: 'IFLA_VXLAN_PORT',
3320 IFLA_VXLAN_GROUP6
: 'IFLA_VXLAN_GROUP6',
3321 IFLA_VXLAN_LOCAL6
: 'IFLA_VXLAN_LOCAL6',
3322 IFLA_VXLAN_UDP_CSUM
: 'IFLA_VXLAN_UDP_CSUM',
3323 IFLA_VXLAN_UDP_ZERO_CSUM6_TX
: 'IFLA_VXLAN_UDP_ZERO_CSUM6_TX',
3324 IFLA_VXLAN_UDP_ZERO_CSUM6_RX
: 'IFLA_VXLAN_UDP_ZERO_CSUM6_RX',
3325 IFLA_VXLAN_REMCSUM_TX
: 'IFLA_VXLAN_REMCSUM_TX',
3326 IFLA_VXLAN_REMCSUM_RX
: 'IFLA_VXLAN_REMCSUM_RX',
3327 IFLA_VXLAN_GBP
: 'IFLA_VXLAN_GBP',
3328 IFLA_VXLAN_REMCSUM_NOPARTIAL
: 'IFLA_VXLAN_REMCSUM_NOPARTIAL',
3329 IFLA_VXLAN_COLLECT_METADATA
: 'IFLA_VXLAN_COLLECT_METADATA',
3330 IFLA_VXLAN_REPLICATION_NODE
: 'IFLA_VXLAN_REPLICATION_NODE',
3331 IFLA_VXLAN_REPLICATION_TYPE
: 'IFLA_VXLAN_REPLICATION_TYPE'
3334 # =========================================
3335 # IFLA_INFO_DATA attributes for bonds
3336 # =========================================
3337 IFLA_BOND_UNSPEC
= 0
3339 IFLA_BOND_ACTIVE_SLAVE
= 2
3340 IFLA_BOND_MIIMON
= 3
3341 IFLA_BOND_UPDELAY
= 4
3342 IFLA_BOND_DOWNDELAY
= 5
3343 IFLA_BOND_USE_CARRIER
= 6
3344 IFLA_BOND_ARP_INTERVAL
= 7
3345 IFLA_BOND_ARP_IP_TARGET
= 8
3346 IFLA_BOND_ARP_VALIDATE
= 9
3347 IFLA_BOND_ARP_ALL_TARGETS
= 10
3348 IFLA_BOND_PRIMARY
= 11
3349 IFLA_BOND_PRIMARY_RESELECT
= 12
3350 IFLA_BOND_FAIL_OVER_MAC
= 13
3351 IFLA_BOND_XMIT_HASH_POLICY
= 14
3352 IFLA_BOND_RESEND_IGMP
= 15
3353 IFLA_BOND_NUM_PEER_NOTIF
= 16
3354 IFLA_BOND_ALL_SLAVES_ACTIVE
= 17
3355 IFLA_BOND_MIN_LINKS
= 18
3356 IFLA_BOND_LP_INTERVAL
= 19
3357 IFLA_BOND_PACKETS_PER_SLAVE
= 20
3358 IFLA_BOND_AD_LACP_RATE
= 21
3359 IFLA_BOND_AD_SELECT
= 22
3360 IFLA_BOND_AD_INFO
= 23
3361 IFLA_BOND_AD_ACTOR_SYS_PRIO
= 24
3362 IFLA_BOND_AD_USER_PORT_KEY
= 25
3363 IFLA_BOND_AD_ACTOR_SYSTEM
= 26
3364 IFLA_BOND_AD_LACP_BYPASS
= 100
3366 ifla_bond_to_string
= {
3367 IFLA_BOND_UNSPEC
: 'IFLA_BOND_UNSPEC',
3368 IFLA_BOND_MODE
: 'IFLA_BOND_MODE',
3369 IFLA_BOND_ACTIVE_SLAVE
: 'IFLA_BOND_ACTIVE_SLAVE',
3370 IFLA_BOND_MIIMON
: 'IFLA_BOND_MIIMON',
3371 IFLA_BOND_UPDELAY
: 'IFLA_BOND_UPDELAY',
3372 IFLA_BOND_DOWNDELAY
: 'IFLA_BOND_DOWNDELAY',
3373 IFLA_BOND_USE_CARRIER
: 'IFLA_BOND_USE_CARRIER',
3374 IFLA_BOND_ARP_INTERVAL
: 'IFLA_BOND_ARP_INTERVAL',
3375 IFLA_BOND_ARP_IP_TARGET
: 'IFLA_BOND_ARP_IP_TARGET',
3376 IFLA_BOND_ARP_VALIDATE
: 'IFLA_BOND_ARP_VALIDATE',
3377 IFLA_BOND_ARP_ALL_TARGETS
: 'IFLA_BOND_ARP_ALL_TARGETS',
3378 IFLA_BOND_PRIMARY
: 'IFLA_BOND_PRIMARY',
3379 IFLA_BOND_PRIMARY_RESELECT
: 'IFLA_BOND_PRIMARY_RESELECT',
3380 IFLA_BOND_FAIL_OVER_MAC
: 'IFLA_BOND_FAIL_OVER_MAC',
3381 IFLA_BOND_XMIT_HASH_POLICY
: 'IFLA_BOND_XMIT_HASH_POLICY',
3382 IFLA_BOND_RESEND_IGMP
: 'IFLA_BOND_RESEND_IGMP',
3383 IFLA_BOND_NUM_PEER_NOTIF
: 'IFLA_BOND_NUM_PEER_NOTIF',
3384 IFLA_BOND_ALL_SLAVES_ACTIVE
: 'IFLA_BOND_ALL_SLAVES_ACTIVE',
3385 IFLA_BOND_MIN_LINKS
: 'IFLA_BOND_MIN_LINKS',
3386 IFLA_BOND_LP_INTERVAL
: 'IFLA_BOND_LP_INTERVAL',
3387 IFLA_BOND_PACKETS_PER_SLAVE
: 'IFLA_BOND_PACKETS_PER_SLAVE',
3388 IFLA_BOND_AD_LACP_RATE
: 'IFLA_BOND_AD_LACP_RATE',
3389 IFLA_BOND_AD_SELECT
: 'IFLA_BOND_AD_SELECT',
3390 IFLA_BOND_AD_INFO
: 'IFLA_BOND_AD_INFO',
3391 IFLA_BOND_AD_ACTOR_SYS_PRIO
: 'IFLA_BOND_AD_ACTOR_SYS_PRIO',
3392 IFLA_BOND_AD_USER_PORT_KEY
: 'IFLA_BOND_AD_USER_PORT_KEY',
3393 IFLA_BOND_AD_ACTOR_SYSTEM
: 'IFLA_BOND_AD_ACTOR_SYSTEM',
3394 IFLA_BOND_AD_LACP_BYPASS
: 'IFLA_BOND_AD_LACP_BYPASS'
3397 IFLA_BOND_AD_INFO_UNSPEC
= 0
3398 IFLA_BOND_AD_INFO_AGGREGATOR
= 1
3399 IFLA_BOND_AD_INFO_NUM_PORTS
= 2
3400 IFLA_BOND_AD_INFO_ACTOR_KEY
= 3
3401 IFLA_BOND_AD_INFO_PARTNER_KEY
= 4
3402 IFLA_BOND_AD_INFO_PARTNER_MAC
= 5
3404 ifla_bond_ad_to_string
= {
3405 IFLA_BOND_AD_INFO_UNSPEC
: 'IFLA_BOND_AD_INFO_UNSPEC',
3406 IFLA_BOND_AD_INFO_AGGREGATOR
: 'IFLA_BOND_AD_INFO_AGGREGATOR',
3407 IFLA_BOND_AD_INFO_NUM_PORTS
: 'IFLA_BOND_AD_INFO_NUM_PORTS',
3408 IFLA_BOND_AD_INFO_ACTOR_KEY
: 'IFLA_BOND_AD_INFO_ACTOR_KEY',
3409 IFLA_BOND_AD_INFO_PARTNER_KEY
: 'IFLA_BOND_AD_INFO_PARTNER_KEY',
3410 IFLA_BOND_AD_INFO_PARTNER_MAC
: 'IFLA_BOND_AD_INFO_PARTNER_MAC'
3413 ifla_bond_mode_tbl
= {
3437 ifla_bond_mode_pretty_tbl
= {
3447 ifla_bond_xmit_hash_policy_tbl
= {
3465 ifla_bond_xmit_hash_policy_pretty_tbl
= {
3473 # =========================================
3474 # IFLA_INFO_SLAVE_DATA attributes for bonds
3475 # =========================================
3476 IFLA_BOND_SLAVE_UNSPEC
= 0
3477 IFLA_BOND_SLAVE_STATE
= 1
3478 IFLA_BOND_SLAVE_MII_STATUS
= 2
3479 IFLA_BOND_SLAVE_LINK_FAILURE_COUNT
= 3
3480 IFLA_BOND_SLAVE_PERM_HWADDR
= 4
3481 IFLA_BOND_SLAVE_QUEUE_ID
= 5
3482 IFLA_BOND_SLAVE_AD_AGGREGATOR_ID
= 6
3483 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE
= 7
3484 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
= 8
3485 IFLA_BOND_SLAVE_CL_START
= 50
3486 IFLA_BOND_SLAVE_AD_RX_BYPASS
= IFLA_BOND_SLAVE_CL_START
3488 ifla_bond_slave_to_string
= {
3489 IFLA_BOND_SLAVE_UNSPEC
: 'IFLA_BOND_SLAVE_UNSPEC',
3490 IFLA_BOND_SLAVE_STATE
: 'IFLA_BOND_SLAVE_STATE',
3491 IFLA_BOND_SLAVE_MII_STATUS
: 'IFLA_BOND_SLAVE_MII_STATUS',
3492 IFLA_BOND_SLAVE_LINK_FAILURE_COUNT
: 'IFLA_BOND_SLAVE_LINK_FAILURE_COUNT',
3493 IFLA_BOND_SLAVE_PERM_HWADDR
: 'IFLA_BOND_SLAVE_PERM_HWADDR',
3494 IFLA_BOND_SLAVE_QUEUE_ID
: 'IFLA_BOND_SLAVE_QUEUE_ID',
3495 IFLA_BOND_SLAVE_AD_AGGREGATOR_ID
: 'IFLA_BOND_SLAVE_AD_AGGREGATOR_ID',
3496 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE
: 'IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE',
3497 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
: 'IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE',
3498 IFLA_BOND_SLAVE_CL_START
: 'IFLA_BOND_SLAVE_CL_START',
3499 IFLA_BOND_SLAVE_AD_RX_BYPASS
: 'IFLA_BOND_SLAVE_AD_RX_BYPASS'
3502 # =========================================
3503 # IFLA_PROTINFO attributes for bridge ports
3504 # =========================================
3505 IFLA_BRPORT_UNSPEC
= 0
3506 IFLA_BRPORT_STATE
= 1
3507 IFLA_BRPORT_PRIORITY
= 2
3508 IFLA_BRPORT_COST
= 3
3509 IFLA_BRPORT_MODE
= 4
3510 IFLA_BRPORT_GUARD
= 5
3511 IFLA_BRPORT_PROTECT
= 6
3512 IFLA_BRPORT_FAST_LEAVE
= 7
3513 IFLA_BRPORT_LEARNING
= 8
3514 IFLA_BRPORT_UNICAST_FLOOD
= 9
3515 IFLA_BRPORT_PROXYARP
= 10
3516 IFLA_BRPORT_LEARNING_SYNC
= 11
3517 IFLA_BRPORT_PROXYARP_WIFI
= 12
3518 IFLA_BRPORT_ROOT_ID
= 13
3519 IFLA_BRPORT_BRIDGE_ID
= 14
3520 IFLA_BRPORT_DESIGNATED_PORT
= 15
3521 IFLA_BRPORT_DESIGNATED_COST
= 16
3524 IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
= 19
3525 IFLA_BRPORT_CONFIG_PENDING
= 20
3526 IFLA_BRPORT_MESSAGE_AGE_TIMER
= 21
3527 IFLA_BRPORT_FORWARD_DELAY_TIMER
= 22
3528 IFLA_BRPORT_HOLD_TIMER
= 23
3529 IFLA_BRPORT_FLUSH
= 24
3530 IFLA_BRPORT_MULTICAST_ROUTER
= 25
3531 IFLA_BRPORT_PAD
= 26
3532 IFLA_BRPORT_MCAST_FLOOD
= 27
3533 IFLA_BRPORT_MCAST_TO_UCAST
= 28
3534 IFLA_BRPORT_VLAN_TUNNEL
= 29
3535 IFLA_BRPORT_BCAST_FLOOD
= 30
3536 IFLA_BRPORT_GROUP_FWD_MASK
= 31
3537 IFLA_BRPORT_ARP_SUPPRESS
= 32
3538 IFLA_BRPORT_PEER_LINK
= 150
3539 IFLA_BRPORT_DUAL_LINK
= 151
3540 IFLA_BRPORT_GROUP_FWD_MASKHI
= 153
3541 IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
= 154
3543 ifla_brport_to_string
= {
3544 IFLA_BRPORT_UNSPEC
: 'IFLA_BRPORT_UNSPEC',
3545 IFLA_BRPORT_STATE
: 'IFLA_BRPORT_STATE',
3546 IFLA_BRPORT_PRIORITY
: 'IFLA_BRPORT_PRIORITY',
3547 IFLA_BRPORT_COST
: 'IFLA_BRPORT_COST',
3548 IFLA_BRPORT_MODE
: 'IFLA_BRPORT_MODE',
3549 IFLA_BRPORT_GUARD
: 'IFLA_BRPORT_GUARD',
3550 IFLA_BRPORT_PROTECT
: 'IFLA_BRPORT_PROTECT',
3551 IFLA_BRPORT_FAST_LEAVE
: 'IFLA_BRPORT_FAST_LEAVE',
3552 IFLA_BRPORT_LEARNING
: 'IFLA_BRPORT_LEARNING',
3553 IFLA_BRPORT_UNICAST_FLOOD
: 'IFLA_BRPORT_UNICAST_FLOOD',
3554 IFLA_BRPORT_PROXYARP
: 'IFLA_BRPORT_PROXYARP',
3555 IFLA_BRPORT_LEARNING_SYNC
: 'IFLA_BRPORT_LEARNING_SYNC',
3556 IFLA_BRPORT_PROXYARP_WIFI
: 'IFLA_BRPORT_PROXYARP_WIFI',
3557 IFLA_BRPORT_ROOT_ID
: 'IFLA_BRPORT_ROOT_ID',
3558 IFLA_BRPORT_BRIDGE_ID
: 'IFLA_BRPORT_BRIDGE_ID',
3559 IFLA_BRPORT_DESIGNATED_PORT
: 'IFLA_BRPORT_DESIGNATED_PORT',
3560 IFLA_BRPORT_DESIGNATED_COST
: 'IFLA_BRPORT_DESIGNATED_COST',
3561 IFLA_BRPORT_ID
: 'IFLA_BRPORT_ID',
3562 IFLA_BRPORT_NO
: 'IFLA_BRPORT_NO',
3563 IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
: 'IFLA_BRPORT_TOPOLOGY_CHANGE_ACK',
3564 IFLA_BRPORT_CONFIG_PENDING
: 'IFLA_BRPORT_CONFIG_PENDING',
3565 IFLA_BRPORT_MESSAGE_AGE_TIMER
: 'IFLA_BRPORT_MESSAGE_AGE_TIMER',
3566 IFLA_BRPORT_FORWARD_DELAY_TIMER
: 'IFLA_BRPORT_FORWARD_DELAY_TIMER',
3567 IFLA_BRPORT_HOLD_TIMER
: 'IFLA_BRPORT_HOLD_TIMER',
3568 IFLA_BRPORT_FLUSH
: 'IFLA_BRPORT_FLUSH',
3569 IFLA_BRPORT_MULTICAST_ROUTER
: 'IFLA_BRPORT_MULTICAST_ROUTER',
3570 IFLA_BRPORT_PAD
: 'IFLA_BRPORT_PAD',
3571 IFLA_BRPORT_MCAST_FLOOD
: 'IFLA_BRPORT_MCAST_FLOOD',
3572 IFLA_BRPORT_MCAST_TO_UCAST
: 'IFLA_BRPORT_MCAST_TO_UCAST',
3573 IFLA_BRPORT_VLAN_TUNNEL
: 'IFLA_BRPORT_VLAN_TUNNEL',
3574 IFLA_BRPORT_BCAST_FLOOD
: 'IFLA_BRPORT_BCAST_FLOOD',
3575 IFLA_BRPORT_GROUP_FWD_MASK
: 'IFLA_BRPORT_GROUP_FWD_MASK',
3576 IFLA_BRPORT_PEER_LINK
: 'IFLA_BRPORT_PEER_LINK',
3577 IFLA_BRPORT_DUAL_LINK
: 'IFLA_BRPORT_DUAL_LINK',
3578 IFLA_BRPORT_ARP_SUPPRESS
: 'IFLA_BRPORT_ARP_SUPPRESS',
3579 IFLA_BRPORT_GROUP_FWD_MASKHI
: 'IFLA_BRPORT_GROUP_FWD_MASKHI',
3580 IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
: 'IFLA_BRPORT_DOWN_PEERLINK_REDIRECT'
3583 # Subtype attributes for IFLA_AF_SPEC
3584 IFLA_INET6_UNSPEC
= 0
3585 IFLA_INET6_FLAGS
= 1 # link flags
3586 IFLA_INET6_CONF
= 2 # sysctl parameters
3587 IFLA_INET6_STATS
= 3 # statistics
3588 IFLA_INET6_MCAST
= 4 # MC things. What of them?
3589 IFLA_INET6_CACHEINFO
= 5 # time values and max reasm size
3590 IFLA_INET6_ICMP6STATS
= 6 # statistics (icmpv6)
3591 IFLA_INET6_TOKEN
= 7 # device token
3592 IFLA_INET6_ADDR_GEN_MODE
= 8 # implicit address generator mode
3593 __IFLA_INET6_MAX
= 9
3595 ifla_inet6_af_spec_to_string
= {
3596 IFLA_INET6_UNSPEC
: 'IFLA_INET6_UNSPEC',
3597 IFLA_INET6_FLAGS
: 'IFLA_INET6_FLAGS',
3598 IFLA_INET6_CONF
: 'IFLA_INET6_CONF',
3599 IFLA_INET6_STATS
: 'IFLA_INET6_STATS',
3600 IFLA_INET6_MCAST
: 'IFLA_INET6_MCAST',
3601 IFLA_INET6_CACHEINFO
: 'IFLA_INET6_CACHEINFO',
3602 IFLA_INET6_ICMP6STATS
: 'IFLA_INET6_ICMP6STATS',
3603 IFLA_INET6_TOKEN
: 'IFLA_INET6_TOKEN',
3604 IFLA_INET6_ADDR_GEN_MODE
: 'IFLA_INET6_ADDR_GEN_MODE',
3607 # IFLA_INET6_ADDR_GEN_MODE values
3608 IN6_ADDR_GEN_MODE_EUI64
= 0
3609 IN6_ADDR_GEN_MODE_NONE
= 1
3610 IN6_ADDR_GEN_MODE_STABLE_PRIVACY
= 2
3611 IN6_ADDR_GEN_MODE_RANDOM
= 3
3613 ifla_inet6_addr_gen_mode_dict
= {
3614 IN6_ADDR_GEN_MODE_EUI64
: "eui64",
3615 IN6_ADDR_GEN_MODE_NONE
: "none",
3616 IN6_ADDR_GEN_MODE_STABLE_PRIVACY
: "stable_secret",
3617 IN6_ADDR_GEN_MODE_RANDOM
: "random"
3620 # Subtype attrbutes AF_INET
3621 IFLA_INET_UNSPEC
= 0
3625 ifla_inet_af_spec_to_string
= {
3626 IFLA_INET_UNSPEC
: 'IFLA_INET_UNSPEC',
3627 IFLA_INET_CONF
: 'IFLA_INET_CONF',
3630 # BRIDGE IFLA_AF_SPEC attributes
3631 IFLA_BRIDGE_FLAGS
= 0
3632 IFLA_BRIDGE_MODE
= 1
3633 IFLA_BRIDGE_VLAN_INFO
= 2
3635 ifla_bridge_af_spec_to_string
= {
3636 IFLA_BRIDGE_FLAGS
: 'IFLA_BRIDGE_FLAGS',
3637 IFLA_BRIDGE_MODE
: 'IFLA_BRIDGE_MODE',
3638 IFLA_BRIDGE_VLAN_INFO
: 'IFLA_BRIDGE_VLAN_INFO'
3641 # BRIDGE_VLAN_INFO flags
3642 BRIDGE_VLAN_INFO_MASTER
= 1 << 0 # Operate on Bridge device as well
3643 BRIDGE_VLAN_INFO_PVID
= 1 << 1 # VLAN is PVID, ingress untagged
3644 BRIDGE_VLAN_INFO_UNTAGGED
= 1 << 2 # VLAN egresses untagged
3645 BRIDGE_VLAN_INFO_RANGE_BEGIN
= 1 << 3 # VLAN is start of vlan range
3646 BRIDGE_VLAN_INFO_RANGE_END
= 1 << 4 # VLAN is end of vlan range
3647 BRIDGE_VLAN_INFO_BRENTRY
= 1 << 5 # Global bridge VLAN entry
3649 bridge_vlan_to_string
= {
3650 BRIDGE_VLAN_INFO_MASTER
: 'BRIDGE_VLAN_INFO_MASTER',
3651 BRIDGE_VLAN_INFO_PVID
: 'BRIDGE_VLAN_INFO_PVID',
3652 BRIDGE_VLAN_INFO_UNTAGGED
: 'BRIDGE_VLAN_INFO_UNTAGGED',
3653 BRIDGE_VLAN_INFO_RANGE_BEGIN
: 'BRIDGE_VLAN_INFO_RANGE_BEGIN',
3654 BRIDGE_VLAN_INFO_RANGE_END
: 'BRIDGE_VLAN_INFO_RANGE_END',
3655 BRIDGE_VLAN_INFO_BRENTRY
: 'BRIDGE_VLAN_INFO_BRENTRY'
3659 BRIDGE_FLAGS_MASTER
= 1
3660 BRIDGE_FLAGS_SELF
= 2
3662 bridge_flags_to_string
= {
3663 BRIDGE_FLAGS_MASTER
: 'BRIDGE_FLAGS_MASTER',
3664 BRIDGE_FLAGS_SELF
: 'BRIDGE_FLAGS_SELF'
3667 # filters for IFLA_EXT_MASK
3668 RTEXT_FILTER_VF
= 1 << 0
3669 RTEXT_FILTER_BRVLAN
= 1 << 1
3670 RTEXT_FILTER_BRVLAN_COMPRESSED
= 1 << 2
3671 RTEXT_FILTER_SKIP_STATS
= 1 << 3
3674 RTEXT_FILTER_VF
: 'RTEXT_FILTER_VF',
3675 RTEXT_FILTER_BRVLAN
: 'RTEXT_FILTER_BRVLAN',
3676 RTEXT_FILTER_BRVLAN_COMPRESSED
: 'RTEXT_FILTER_BRVLAN_COMPRESSED',
3677 RTEXT_FILTER_SKIP_STATS
: 'RTEXT_FILTER_SKIP_STATS'
3681 IFLA_BR_FORWARD_DELAY
= 1
3682 IFLA_BR_HELLO_TIME
= 2
3684 IFLA_BR_AGEING_TIME
= 4
3685 IFLA_BR_STP_STATE
= 5
3686 IFLA_BR_PRIORITY
= 6
3687 IFLA_BR_VLAN_FILTERING
= 7
3688 IFLA_BR_VLAN_PROTOCOL
= 8
3689 IFLA_BR_GROUP_FWD_MASK
= 9
3690 IFLA_BR_ROOT_ID
= 10
3691 IFLA_BR_BRIDGE_ID
= 11
3692 IFLA_BR_ROOT_PORT
= 12
3693 IFLA_BR_ROOT_PATH_COST
= 13
3694 IFLA_BR_TOPOLOGY_CHANGE
= 14
3695 IFLA_BR_TOPOLOGY_CHANGE_DETECTED
= 15
3696 IFLA_BR_HELLO_TIMER
= 16
3697 IFLA_BR_TCN_TIMER
= 17
3698 IFLA_BR_TOPOLOGY_CHANGE_TIMER
= 18
3699 IFLA_BR_GC_TIMER
= 19
3700 IFLA_BR_GROUP_ADDR
= 20
3701 IFLA_BR_FDB_FLUSH
= 21
3702 IFLA_BR_MCAST_ROUTER
= 22
3703 IFLA_BR_MCAST_SNOOPING
= 23
3704 IFLA_BR_MCAST_QUERY_USE_IFADDR
= 24
3705 IFLA_BR_MCAST_QUERIER
= 25
3706 IFLA_BR_MCAST_HASH_ELASTICITY
= 26
3707 IFLA_BR_MCAST_HASH_MAX
= 27
3708 IFLA_BR_MCAST_LAST_MEMBER_CNT
= 28
3709 IFLA_BR_MCAST_STARTUP_QUERY_CNT
= 29
3710 IFLA_BR_MCAST_LAST_MEMBER_INTVL
= 30
3711 IFLA_BR_MCAST_MEMBERSHIP_INTVL
= 31
3712 IFLA_BR_MCAST_QUERIER_INTVL
= 32
3713 IFLA_BR_MCAST_QUERY_INTVL
= 33
3714 IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
= 34
3715 IFLA_BR_MCAST_STARTUP_QUERY_INTVL
= 35
3716 IFLA_BR_NF_CALL_IPTABLES
= 36
3717 IFLA_BR_NF_CALL_IP6TABLES
= 37
3718 IFLA_BR_NF_CALL_ARPTABLES
= 38
3719 IFLA_BR_VLAN_DEFAULT_PVID
= 39
3721 IFLA_BR_VLAN_STATS_ENABLED
= 41
3722 IFLA_BR_MCAST_STATS_ENABLED
= 42
3723 IFLA_BR_MCAST_IGMP_VERSION
= 43
3724 IFLA_BR_MCAST_MLD_VERSION
= 44
3726 ifla_br_to_string
= {
3727 IFLA_BR_UNSPEC
: 'IFLA_BR_UNSPEC',
3728 IFLA_BR_FORWARD_DELAY
: 'IFLA_BR_FORWARD_DELAY',
3729 IFLA_BR_HELLO_TIME
: 'IFLA_BR_HELLO_TIME',
3730 IFLA_BR_MAX_AGE
: 'IFLA_BR_MAX_AGE',
3731 IFLA_BR_AGEING_TIME
: 'IFLA_BR_AGEING_TIME',
3732 IFLA_BR_STP_STATE
: 'IFLA_BR_STP_STATE',
3733 IFLA_BR_PRIORITY
: 'IFLA_BR_PRIORITY',
3734 IFLA_BR_VLAN_FILTERING
: 'IFLA_BR_VLAN_FILTERING',
3735 IFLA_BR_VLAN_PROTOCOL
: 'IFLA_BR_VLAN_PROTOCOL',
3736 IFLA_BR_GROUP_FWD_MASK
: 'IFLA_BR_GROUP_FWD_MASK',
3737 IFLA_BR_ROOT_ID
: 'IFLA_BR_ROOT_ID',
3738 IFLA_BR_BRIDGE_ID
: 'IFLA_BR_BRIDGE_ID',
3739 IFLA_BR_ROOT_PORT
: 'IFLA_BR_ROOT_PORT',
3740 IFLA_BR_ROOT_PATH_COST
: 'IFLA_BR_ROOT_PATH_COST',
3741 IFLA_BR_TOPOLOGY_CHANGE
: 'IFLA_BR_TOPOLOGY_CHANGE',
3742 IFLA_BR_TOPOLOGY_CHANGE_DETECTED
: 'IFLA_BR_TOPOLOGY_CHANGE_DETECTED',
3743 IFLA_BR_HELLO_TIMER
: 'IFLA_BR_HELLO_TIMER',
3744 IFLA_BR_TCN_TIMER
: 'IFLA_BR_TCN_TIMER',
3745 IFLA_BR_TOPOLOGY_CHANGE_TIMER
: 'IFLA_BR_TOPOLOGY_CHANGE_TIMER',
3746 IFLA_BR_GC_TIMER
: 'IFLA_BR_GC_TIMER',
3747 IFLA_BR_GROUP_ADDR
: 'IFLA_BR_GROUP_ADDR',
3748 IFLA_BR_FDB_FLUSH
: 'IFLA_BR_FDB_FLUSH',
3749 IFLA_BR_MCAST_ROUTER
: 'IFLA_BR_MCAST_ROUTER',
3750 IFLA_BR_MCAST_SNOOPING
: 'IFLA_BR_MCAST_SNOOPING',
3751 IFLA_BR_MCAST_QUERY_USE_IFADDR
: 'IFLA_BR_MCAST_QUERY_USE_IFADDR',
3752 IFLA_BR_MCAST_QUERIER
: 'IFLA_BR_MCAST_QUERIER',
3753 IFLA_BR_MCAST_HASH_ELASTICITY
: 'IFLA_BR_MCAST_HASH_ELASTICITY',
3754 IFLA_BR_MCAST_HASH_MAX
: 'IFLA_BR_MCAST_HASH_MAX',
3755 IFLA_BR_MCAST_LAST_MEMBER_CNT
: 'IFLA_BR_MCAST_LAST_MEMBER_CNT',
3756 IFLA_BR_MCAST_STARTUP_QUERY_CNT
: 'IFLA_BR_MCAST_STARTUP_QUERY_CNT',
3757 IFLA_BR_MCAST_LAST_MEMBER_INTVL
: 'IFLA_BR_MCAST_LAST_MEMBER_INTVL',
3758 IFLA_BR_MCAST_MEMBERSHIP_INTVL
: 'IFLA_BR_MCAST_MEMBERSHIP_INTVL',
3759 IFLA_BR_MCAST_QUERIER_INTVL
: 'IFLA_BR_MCAST_QUERIER_INTVL',
3760 IFLA_BR_MCAST_QUERY_INTVL
: 'IFLA_BR_MCAST_QUERY_INTVL',
3761 IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
: 'IFLA_BR_MCAST_QUERY_RESPONSE_INTVL',
3762 IFLA_BR_MCAST_STARTUP_QUERY_INTVL
: 'IFLA_BR_MCAST_STARTUP_QUERY_INTVL',
3763 IFLA_BR_NF_CALL_IPTABLES
: 'IFLA_BR_NF_CALL_IPTABLES',
3764 IFLA_BR_NF_CALL_IP6TABLES
: 'IFLA_BR_NF_CALL_IP6TABLES',
3765 IFLA_BR_NF_CALL_ARPTABLES
: 'IFLA_BR_NF_CALL_ARPTABLES',
3766 IFLA_BR_VLAN_DEFAULT_PVID
: 'IFLA_BR_VLAN_DEFAULT_PVID',
3767 IFLA_BR_PAD
: 'IFLA_BR_PAD',
3768 IFLA_BR_VLAN_STATS_ENABLED
: 'IFLA_BR_VLAN_STATS_ENABLED',
3769 IFLA_BR_MCAST_STATS_ENABLED
: 'IFLA_BR_MCAST_STATS_ENABLED',
3770 IFLA_BR_MCAST_IGMP_VERSION
: 'IFLA_BR_MCAST_IGMP_VERSION',
3771 IFLA_BR_MCAST_MLD_VERSION
: 'IFLA_BR_MCAST_MLD_VERSION'
3774 # =========================================
3775 # IFLA_INFO_DATA attributes for vrfs
3776 # =========================================
3780 ifla_vrf_to_string
= {
3781 IFLA_VRF_UNSPEC
: 'IFLA_VRF_UNSPEC',
3782 IFLA_VRF_TABLE
: 'IFLA_VRF_TABLE'
3785 # ================================================================
3786 # IFLA_INFO_DATA attributes for (ip6)gre, (ip6)gretap, (ip6)erspan
3787 # ================================================================
3798 IFLA_GRE_PMTUDISC
= 10
3799 IFLA_GRE_ENCAP_LIMIT
= 11
3800 IFLA_GRE_FLOWINFO
= 12
3802 IFLA_GRE_ENCAP_TYPE
= 14
3803 IFLA_GRE_ENCAP_FLAGS
= 15
3804 IFLA_GRE_ENCAP_SPORT
= 16
3805 IFLA_GRE_ENCAP_DPORT
= 17
3806 IFLA_GRE_COLLECT_METADATA
= 18
3807 IFLA_GRE_IGNORE_DF
= 19
3808 IFLA_GRE_FWMARK
= 20
3809 IFLA_GRE_ERSPAN_INDEX
= 21
3810 IFLA_GRE_ERSPAN_VER
= 22
3811 IFLA_GRE_ERSPAN_DIR
= 23
3812 IFLA_GRE_ERSPAN_HWID
= 24
3814 ifla_gre_to_string
= {
3815 IFLA_GRE_UNSPEC
: "IFLA_GRE_UNSPEC",
3816 IFLA_GRE_LINK
: "IFLA_GRE_LINK",
3817 IFLA_GRE_IFLAGS
: "IFLA_GRE_IFLAGS",
3818 IFLA_GRE_OFLAGS
: "IFLA_GRE_OFLAGS",
3819 IFLA_GRE_IKEY
: "IFLA_GRE_IKEY",
3820 IFLA_GRE_OKEY
: "IFLA_GRE_OKEY",
3821 IFLA_GRE_LOCAL
: "IFLA_GRE_LOCAL",
3822 IFLA_GRE_REMOTE
: "IFLA_GRE_REMOTE",
3823 IFLA_GRE_TTL
: "IFLA_GRE_TTL",
3824 IFLA_GRE_TOS
: "IFLA_GRE_TOS",
3825 IFLA_GRE_PMTUDISC
: "IFLA_GRE_PMTUDISC",
3826 IFLA_GRE_ENCAP_LIMIT
: "IFLA_GRE_ENCAP_LIMIT",
3827 IFLA_GRE_FLOWINFO
: "IFLA_GRE_FLOWINFO",
3828 IFLA_GRE_FLAGS
: "IFLA_GRE_FLAGS",
3829 IFLA_GRE_ENCAP_TYPE
: "IFLA_GRE_ENCAP_TYPE",
3830 IFLA_GRE_ENCAP_FLAGS
: "IFLA_GRE_ENCAP_FLAGS",
3831 IFLA_GRE_ENCAP_SPORT
: "IFLA_GRE_ENCAP_SPORT",
3832 IFLA_GRE_ENCAP_DPORT
: "IFLA_GRE_ENCAP_DPORT",
3833 IFLA_GRE_COLLECT_METADATA
: "IFLA_GRE_COLLECT_METADATA",
3834 IFLA_GRE_IGNORE_DF
: "IFLA_GRE_IGNORE_DF",
3835 IFLA_GRE_FWMARK
: "IFLA_GRE_FWMARK",
3836 IFLA_GRE_ERSPAN_INDEX
: "IFLA_GRE_ERSPAN_INDEX",
3837 IFLA_GRE_ERSPAN_VER
: "IFLA_GRE_ERSPAN_VER",
3838 IFLA_GRE_ERSPAN_DIR
: "IFLA_GRE_ERSPAN_DIR",
3839 IFLA_GRE_ERSPAN_HWID
: "IFLA_GRE_ERSPAN_HWID",
3842 # ===============================================
3843 # IFLA_INFO_DATA attributes for ipip, sit, ip6tnl
3844 # ===============================================
3845 IFLA_IPTUN_UNSPEC
= 0
3847 IFLA_IPTUN_LOCAL
= 2
3848 IFLA_IPTUN_REMOTE
= 3
3851 IFLA_IPTUN_ENCAP_LIMIT
= 6
3852 IFLA_IPTUN_FLOWINFO
= 7
3853 IFLA_IPTUN_FLAGS
= 8
3854 IFLA_IPTUN_PROTO
= 9
3855 IFLA_IPTUN_PMTUDISC
= 10
3856 IFLA_IPTUN_6RD_PREFIX
= 11
3857 IFLA_IPTUN_6RD_RELAY_PREFIX
= 12
3858 IFLA_IPTUN_6RD_PREFIXLEN
= 13
3859 IFLA_IPTUN_6RD_RELAY_PREFIXLEN
= 14
3860 IFLA_IPTUN_ENCAP_TYPE
= 15
3861 IFLA_IPTUN_ENCAP_FLAGS
= 16
3862 IFLA_IPTUN_ENCAP_SPORT
= 17
3863 IFLA_IPTUN_ENCAP_DPORT
= 18
3864 IFLA_IPTUN_COLLECT_METADATA
= 19
3865 IFLA_IPTUN_FWMARK
= 20
3867 ifla_iptun_to_string
= {
3868 IFLA_IPTUN_UNSPEC
: "IFLA_IPTUN_UNSPEC",
3869 IFLA_IPTUN_LINK
: "IFLA_IPTUN_LINK",
3870 IFLA_IPTUN_LOCAL
: "IFLA_IPTUN_LOCAL",
3871 IFLA_IPTUN_REMOTE
: "IFLA_IPTUN_REMOTE",
3872 IFLA_IPTUN_TTL
: "IFLA_IPTUN_TTL",
3873 IFLA_IPTUN_TOS
: "IFLA_IPTUN_TOS",
3874 IFLA_IPTUN_ENCAP_LIMIT
: "IFLA_IPTUN_ENCAP_LIMIT",
3875 IFLA_IPTUN_FLOWINFO
: "IFLA_IPTUN_FLOWINFO",
3876 IFLA_IPTUN_FLAGS
: "IFLA_IPTUN_FLAGS",
3877 IFLA_IPTUN_PROTO
: "IFLA_IPTUN_PROTO",
3878 IFLA_IPTUN_PMTUDISC
: "IFLA_IPTUN_PMTUDISC",
3879 IFLA_IPTUN_6RD_PREFIX
: "IFLA_IPTUN_6RD_PREFIX",
3880 IFLA_IPTUN_6RD_RELAY_PREFIX
: "IFLA_IPTUN_6RD_RELAY_PREFIX",
3881 IFLA_IPTUN_6RD_PREFIXLEN
: "IFLA_IPTUN_6RD_PREFIXLEN",
3882 IFLA_IPTUN_6RD_RELAY_PREFIXLEN
: "IFLA_IPTUN_6RD_RELAY_PREFIXLEN",
3883 IFLA_IPTUN_ENCAP_TYPE
: "IFLA_IPTUN_ENCAP_TYPE",
3884 IFLA_IPTUN_ENCAP_FLAGS
: "IFLA_IPTUN_ENCAP_FLAGS",
3885 IFLA_IPTUN_ENCAP_SPORT
: "IFLA_IPTUN_ENCAP_SPORT",
3886 IFLA_IPTUN_ENCAP_DPORT
: "IFLA_IPTUN_ENCAP_DPORT",
3887 IFLA_IPTUN_COLLECT_METADATA
: "IFLA_IPTUN_COLLECT_METADATA",
3888 IFLA_IPTUN_FWMARK
: "IFLA_IPTUN_FWMARK",
3891 # =========================================
3892 # IFLA_INFO_DATA attributes for vti, vti6
3893 # =========================================
3902 ifla_vti_to_string
= {
3903 IFLA_VTI_UNSPEC
: "IFLA_VTI_UNSPEC",
3904 IFLA_VTI_LINK
: "IFLA_VTI_LINK",
3905 IFLA_VTI_IKEY
: "IFLA_VTI_IKEY",
3906 IFLA_VTI_OKEY
: "IFLA_VTI_OKEY",
3907 IFLA_VTI_LOCAL
: "IFLA_VTI_LOCAL",
3908 IFLA_VTI_REMOTE
: "IFLA_VTI_REMOTE",
3909 IFLA_VTI_FWMARK
: "IFLA_VTI_FWMARK",
3912 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
3913 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
3914 self
.PACK
= 'BxHiII'
3915 self
.LEN
= calcsize(self
.PACK
)
3917 def get_link_type_string(self
, index
):
3918 return self
.get_string(self
.link_type_to_string
, index
)
3920 def get_ifla_inet6_af_spec_to_string(self
, index
):
3921 return self
.get_string(self
.ifla_inet6_af_spec_to_string
, index
)
3923 def get_ifla_inet_af_spec_to_string(self
, index
):
3924 return self
.get_string(self
.ifla_inet_af_spec_to_string
, index
)
3926 def get_ifla_bridge_af_spec_to_string(self
, index
):
3927 return self
.get_string(self
.ifla_bridge_af_spec_to_string
, index
)
3929 def get_ifla_info_string(self
, index
):
3930 return self
.get_string(self
.ifla_info_to_string
, index
)
3932 def get_ifla_vlan_string(self
, index
):
3933 return self
.get_string(self
.ifla_vlan_to_string
, index
)
3935 def get_ifla_vxlan_string(self
, index
):
3936 return self
.get_string(self
.ifla_vxlan_to_string
, index
)
3938 def get_ifla_macvlan_string(self
, index
):
3939 return self
.get_string(self
.ifla_macvlan_to_string
, index
)
3941 def get_ifla_xfrm_string(self
, index
):
3942 return self
.get_string(self
.ifla_xfrm_to_string
, index
)
3944 def get_macvlan_mode_string(self
, index
):
3945 return self
.get_string(self
.macvlan_mode_to_string
, index
)
3947 def get_ifla_gre_string(self
, index
):
3948 return self
.get_string(self
.ifla_gre_to_string
, index
)
3950 def get_ifla_vti_string(self
, index
):
3951 return self
.get_string(self
.ifla_vti_to_string
, index
)
3953 def get_ifla_iptun_string(self
, index
):
3954 return self
.get_string(self
.ifla_iptun_to_string
, index
)
3956 def get_ifla_bond_string(self
, index
):
3957 return self
.get_string(self
.ifla_bond_to_string
, index
)
3959 def get_ifla_bond_ad_string(self
, index
):
3960 return self
.get_string(self
.ifla_bond_ad_to_string
, index
)
3962 def get_ifla_brport_string(self
, index
):
3963 return self
.get_string(self
.ifla_brport_to_string
, index
)
3965 def get_ifla_br_string(self
, index
):
3966 return self
.get_string(self
.ifla_br_to_string
, index
)
3968 def get_bridge_vlan_string(self
, index
):
3969 return self
.get_string(self
.bridge_vlan_to_string
, index
)
3971 def get_bridge_flags_string(self
, index
):
3972 return self
.get_string(self
.bridge_flags_to_string
, index
)
3974 def decode_service_header(self
):
3976 # Nothing to do if the message did not contain a service header
3977 if self
.length
== self
.header_LEN
:
3980 (self
.family
, self
.device_type
,
3983 self
.change_mask
) = \
3984 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
3987 color
= yellow
if self
.use_color
else None
3988 color_start
= "\033[%dm" % color
if color
else ""
3989 color_end
= "\033[0m" if color
else ""
3990 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
3992 for x
in range(0, self
.LEN
/4):
3993 if self
.line_number
== 5:
3994 extra
= "Family %s (%s:%d), Device Type %s (%d - %s)" % \
3995 (zfilled_hex(self
.family
, 2), get_family_str(self
.family
), self
.family
,
3996 zfilled_hex(self
.device_type
, 4), self
.device_type
, self
.get_link_type_string(self
.device_type
))
3997 elif self
.line_number
== 6:
3998 extra
= "Interface Index %s (%d)" % (zfilled_hex(self
.ifindex
, 8), self
.ifindex
)
3999 elif self
.line_number
== 7:
4000 extra
= "Device Flags %s (%s)" % (zfilled_hex(self
.flags
, 8), self
.get_flags_string())
4001 elif self
.line_number
== 8:
4002 extra
= "Change Mask %s" % zfilled_hex(self
.change_mask
, 8)
4004 extra
= "Unexpected line number %d" % self
.line_number
4008 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
4009 self
.line_number
+= 1
4012 if self
.flags
& Link
.IFF_UP
:
4017 class Netconf(Link
):
4019 RTM_NEWNETCONF - Service Header
4027 RTM_GETNETCONF - Service Header
4030 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
4031 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4032 | Family | Reserved | Device Type |
4033 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4035 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4037 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4039 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4041 # Netconf attributes
4042 # /usr/include/linux/netconf.h
4044 NETCONFA_IFINDEX
= 1
4045 NETCONFA_FORWARDING
= 2
4046 NETCONFA_RP_FILTER
= 3
4047 NETCONFA_MC_FORWARDING
= 4
4048 NETCONFA_PROXY_NEIGH
= 5
4049 NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN
= 6
4053 NETCONFA_MAX
= (__NETCONFA_MAX
- 1)
4056 NETCONFA_IFINDEX_ALL
= -1
4057 NETCONFA_IFINDEX_DEFAULT
= -2
4059 NETCONF_ATTR_FAMILY
= 0x0001
4060 NETCONF_ATTR_IFINDEX
= 0x0002
4061 NETCONF_ATTR_RP_FILTER
= 0x0004
4062 NETCONF_ATTR_FWDING
= 0x0008
4063 NETCONF_ATTR_MC_FWDING
= 0x0010
4064 NETCONF_ATTR_PROXY_NEIGH
= 0x0020
4065 NETCONF_ATTR_IGNORE_RT_LINKDWN
= 0x0040
4067 attribute_to_class
= {
4068 NETCONFA_UNSPEC
: ('NETCONFA_UNSPEC', AttributeGeneric
),
4069 NETCONFA_IFINDEX
: ('NETCONFA_IFINDEX', AttributeFourByteValue
),
4070 NETCONFA_FORWARDING
: ('NETCONFA_FORWARDING', AttributeFourByteValue
),
4071 NETCONFA_RP_FILTER
: ('NETCONFA_RP_FILTER', AttributeFourByteValue
),
4072 NETCONFA_MC_FORWARDING
: ('NETCONFA_MC_FORWARDING', AttributeFourByteValue
),
4073 NETCONFA_PROXY_NEIGH
: ('NETCONFA_PROXY_NEIGH', AttributeFourByteValue
),
4074 NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN
: ('NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN', AttributeFourByteValue
),
4075 NETCONFA_INPUT
: ('NETCONFA_INPUT', AttributeFourByteValue
),
4078 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
4079 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
4080 if msgtype
== RTM_GETNETCONF
: # same as RTM_GETLINK
4081 self
.PACK
= 'BxHiII'
4082 self
.LEN
= calcsize(self
.PACK
)
4083 elif msgtype
== RTM_NEWNETCONF
:
4085 self
.LEN
= calcsize(self
.PACK
)
4087 def decode_service_header(self
):
4088 # Nothing to do if the message did not contain a service header
4089 if self
.length
== self
.header_LEN
:
4092 if self
.msgtype
== RTM_GETNETCONF
:
4093 super(Netconf
, self
).decode_service_header()
4095 elif self
.msgtype
== RTM_NEWNETCONF
:
4096 (self
.family
,) = unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
4099 color
= yellow
if self
.use_color
else None
4100 color_start
= "\033[%dm" % color
if color
else ""
4101 color_end
= "\033[0m" if color
else ""
4102 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
4103 self
.dump_buffer
.append(data_to_color_text(1, color
, bytearray(struct
.pack('!I', self
.family
)), "Family %s (%s:%d)" % (zfilled_hex(self
.family
, 2), get_family_str(self
.family
), self
.family
)))
4106 class Neighbor(NetlinkPacket
):
4111 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
4112 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4113 | Family | Reserved1 | Reserved2 |
4114 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4116 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4117 | State | Flags | Type |
4118 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4121 # Neighbor attributes
4122 # /usr/include/linux/neighbour.h
4123 NDA_UNSPEC
= 0x00 # Unknown type
4124 NDA_DST
= 0x01 # A neighbour cache network. layer destination address
4125 NDA_LLADDR
= 0x02 # A neighbor cache link layer address.
4126 NDA_CACHEINFO
= 0x03 # Cache statistics
4133 NDA_LINK_NETNSID
= 0x0A
4135 attribute_to_class
= {
4136 NDA_UNSPEC
: ('NDA_UNSPEC', AttributeGeneric
),
4137 NDA_DST
: ('NDA_DST', AttributeIPAddress
),
4138 NDA_LLADDR
: ('NDA_LLADDR', AttributeMACAddress
),
4139 NDA_CACHEINFO
: ('NDA_CACHEINFO', AttributeFourByteList
),
4140 NDA_PROBES
: ('NDA_PROBES', AttributeFourByteValue
),
4141 NDA_VLAN
: ('NDA_VLAN', AttributeTwoByteValue
),
4142 NDA_PORT
: ('NDA_PORT', AttributeGeneric
),
4143 NDA_VNI
: ('NDA_VNI', AttributeFourByteValue
),
4144 NDA_IFINDEX
: ('NDA_IFINDEX', AttributeFourByteValue
),
4145 NDA_MASTER
: ('NDA_MASTER', AttributeFourByteValue
),
4146 NDA_LINK_NETNSID
: ('NDA_LINK_NETNSID', AttributeGeneric
)
4150 # /usr/include/linux/neighbour.h
4154 NTF_PROXY
= 0x08 # A proxy ARP entry
4155 NTF_EXT_LEARNED
= 0x10 # neigh entry installed by an external APP
4156 NTF_ROUTER
= 0x80 # An IPv6 router
4159 NTF_USE
: 'NTF_USE',
4160 NTF_SELF
: 'NTF_SELF',
4161 NTF_MASTER
: 'NTF_MASTER',
4162 NTF_PROXY
: 'NTF_PROXY',
4163 NTF_EXT_LEARNED
: 'NTF_EXT_LEARNED',
4164 NTF_ROUTER
: 'NTF_ROUTER'
4168 # /usr/include/linux/neighbour.h
4170 NUD_INCOMPLETE
= 0x01 # Still attempting to resolve
4171 NUD_REACHABLE
= 0x02 # A confirmed working cache entry
4172 NUD_STALE
= 0x04 # an expired cache entry
4173 NUD_DELAY
= 0x08 # Neighbor no longer reachable. Traffic sent, waiting for confirmatio.
4174 NUD_PROBE
= 0x10 # A cache entry that is currently being re-solicited
4175 NUD_FAILED
= 0x20 # An invalid cache entry
4176 NUD_NOARP
= 0x40 # A device which does not do neighbor discovery(ARP)
4177 NUD_PERMANENT
= 0x80 # A static entry
4180 NUD_NONE
: 'NUD_NONE',
4181 NUD_INCOMPLETE
: 'NUD_INCOMPLETE',
4182 NUD_REACHABLE
: 'NUD_REACHABLE',
4183 NUD_STALE
: 'NUD_STALE',
4184 NUD_DELAY
: 'NUD_DELAY',
4185 NUD_PROBE
: 'NUD_PROBE',
4186 NUD_FAILED
: 'NUD_FAILED',
4187 NUD_NOARP
: 'NUD_NOARP',
4188 NUD_PERMANENT
: 'NUD_PERMANENT'
4191 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
4192 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
4193 self
.PACK
= 'BxxxiHBB'
4194 self
.LEN
= calcsize(self
.PACK
)
4196 def get_state_string(self
, index
):
4197 return self
.get_string(self
.state_to_string
, index
)
4199 def get_states_string(self
, states
):
4202 if states
& Neighbor
.NUD_INCOMPLETE
:
4203 for_string
.append('NUD_INCOMPLETE')
4205 if states
& Neighbor
.NUD_REACHABLE
:
4206 for_string
.append('NUD_REACHABLE')
4208 if states
& Neighbor
.NUD_STALE
:
4209 for_string
.append('NUD_STALE')
4211 if states
& Neighbor
.NUD_DELAY
:
4212 for_string
.append('NUD_DELAY')
4214 if states
& Neighbor
.NUD_PROBE
:
4215 for_string
.append('NUD_PROBE')
4217 if states
& Neighbor
.NUD_FAILED
:
4218 for_string
.append('NUD_FAILED')
4220 if states
& Neighbor
.NUD_NOARP
:
4221 for_string
.append('NUD_NOARP')
4223 if states
& Neighbor
.NUD_PERMANENT
:
4224 for_string
.append('NUD_PERMANENT')
4226 return ', '.join(for_string
)
4228 def get_flags_string(self
, flags
):
4231 if flags
& Neighbor
.NTF_USE
:
4232 for_string
.append('NTF_USE')
4234 if flags
& Neighbor
.NTF_SELF
:
4235 for_string
.append('NTF_SELF')
4237 if flags
& Neighbor
.NTF_MASTER
:
4238 for_string
.append('NTF_MASTER')
4240 if flags
& Neighbor
.NTF_PROXY
:
4241 for_string
.append('NTF_PROXY')
4243 if flags
& Neighbor
.NTF_ROUTER
:
4244 for_string
.append('NTF_ROUTER')
4246 return ', '.join(for_string
)
4248 def decode_service_header(self
):
4250 # Nothing to do if the message did not contain a service header
4251 if self
.length
== self
.header_LEN
:
4256 self
.state
, self
.flags
, self
.neighbor_type
) = \
4257 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
4260 color
= yellow
if self
.use_color
else None
4261 color_start
= "\033[%dm" % color
if color
else ""
4262 color_end
= "\033[0m" if color
else ""
4263 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
4265 for x
in range(0, self
.LEN
/4):
4266 if self
.line_number
== 5:
4267 extra
= "Family %s (%s:%d)" % (zfilled_hex(self
.family
, 2), get_family_str(self
.family
), self
.family
)
4268 elif self
.line_number
== 6:
4269 extra
= "Interface Index %s (%d)" % (zfilled_hex(self
.ifindex
, 8), self
.ifindex
)
4270 elif self
.line_number
== 7:
4271 extra
= "State %s (%d) %s, Flags %s (%s) %s, Type %s (%d)" % \
4272 (zfilled_hex(self
.state
, 4), self
.state
, self
.get_states_string(self
.state
),
4273 zfilled_hex(self
.flags
, 2), self
.flags
, self
.get_flags_string(self
.flags
),
4274 zfilled_hex(self
.neighbor_type
, 4), self
.neighbor_type
)
4276 extra
= "Unexpected line number %d" % self
.line_number
4280 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
4281 self
.line_number
+= 1
4284 class Route(NetlinkPacket
):
4289 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
4290 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4291 | Family | Dest length | Src length | TOS |
4292 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4293 | Table ID | Protocol | Scope | Type |
4294 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4296 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4300 # /usr/include/linux/rtnetlink.h
4301 RTA_UNSPEC
= 0x00 # Ignored.
4302 RTA_DST
= 0x01 # Protocol address for route destination address.
4303 RTA_SRC
= 0x02 # Protocol address for route source address.
4304 RTA_IIF
= 0x03 # Input interface index.
4305 RTA_OIF
= 0x04 # Output interface index.
4306 RTA_GATEWAY
= 0x05 # Protocol address for the gateway of the route
4307 RTA_PRIORITY
= 0x06 # Priority of broker.
4308 RTA_PREFSRC
= 0x07 # Preferred source address in cases where more than one source address could be used.
4309 RTA_METRICS
= 0x08 # Route metrics attributed to route and associated protocols(e.g., RTT, initial TCP window, etc.).
4310 RTA_MULTIPATH
= 0x09 # Multipath route next hop's attributes.
4311 RTA_PROTOINFO
= 0x0A # Firewall based policy routing attribute.
4312 RTA_FLOW
= 0x0B # Route realm.
4313 RTA_CACHEINFO
= 0x0C # Cached route information.
4318 RTA_MFC_STATS
= 0x11
4322 RTA_ENCAP_TYPE
= 0x15
4325 attribute_to_class
= {
4326 RTA_UNSPEC
: ('RTA_UNSPEC', AttributeGeneric
),
4327 RTA_DST
: ('RTA_DST', AttributeIPAddress
),
4328 RTA_SRC
: ('RTA_SRC', AttributeIPAddress
),
4329 RTA_IIF
: ('RTA_IIF', AttributeFourByteValue
),
4330 RTA_OIF
: ('RTA_OIF', AttributeFourByteValue
),
4331 RTA_GATEWAY
: ('RTA_GATEWAY', AttributeIPAddress
),
4332 RTA_PRIORITY
: ('RTA_PRIORITY', AttributeFourByteValue
),
4333 RTA_PREFSRC
: ('RTA_PREFSRC', AttributeIPAddress
),
4334 RTA_METRICS
: ('RTA_METRICS', AttributeGeneric
),
4335 RTA_MULTIPATH
: ('RTA_MULTIPATH', AttributeRTA_MULTIPATH
),
4336 RTA_PROTOINFO
: ('RTA_PROTOINFO', AttributeGeneric
),
4337 RTA_FLOW
: ('RTA_FLOW', AttributeGeneric
),
4338 RTA_CACHEINFO
: ('RTA_CACHEINFO', AttributeGeneric
),
4339 RTA_SESSION
: ('RTA_SESSION', AttributeGeneric
),
4340 RTA_MP_ALGO
: ('RTA_MP_ALGO', AttributeGeneric
),
4341 RTA_TABLE
: ('RTA_TABLE', AttributeFourByteValue
),
4342 RTA_MARK
: ('RTA_MARK', AttributeGeneric
),
4343 RTA_MFC_STATS
: ('RTA_MFC_STATS', AttributeGeneric
),
4344 RTA_VIA
: ('RTA_VIA', AttributeGeneric
),
4345 RTA_NEWDST
: ('RTA_NEWDST', AttributeGeneric
),
4346 RTA_PREF
: ('RTA_PREF', AttributeGeneric
),
4347 RTA_ENCAP_TYPE
: ('RTA_ENCAP_TYPE', AttributeGeneric
),
4348 RTA_ENCAP
: ('RTA_ENCAP', AttributeGeneric
)
4352 # /usr/include/linux/rtnetlink.h
4353 RT_TABLE_UNSPEC
= 0x00 # An unspecified routing table
4354 RT_TABLE_COMPAT
= 0xFC
4355 RT_TABLE_DEFAULT
= 0xFD # The default table
4356 RT_TABLE_MAIN
= 0xFE # The main table
4357 RT_TABLE_LOCAL
= 0xFF # The local table
4360 RT_TABLE_UNSPEC
: 'RT_TABLE_UNSPEC',
4361 RT_TABLE_COMPAT
: 'RT_TABLE_COMPAT',
4362 RT_TABLE_DEFAULT
: 'RT_TABLE_DEFAULT',
4363 RT_TABLE_MAIN
: 'RT_TABLE_MAIN',
4364 RT_TABLE_LOCAL
: 'RT_TABLE_LOCAL'
4368 # /usr/include/linux/rtnetlink.h
4369 RT_SCOPE_UNIVERSE
= 0x00 # Global route
4370 RT_SCOPE_SITE
= 0xC8 # Interior route in the local autonomous system
4371 RT_SCOPE_LINK
= 0xFD # Route on this link
4372 RT_SCOPE_HOST
= 0xFE # Route on the local host
4373 RT_SCOPE_NOWHERE
= 0xFF # Destination does not exist
4376 RT_SCOPE_UNIVERSE
: 'RT_SCOPE_UNIVERSE',
4377 RT_SCOPE_SITE
: 'RT_SCOPE_SITE',
4378 RT_SCOPE_LINK
: 'RT_SCOPE_LINK',
4379 RT_SCOPE_HOST
: 'RT_SCOPE_HOST',
4380 RT_SCOPE_NOWHERE
: 'RT_SCOPE_NOWHERE'
4383 # Route scope to string
4384 # iproute2/lib/rt_names.c
4385 rtnl_rtscope_tab
= {
4386 RT_SCOPE_UNIVERSE
: 'global',
4387 RT_SCOPE_NOWHERE
: 'nowhere',
4388 RT_SCOPE_HOST
: 'host',
4389 RT_SCOPE_LINK
: 'link',
4390 RT_SCOPE_SITE
: 'site'
4394 # /usr/include/linux/rtnetlink.h
4395 RT_PROT_UNSPEC
= 0x00 # Identifies what/who added the route
4396 RT_PROT_REDIRECT
= 0x01 # By an ICMP redirect
4397 RT_PROT_KERNEL
= 0x02 # By the kernel
4398 RT_PROT_BOOT
= 0x03 # During bootup
4399 RT_PROT_STATIC
= 0x04 # By the administrator
4400 RT_PROT_GATED
= 0x08 # GateD
4401 RT_PROT_RA
= 0x09 # RDISC/ND router advertissements
4402 RT_PROT_MRT
= 0x0A # Merit MRT
4403 RT_PROT_ZEBRA
= 0x0B # ZEBRA
4404 RT_PROT_BIRD
= 0x0C # BIRD
4405 RT_PROT_DNROUTED
= 0x0D # DECnet routing daemon
4406 RT_PROT_XORP
= 0x0E # XORP
4407 RT_PROT_NTK
= 0x0F # Netsukuku
4408 RT_PROT_DHCP
= 0x10 # DHCP client
4409 RT_PROT_EXABGP
= 0x11 # Exa Networks ExaBGP
4412 RT_PROT_UNSPEC
: 'RT_PROT_UNSPEC',
4413 RT_PROT_REDIRECT
: 'RT_PROT_REDIRECT',
4414 RT_PROT_KERNEL
: 'RT_PROT_KERNEL',
4415 RT_PROT_BOOT
: 'RT_PROT_BOOT',
4416 RT_PROT_STATIC
: 'RT_PROT_STATIC',
4417 RT_PROT_GATED
: 'RT_PROT_GATED',
4418 RT_PROT_RA
: 'RT_PROT_RA',
4419 RT_PROT_MRT
: 'RT_PROT_MRT',
4420 RT_PROT_ZEBRA
: 'RT_PROT_ZEBRA',
4421 RT_PROT_BIRD
: 'RT_PROT_BIRD',
4422 RT_PROT_DNROUTED
: 'RT_PROT_DNROUTED',
4423 RT_PROT_XORP
: 'RT_PROT_XORP',
4424 RT_PROT_NTK
: 'RT_PROT_NTK',
4425 RT_PROT_DHCP
: 'RT_PROT_DHCP',
4426 RT_PROT_EXABGP
: 'RT_PROT_EXABGP'
4430 # /usr/include/linux/rtnetlink.h
4431 RTN_UNSPEC
= 0x00 # Unknown broker.
4432 RTN_UNICAST
= 0x01 # A gateway or direct broker.
4433 RTN_LOCAL
= 0x02 # A local interface broker.
4434 RTN_BROADCAST
= 0x03 # A local broadcast route(sent as a broadcast).
4435 RTN_ANYCAST
= 0x04 # An anycast broker.
4436 RTN_MULTICAST
= 0x05 # A multicast broker.
4437 RTN_BLACKHOLE
= 0x06 # A silent packet dropping broker.
4438 RTN_UNREACHABLE
= 0x07 # An unreachable destination. Packets dropped and
4439 # host unreachable ICMPs are sent to the originator.
4440 RTN_PROHIBIT
= 0x08 # A packet rejection broker. Packets are dropped and
4441 # communication prohibited ICMPs are sent to the originator.
4442 RTN_THROW
= 0x09 # When used with policy routing, continue routing lookup
4443 # in another table. Under normal routing, packets are
4444 # dropped and net unreachable ICMPs are sent to the originator.
4445 RTN_NAT
= 0x0A # A network address translation rule.
4446 RTN_XRESOLVE
= 0x0B # Refer to an external resolver(not implemented).
4448 rt_type_to_string
= {
4449 RTN_UNSPEC
: 'RTN_UNSPEC',
4450 RTN_UNICAST
: 'RTN_UNICAST',
4451 RTN_LOCAL
: 'RTN_LOCAL',
4452 RTN_BROADCAST
: 'RTN_BROADCAST',
4453 RTN_ANYCAST
: 'RTN_ANYCAST',
4454 RTN_MULTICAST
: 'RTN_MULTICAST',
4455 RTN_BLACKHOLE
: 'RTN_BLACKHOLE',
4456 RTN_UNREACHABLE
: 'RTN_UNREACHABLE',
4457 RTN_PROHIBIT
: 'RTN_PROHIBIT',
4458 RTN_THROW
: 'RTN_THROW',
4459 RTN_NAT
: 'RTN_NAT',
4460 RTN_XRESOLVE
: 'RTN_XRESOLVE'
4464 # /usr/include/linux/rtnetlink.h
4465 RTM_F_NOTIFY
= 0x100 # If the route changes, notify the user
4466 RTM_F_CLONED
= 0x200 # Route is cloned from another route
4467 RTM_F_EQUALIZE
= 0x400 # Allow randomization of next hop path in multi-path routing(currently not implemented)
4468 RTM_F_PREFIX
= 0x800 # Prefix Address
4471 RTM_F_NOTIFY
: 'RTM_F_NOTIFY',
4472 RTM_F_CLONED
: 'RTM_F_CLONED',
4473 RTM_F_EQUALIZE
: 'RTM_F_EQUALIZE',
4474 RTM_F_PREFIX
: 'RTM_F_PREFIX'
4477 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
4478 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
4479 self
.PACK
= '=8BI' # or is it 8Bi ?
4480 self
.LEN
= calcsize(self
.PACK
)
4482 def get_prefix_string(self
):
4483 dst
= self
.get_attribute_value(self
.RTA_DST
)
4486 return "%s/%d" % (dst
, self
.src_len
)
4488 if self
.family
== AF_INET
:
4490 elif self
.family
== AF_INET6
:
4493 def get_protocol_string(self
, index
=None):
4495 index
= self
.protocol
4496 return self
.get_string(self
.prot_to_string
, index
)
4498 def get_rt_type_string(self
, index
=None):
4500 index
= self
.route_type
4501 return self
.get_string(self
.rt_type_to_string
, index
)
4503 def get_scope_string(self
, index
=None):
4506 return self
.get_string(self
.scope_to_string
, index
)
4508 def get_table_id_string(self
, index
=None):
4510 index
= self
.table_id
4511 return self
.get_string(self
.table_to_string
, index
)
4513 def _get_ifname_from_index(self
, ifindex
, ifname_by_index
):
4515 ifname
= ifname_by_index
.get(ifindex
)
4518 ifname
= str(ifindex
)
4524 def get_nexthops(self
, ifname_by_index
={}):
4525 nexthop
= self
.get_attribute_value(self
.RTA_GATEWAY
)
4526 multipath
= self
.get_attribute_value(self
.RTA_MULTIPATH
)
4530 rta_oif
= self
.get_attribute_value(self
.RTA_OIF
)
4531 ifname
= self
._get
_ifname
_from
_index
(rta_oif
, ifname_by_index
)
4532 nexthops
.append((nexthop
, ifname
))
4535 for (nexthop
, rtnh_ifindex
, rtnh_flags
, rtnh_hops
) in multipath
:
4536 ifname
= self
._get
_ifname
_from
_index
(rtnh_ifindex
, ifname_by_index
)
4537 nexthops
.append((nexthop
, ifname
))
4541 def get_nexthops_string(self
, ifname_by_index
={}):
4544 for (nexthop
, ifname
) in self
.get_nexthops(ifname_by_index
):
4545 output
.append(" via %s on %s" % (nexthop
, ifname
))
4547 return ",".join(output
)
4549 def decode_service_header(self
):
4551 # Nothing to do if the message did not contain a service header
4552 if self
.length
== self
.header_LEN
:
4555 (self
.family
, self
.src_len
, self
.dst_len
, self
.tos
,
4556 self
.table_id
, self
.protocol
, self
.scope
, self
.route_type
,
4558 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
4561 color
= yellow
if self
.use_color
else None
4562 color_start
= "\033[%dm" % color
if color
else ""
4563 color_end
= "\033[0m" if color
else ""
4564 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
4566 for x
in range(0, self
.LEN
/4):
4567 if self
.line_number
== 5:
4568 extra
= "Family %s (%s:%d), Source Length %s (%d), Destination Length %s (%d), TOS %s (%d)" % \
4569 (zfilled_hex(self
.family
, 2), get_family_str(self
.family
), self
.family
,
4570 zfilled_hex(self
.src_len
, 2), self
.src_len
,
4571 zfilled_hex(self
.dst_len
, 2), self
.dst_len
,
4572 zfilled_hex(self
.tos
, 2), self
.tos
)
4573 elif self
.line_number
== 6:
4574 extra
= "Table ID %s (%d - %s), Protocol %s (%d - %s), Scope %s (%d - %s), Type %s (%d - %s)" % \
4575 (zfilled_hex(self
.table_id
, 2), self
.table_id
, self
.get_table_id_string(),
4576 zfilled_hex(self
.protocol
, 2), self
.protocol
, self
.get_protocol_string(),
4577 zfilled_hex(self
.scope
, 2), self
.scope
, self
.get_scope_string(),
4578 zfilled_hex(self
.route_type
, 2), self
.route_type
, self
.get_rt_type_string())
4579 elif self
.line_number
== 7:
4580 extra
= "Flags %s" % zfilled_hex(self
.flags
, 8)
4582 extra
= "Unexpected line number %d" % self
.line_number
4586 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
4587 self
.line_number
+= 1
4589 class Done(NetlinkPacket
):
4595 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
4596 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4598 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4601 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
4602 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
4604 self
.LEN
= calcsize(self
.PACK
)
4606 def decode_service_header(self
):
4607 foo
= unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
4610 color
= yellow
if self
.use_color
else None
4611 color_start
= "\033[%dm" % color
if color
else ""
4612 color_end
= "\033[0m" if color
else ""
4613 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
4615 for x
in range(0, self
.LEN
/4):
4619 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
4620 self
.line_number
+= 1