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)
74 # Netlink message flags
75 NLM_F_REQUEST
= 0x01 # It is query message.
76 NLM_F_MULTI
= 0x02 # Multipart message, terminated by NLMSG_DONE
77 NLM_F_ACK
= 0x04 # Reply with ack, with zero or error code
78 NLM_F_ECHO
= 0x08 # Echo this query
80 # Modifiers to GET query
81 NLM_F_ROOT
= 0x100 # specify tree root
82 NLM_F_MATCH
= 0x200 # return all matching
83 NLM_F_DUMP
= NLM_F_ROOT | NLM_F_MATCH
84 NLM_F_ATOMIC
= 0x400 # atomic GET
86 # Modifiers to NEW query
87 NLM_F_REPLACE
= 0x100 # Override existing
88 NLM_F_EXCL
= 0x200 # Do not touch, if it exists
89 NLM_F_CREATE
= 0x400 # Create, if it does not exist
90 NLM_F_APPEND
= 0x800 # Add to end of list
93 NLA_F_NET_BYTEORDER
= 0x4000
94 NLA_TYPE_MASK
= ~
(NLA_F_NESTED | NLA_F_NET_BYTEORDER
)
101 RTMGRP_IPV4_IFADDR
= 0x10
102 RTMGRP_IPV4_MROUTE
= 0x20
103 RTMGRP_IPV4_ROUTE
= 0x40
104 RTMGRP_IPV4_RULE
= 0x80
105 RTMGRP_IPV6_IFADDR
= 0x100
106 RTMGRP_IPV6_MROUTE
= 0x200
107 RTMGRP_IPV6_ROUTE
= 0x400
108 RTMGRP_IPV6_IFINFO
= 0x800
109 RTMGRP_DECnet_IFADDR
= 0x1000
110 RTMGRP_DECnet_ROUTE
= 0x4000
111 RTMGRP_IPV6_PREFIX
= 0x20000
113 RTMGRP_ALL
= (RTMGRP_LINK | RTMGRP_NOTIFY | RTMGRP_NEIGH | RTMGRP_TC |
114 RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_MROUTE | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_RULE |
115 RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_MROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFINFO |
116 RTMGRP_DECnet_IFADDR | RTMGRP_DECnet_ROUTE |
127 value_to_bool_dict
= {
145 def set_log_level(level
):
149 def zfilled_hex(value
, digits
):
150 return '0x' + hex(value
)[2:].zfill(digits
)
153 def remove_trailing_null(line
):
155 Remove the last character if it is a NULL...having that NULL
156 causes python to print a garbage character
159 if ord(line
[-1]) == 0:
165 def mac_int_to_str(mac_int
):
167 Return an integer in MAC string format
170 # [2:] to remove the leading 0x, then fill out to 12 zeroes, then uppercase
171 all_caps
= hex(int(mac_int
))[2:].zfill(12).upper()
173 if all_caps
[-1] == 'L':
174 all_caps
= all_caps
[:-1]
175 all_caps
= all_caps
.zfill(12).upper()
177 return "%s.%s.%s" % (all_caps
[0:4], all_caps
[4:8], all_caps
[8:12])
180 def data_to_color_text(line_number
, color
, data
, extra
=''):
181 (c1
, c2
, c3
, c4
) = unpack('BBBB', data
[0:4])
184 for c
in (c1
, c2
, c3
, c4
):
187 if char_c
in printable
[:-5]:
188 in_ascii
.append(char_c
)
193 return ' %2d: \033[%dm0x%02x%02x%02x%02x\033[0m %s %s' % (line_number
, color
, c1
, c2
, c3
, c4
, ''.join(in_ascii
), extra
)
195 return ' %2d: 0x%02x%02x%02x%02x %s %s' % (line_number
, c1
, c2
, c3
, c4
, ''.join(in_ascii
), extra
)
198 def padded_length(length
):
199 return int((length
+ 3) / 4) * 4
202 class Attribute(object):
204 def __init__(self
, atype
, string
, logger
):
207 self
.HEADER_PACK
= '=HH'
208 self
.HEADER_LEN
= calcsize(self
.HEADER_PACK
)
213 self
.net_byteorder
= False
219 def set_value(self
, value
):
222 def set_nested(self
, nested
):
225 def set_net_byteorder(self
, net_byteorder
):
226 self
.net_byteorder
= net_byteorder
228 def pad_bytes_needed(self
, length
):
230 Return the number of bytes that should be added to align on a 4-byte boundry
232 remainder
= length
% 4
239 def pad(self
, length
, raw
):
240 pad
= self
.pad_bytes_needed(length
)
250 raise Exception('Please define an encode() method in your child attribute class, or do not use AttributeGeneric')
252 length
= self
.HEADER_LEN
+ self
.LEN
253 attr_type_with_flags
= self
.atype
256 attr_type_with_flags
= attr_type_with_flags | NLA_F_NESTED
258 if self
.net_byteorder
:
259 attr_type_with_flags
= attr_type_with_flags | NLA_F_NET_BYTEORDER
261 raw
= pack(self
.HEADER_PACK
, length
, attr_type_with_flags
) + pack(self
.PACK
, self
.value
)
262 raw
= self
.pad(length
, raw
)
265 def decode_length_type(self
, data
):
267 The first two bytes of an attribute are the length, the next two bytes are the type
270 prev_atype
= self
.atype
271 (data1
, data2
) = unpack(self
.HEADER_PACK
, data
[:self
.HEADER_LEN
])
272 self
.length
= int(data1
)
273 self
.atype
= int(data2
)
274 self
.attr_end
= padded_length(self
.length
)
276 self
.nested
= True if self
.atype
& NLA_F_NESTED
else False
277 self
.net_byteorder
= True if self
.atype
& NLA_F_NET_BYTEORDER
else False
278 self
.atype
= self
.atype
& NLA_TYPE_MASK
280 # Should never happen
281 assert self
.atype
== prev_atype
, "This object changes attribute type from %d to %d, this is bad" % (prev_atype
, self
.atype
)
283 def dump_first_line(self
, dump_buffer
, line_number
, color
):
285 Add the "Length....Type..." line to the dump buffer
287 if self
.attr_end
== self
.length
:
290 padded_to
= ' padded to %d, ' % self
.attr_end
292 extra
= 'Length %s (%d)%sType %s%s%s (%d) %s' % \
293 (zfilled_hex(self
.length
, 4), self
.length
,
295 zfilled_hex(self
.atype
, 4),
296 " (NLA_F_NESTED set)" if self
.nested
else "",
297 " (NLA_F_NET_BYTEORDER set)" if self
.net_byteorder
else "",
301 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[0:4], extra
))
302 return line_number
+ 1
304 def dump_lines(self
, dump_buffer
, line_number
, color
):
305 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
307 for x
in xrange(1, self
.attr_end
/4):
310 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], ''))
315 def get_pretty_value(self
, obj
=None):
316 if obj
and callable(obj
):
317 return obj(self
.value
)
321 class AttributeFourByteList(Attribute
):
323 def __init__(self
, atype
, string
, family
, logger
):
324 Attribute
.__init
__(self
, atype
, string
, logger
)
326 def decode(self
, parent_msg
, data
):
327 self
.decode_length_type(data
)
328 wordcount
= (self
.attr_end
- 4)/4
329 self
.PACK
= '=%dL' % wordcount
330 self
.LEN
= calcsize(self
.PACK
)
333 self
.value
= unpack(self
.PACK
, self
.data
[4:])
335 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
338 def dump_lines(self
, dump_buffer
, line_number
, color
):
339 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
341 for val
in self
.value
:
342 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4*idx
:4*(idx
+1)], val
))
348 class AttributeFourByteValue(Attribute
):
350 def __init__(self
, atype
, string
, family
, logger
):
351 Attribute
.__init
__(self
, atype
, string
, logger
)
353 self
.LEN
= calcsize(self
.PACK
)
355 def decode(self
, parent_msg
, data
):
356 self
.decode_length_type(data
)
357 assert self
.attr_end
== 8, "Attribute length for %s must be 8, it is %d" % (self
, self
.attr_end
)
360 self
.value
= int(unpack(self
.PACK
, self
.data
[4:])[0])
362 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
365 def dump_lines(self
, dump_buffer
, line_number
, color
):
366 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
367 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
368 return line_number
+ 1
371 class AttributeTwoByteValue(Attribute
):
373 def __init__(self
, atype
, string
, family
, logger
):
374 Attribute
.__init
__(self
, atype
, string
, logger
)
376 self
.LEN
= calcsize(self
.PACK
)
378 def decode(self
, parent_msg
, data
):
379 self
.decode_length_type(data
)
380 assert self
.attr_end
== 8, "Attribute length for %s must be 8, it is %d" % (self
, self
.attr_end
)
383 self
.value
= int(unpack(self
.PACK
, self
.data
[4:8])[0])
385 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:6])))
389 length
= self
.HEADER_LEN
+ self
.LEN
390 raw
= pack(self
.HEADER_PACK
, length
-2, self
.atype
) + pack(self
.PACK
, self
.value
)
391 raw
= self
.pad(length
, raw
)
394 def dump_lines(self
, dump_buffer
, line_number
, color
):
395 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
396 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
397 return line_number
+ 1
400 class AttributeString(Attribute
):
402 def __init__(self
, atype
, string
, family
, logger
):
403 Attribute
.__init
__(self
, atype
, string
, logger
)
408 # some interface names come from JSON as unicode strings
409 # and cannot be packed as is so we must convert them to strings
410 if isinstance(self
.value
, unicode):
411 self
.value
= str(self
.value
)
412 self
.PACK
= '%ds' % len(self
.value
)
413 self
.LEN
= calcsize(self
.PACK
)
415 length
= self
.HEADER_LEN
+ self
.LEN
416 raw
= pack(self
.HEADER_PACK
, length
, self
.atype
) + pack(self
.PACK
, self
.value
)
417 raw
= self
.pad(length
, raw
)
420 def decode(self
, parent_msg
, data
):
421 self
.decode_length_type(data
)
422 self
.PACK
= '%ds' % (self
.length
- 4)
423 self
.LEN
= calcsize(self
.PACK
)
426 self
.value
= remove_trailing_null(unpack(self
.PACK
, self
.data
[4:self
.length
])[0])
428 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:self
.length
])))
432 class AttributeStringInterfaceName(AttributeString
):
434 def __init__(self
, atype
, string
, family
, logger
):
435 AttributeString
.__init
__(self
, atype
, string
, family
, logger
)
437 def set_value(self
, value
):
438 if value
and len(value
) > IF_NAME_SIZE
:
439 raise Exception('interface name exceeds max length of %d' % IF_NAME_SIZE
)
443 class AttributeIPAddress(Attribute
):
445 def __init__(self
, atype
, string
, family
, logger
):
446 Attribute
.__init
__(self
, atype
, string
, logger
)
447 self
.value_int
= None
448 self
.value_int_str
= None
451 if self
.family
== AF_INET
:
454 elif self
.family
== AF_INET6
:
457 elif self
.family
== AF_BRIDGE
:
461 raise Exception("%s is not a supported address family" % self
.family
)
463 self
.LEN
= calcsize(self
.PACK
)
465 def set_value(self
, value
):
469 self
.value
= IPAddress(value
)
471 def decode(self
, parent_msg
, data
):
472 self
.decode_length_type(data
)
475 if self
.family
== AF_INET
:
476 self
.value
= IPv4Address(unpack(self
.PACK
, self
.data
[4:])[0])
478 elif self
.family
== AF_INET6
:
479 (data1
, data2
) = unpack(self
.PACK
, self
.data
[4:])
480 self
.value
= IPv6Address(data1
<< 64 | data2
)
482 elif self
.family
== AF_BRIDGE
:
483 self
.value
= IPv4Address(unpack(self
.PACK
, self
.data
[4:])[0])
485 self
.value_int
= int(self
.value
)
486 self
.value_int_str
= str(self
.value_int
)
490 self
.value_int
= None
491 self
.value_int_str
= None
492 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
496 length
= self
.HEADER_LEN
+ self
.LEN
498 if self
.family
not in [AF_INET
, AF_INET6
, AF_BRIDGE
]:
499 raise Exception("%s is not a supported address family" % self
.family
)
501 raw
= pack(self
.HEADER_PACK
, length
, self
.atype
) + self
.value
.packed
502 raw
= self
.pad(length
, raw
)
505 def dump_lines(self
, dump_buffer
, line_number
, color
):
506 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
508 if self
.family
== AF_INET
:
509 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
512 elif self
.family
== AF_INET6
:
514 for x
in xrange(1, self
.attr_end
/4):
517 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], self
.value
))
520 elif self
.family
== AF_BRIDGE
:
521 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
527 class AttributeMACAddress(Attribute
):
529 def __init__(self
, atype
, string
, family
, logger
):
530 Attribute
.__init
__(self
, atype
, string
, logger
)
532 self
.LEN
= calcsize(self
.PACK
)
534 def decode(self
, parent_msg
, data
):
535 self
.decode_length_type(data
)
537 # IFLA_ADDRESS and IFLA_BROADCAST attributes for all interfaces has been a
538 # 6-byte MAC address. But the GRE interface uses a 4-byte IP address and
539 # GREv6 uses a 16-byte IPv6 address for this attribute.
541 # GRE interface uses a 4-byte IP address for this attribute
543 self
.value
= IPv4Address(unpack('>L', self
.data
[4:])[0])
544 self
.value_int
= int(self
.value
)
545 self
.value_int_str
= str(self
.value_int
)
547 elif self
.length
== 10:
548 (data1
, data2
) = unpack(self
.PACK
, self
.data
[4:])
549 self
.value
= mac_int_to_str(data1
<< 16 | data2
)
550 # GREv6 interface uses a 16-byte IP address for this attribute
551 elif self
.length
== 20:
552 self
.value
= IPv6Address(unpack('>L', self
.data
[16:])[0])
553 self
.value_int
= int(self
.value
)
554 self
.value_int_str
= str(self
.value_int
)
556 raise Exception("Length of MACAddress attribute not supported: %d" % self
.length
)
559 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
563 length
= self
.HEADER_LEN
+ self
.LEN
564 mac_raw
= int(self
.value
.replace('.', '').replace(':', ''), 16)
565 raw
= pack(self
.HEADER_PACK
, length
-2, self
.atype
) + pack(self
.PACK
, mac_raw
>> 16, mac_raw
& 0x0000FFFF)
566 raw
= self
.pad(length
, raw
)
569 def dump_lines(self
, dump_buffer
, line_number
, color
):
570 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
571 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
573 if len(self
.data
) >= 12:
574 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[8:12]))
579 class AttributeMplsLabel(Attribute
):
581 def __init__(self
, atype
, string
, family
, logger
):
582 Attribute
.__init
__(self
, atype
, string
, logger
)
583 self
.value_int
= None
584 self
.value_int_str
= None
588 def decode(self
, parent_msg
, data
):
589 self
.decode_length_type(data
)
592 (label_high
, label_low_tc_s
, self
.ttl
) = unpack(self
.PACK
, self
.data
[4:])
593 self
.s_bit
= label_low_tc_s
& 0x1
594 self
.traffic_class
= ((label_low_tc_s
& 0xf) >> 1)
595 self
.label
= (label_high
<< 4) |
(label_low_tc_s
>> 4)
596 self
.value
= self
.label
597 self
.value_int
= self
.value
598 self
.value_int_str
= str(self
.value_int
)
602 self
.value_int
= None
603 self
.value_int_str
= None
604 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
607 def dump_lines(self
, dump_buffer
, line_number
, color
):
608 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
609 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8],
610 'label %s, TC %s, bottom-of-stack %s, TTL %d' %
611 (self
.label
, self
.traffic_class
, self
.s_bit
, self
.ttl
)))
617 class AttributeGeneric(Attribute
):
619 def __init__(self
, atype
, string
, family
, logger
):
620 Attribute
.__init
__(self
, atype
, string
, logger
)
624 def decode(self
, parent_msg
, data
):
625 self
.decode_length_type(data
)
626 wordcount
= (self
.attr_end
- 4)/4
627 self
.PACK
= '=%dL' % wordcount
628 self
.LEN
= calcsize(self
.PACK
)
631 self
.value
= ''.join(map(str, unpack(self
.PACK
, self
.data
[4:])))
633 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
637 class AttributeOneByteValue(AttributeGeneric
):
639 def __init__(self
, atype
, string
, family
, logger
):
640 AttributeGeneric
.__init
__(self
, atype
, string
, family
, logger
)
642 self
.LEN
= calcsize(self
.PACK
)
644 def decode(self
, parent_msg
, data
):
645 self
.decode_length_type(data
)
646 assert self
.attr_end
== 8, "Attribute length for %s must be 8, it is %d" % (self
, self
.attr_end
)
649 self
.value
= int(unpack(self
.PACK
, self
.data
[4:8])[0])
651 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:5])))
655 length
= self
.HEADER_LEN
+ self
.LEN
656 raw
= pack(self
.HEADER_PACK
, length
-3, self
.atype
) + pack(self
.PACK
, self
.value
)
657 raw
= self
.pad(length
, raw
)
660 def dump_lines(self
, dump_buffer
, line_number
, color
):
661 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
662 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
663 return line_number
+ 1
666 class AttributeIFLA_AF_SPEC(Attribute
):
668 value will be a dictionary such as:
670 Link.IFLA_BRIDGE_FLAGS: flags,
671 Link.IFLA_BRIDGE_VLAN_INFO: (vflags, vlanid)
674 def __init__(self
, atype
, string
, family
, logger
):
675 Attribute
.__init
__(self
, atype
, string
, logger
)
679 pack_layout
= [self
.HEADER_PACK
]
680 payload
= [0, self
.atype | NLA_F_NESTED
]
681 attr_length_index
= 0
683 # For now this assumes that all data will be packed in the native endian
684 # order (=). If a field is added that needs to be packed via network
685 # order (>) then some smarts will need to be added to split the pack_layout
686 # string at the >, split the payload and make the needed pack() calls.
688 # Until we cross that bridge though we will keep things nice and simple and
689 # pack everything via a single pack() call.
692 for (sub_attr_type
, sub_attr_value
) in self
.value
.iteritems():
694 if sub_attr_type
== Link
.IFLA_BRIDGE_FLAGS
:
695 sub_attr_to_add
.append((sub_attr_type
, sub_attr_value
))
697 elif sub_attr_type
== Link
.IFLA_BRIDGE_VLAN_INFO
:
698 for (vlan_flag
, vlan_id
) in sub_attr_value
:
699 sub_attr_to_add
.append((sub_attr_type
, (vlan_flag
, vlan_id
)))
702 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_AF_SPEC sub-attribute type %d' % sub_attr_type
)
705 for (sub_attr_type
, sub_attr_value
) in sub_attr_to_add
:
706 sub_attr_pack_layout
= ['=', 'HH']
707 sub_attr_payload
= [0, sub_attr_type
]
708 sub_attr_length_index
= 0
710 if sub_attr_type
== Link
.IFLA_BRIDGE_FLAGS
:
711 sub_attr_pack_layout
.append('H')
712 sub_attr_payload
.append(sub_attr_value
)
714 elif sub_attr_type
== Link
.IFLA_BRIDGE_VLAN_INFO
:
715 sub_attr_pack_layout
.append('HH')
716 sub_attr_payload
.append(sub_attr_value
[0])
717 sub_attr_payload
.append(sub_attr_value
[1])
719 sub_attr_length
= calcsize(''.join(sub_attr_pack_layout
))
720 sub_attr_payload
[sub_attr_length_index
] = sub_attr_length
723 for x
in xrange(self
.pad_bytes_needed(sub_attr_length
)):
724 sub_attr_pack_layout
.append('x')
726 # The [1:] is to remove the leading = so that when we do the ''.join() later
727 # we do not end up with an = in the middle of the pack layout string. There
728 # will be an = at the beginning via self.HEADER_PACK
729 sub_attr_pack_layout
= sub_attr_pack_layout
[1:]
731 # Now extend the ovarall attribute pack_layout/payload to include this sub-attribute
732 pack_layout
.extend(sub_attr_pack_layout
)
733 payload
.extend(sub_attr_payload
)
735 pack_layout
= ''.join(pack_layout
)
737 # Fill in the length field
738 length
= calcsize(pack_layout
)
739 payload
[attr_length_index
] = length
741 raw
= pack(pack_layout
, *payload
)
742 raw
= self
.pad(length
, raw
)
745 def decode(self
, parent_msg
, data
):
747 value is a dictionary such as:
749 Link.IFLA_BRIDGE_FLAGS: flags,
750 Link.IFLA_BRIDGE_VLAN_INFO: (vflags, vlanid)
754 The encoding of the IFLA_AF_SPEC attribute varies depending on the family
755 used for the request (RTM_GETLINK) message. For AF_UNSPEC the encoding
756 has another level of nesting for each address family with the type encoded
758 af_spec = nla_nest_start(skb, IFLA_AF_SPEC)
760 af = nla_nest_start(skb, af_ops->family)
761 af_ops->fill_link_af(skb, dev, ext_filter_mask)
765 This allows the parser to find the address family by looking at the first
768 Whereas AF_BRIDGE encoding is just:
769 af_spec = nla_nest_start(skb, IFLA_AF_SPEC)
770 br_fill_ifvlaninfo{_compressed}(skb, vg)
773 which means the parser can not use the attribute itself to know the family
774 to which the attribute belongs.
776 /include/uapi/linux/if_link.h
779 * Contains nested attributes for address family specific attributes.
780 * Each address family may create a attribute with the address family
781 * number as type and create its own attribute structure in it.
786 * [IFLA_INET_CONF] = ...,
789 * [IFLA_INET6_FLAGS] = ...,
790 * [IFLA_INET6_CONF] = ...,
796 self
.decode_length_type(data
)
802 (sub_attr_length
, sub_attr_type
) = unpack('=HH', data
[:4])
803 sub_attr_end
= padded_length(sub_attr_length
)
805 if not sub_attr_length
:
806 self
.log
.error('parsed a zero length sub-attr')
809 sub_attr_data
= data
[4:sub_attr_end
]
811 if self
.family
== AF_BRIDGE
:
812 if sub_attr_type
== Link
.IFLA_BRIDGE_FLAGS
:
813 self
.value
[Link
.IFLA_BRIDGE_FLAGS
] = unpack("=H", sub_attr_data
[0:2])[0]
815 elif sub_attr_type
== Link
.IFLA_BRIDGE_VLAN_INFO
:
816 if Link
.IFLA_BRIDGE_VLAN_INFO
not in self
.value
:
817 self
.value
[Link
.IFLA_BRIDGE_VLAN_INFO
] = []
818 self
.value
[Link
.IFLA_BRIDGE_VLAN_INFO
].append(tuple(unpack("=HH", sub_attr_data
[0:4])))
821 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_AF_SPEC sub-attribute '
822 'type %s (%d), length %d, padded to %d' %
823 (parent_msg
.get_ifla_bridge_af_spec_to_string(sub_attr_type
),
824 sub_attr_type
, sub_attr_length
, sub_attr_end
))
826 elif self
.family
== AF_UNSPEC
:
828 if sub_attr_type
== AF_INET6
:
832 (inet6_attr_length
, inet6_attr_type
) = unpack('=HH', sub_attr_data
[:4])
833 inet6_attr_end
= padded_length(inet6_attr_length
)
836 if inet6_attr_type
== Link
.IFLA_INET6_ADDR_GEN_MODE
:
837 inet6_attr
[inet6_attr_type
] = unpack('=B', sub_attr_data
[4])[0]
838 # nlmanager doesn't support multiple kernel version
839 # all the other attributes like IFLA_INET6_CONF are
840 # based on DEVCONF_MAX from _UAPI_IPV6_H.
841 # we can opti the code and break this loop once we
842 # found the attribute that we are interested in.
843 # It's not really worth going through all the other
844 # attributes to log that we don't support them yet
849 'Add support for decoding AF_INET6 IFLA_AF_SPEC '
850 'sub-attribute type %s (%d), length %d, padded to %d'
852 parent_msg
.get_ifla_inet6_af_spec_to_string(inet6_attr_type
),
853 inet6_attr_type
, inet6_attr_length
, inet6_attr_end
857 sub_attr_data
= sub_attr_data
[inet6_attr_end
:]
858 self
.value
[AF_INET6
] = inet6_attr
860 self
.value
[sub_attr_type
] = {}
862 # Uncomment the following block to implement the AF_INET attributes
863 # see Link.get_ifla_inet_af_spec_to_string (dict)
864 #elif sub_attr_type == AF_INET:
867 # while sub_attr_data:
868 # (inet_attr_length, inet_attr_type) = unpack('=HH', sub_attr_data[:4])
869 # inet_attr_end = padded_length(inet_attr_length)
872 # # SYSLOG_EXTRA_DEBUG,
873 # 'Add support for decoding AF_INET IFLA_AF_SPEC '
874 # 'sub-attribute type %s (%d), length %d, padded to %d'
876 # parent_msg.get_ifla_inet_af_spec_to_string(inet_attr_type),
877 # inet_attr_type, inet_attr_length, inet_attr_end
881 # sub_attr_data = sub_attr_data[inet_attr_end:]
883 # self.value[AF_INET] = inet_attr
885 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_AF_SPEC sub-attribute '
886 'family %d, length %d, padded to %d'
887 % (self
.family
, sub_attr_length
, sub_attr_end
))
889 data
= data
[sub_attr_end
:]
891 def dump_lines(self
, dump_buffer
, line_number
, color
):
892 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
895 next_sub_attr_line
= 0
898 for x
in xrange(1, self
.attr_end
/4):
902 if line_number
== next_sub_attr_line
:
906 sub_attr_line
= False
908 (sub_attr_length
, sub_attr_type
) = unpack('=HH', self
.data
[start
:start
+4])
909 sub_attr_end
= padded_length(sub_attr_length
)
911 next_sub_attr_line
= line_number
+ (sub_attr_end
/4)
913 if sub_attr_end
== sub_attr_length
:
916 padded_to
= ' padded to %d,' % sub_attr_end
918 if self
.family
== AF_BRIDGE
:
919 extra
= 'Nested Attribute - Length %s (%d)%s Type %s (%d) %s' % \
920 (zfilled_hex(sub_attr_length
, 4), sub_attr_length
,
922 zfilled_hex(sub_attr_type
, 4), sub_attr_type
,
923 Link
.ifla_bridge_af_spec_to_string
.get(sub_attr_type
))
924 elif self
.family
== AF_UNSPEC
:
925 if sub_attr_type
== AF_INET6
:
927 elif sub_attr_type
== AF_INET
:
930 family
= 'Unsupported family %d' % sub_attr_type
932 extra
= 'Nested Attribute Structure for %s - Length %s (%d)%s Type %s (%d)' % (
933 family
, zfilled_hex(sub_attr_length
, 4), sub_attr_length
, padded_to
,
934 zfilled_hex(sub_attr_type
, 4), sub_attr_type
,
939 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], extra
))
944 def get_pretty_value(self
, obj
=None):
946 if obj
and callable(obj
):
947 return obj(self
.value
)
949 # We do this so we can print a more human readable dictionary
950 # with the names of the nested keys instead of their numbers
953 if self
.family
== AF_BRIDGE
:
954 for (sub_key
, sub_value
) in self
.value
.iteritems():
955 sub_key_pretty
= "(%2d) %s" % (sub_key
, Link
.ifla_bridge_af_spec_to_string
.get(sub_key
))
956 value_pretty
[sub_key_pretty
] = sub_value
957 elif self
.family
== AF_UNSPEC
:
958 for (family
, family_attr
) in self
.value
.iteritems():
959 family_value_pretty
= {}
961 if family
== AF_INET6
:
962 family_af_spec_to_string
= Link
.ifla_inet6_af_spec_to_string
963 elif family
== AF_INET
:
964 family_af_spec_to_string
= Link
.ifla_inet_af_spec_to_string
966 continue # log error?
968 for (sub_key
, sub_value
) in family_attr
.iteritems():
969 sub_key_pretty
= "(%2d) %s" % (sub_key
, family_af_spec_to_string
.get(sub_key
))
970 family_value_pretty
[sub_key_pretty
] = sub_value
971 value_pretty
= family_value_pretty
977 class AttributeRTA_MULTIPATH(Attribute
):
979 /* RTA_MULTIPATH --- array of struct rtnexthop.
981 * "struct rtnexthop" describes all necessary nexthop information,
982 * i.e. parameters of path to a destination via this nexthop.
984 * At the moment it is impossible to set different prefsrc, mtu, window
985 * and rtt for different paths from multipath.
989 unsigned short rtnh_len;
990 unsigned char rtnh_flags;
991 unsigned char rtnh_hops;
996 def __init__(self
, atype
, string
, family
, logger
):
997 Attribute
.__init
__(self
, atype
, string
, logger
)
1001 self
.RTNH_PACK
= '=HBBL' # rtnh_len, flags, hops, ifindex
1002 self
.RTNH_LEN
= calcsize(self
.RTNH_PACK
)
1008 # Calculate the length
1009 if self
.family
== AF_INET
:
1010 ip_len
= self
.IPV4_LEN
1011 elif self
.family
== AF_INET6
:
1012 ip_len
= self
.IPV6_LEN
1015 length
= self
.HEADER_LEN
+ ((self
.RTNH_LEN
+ self
.HEADER_LEN
+ ip_len
) * len(self
.value
))
1016 raw
= pack(self
.HEADER_PACK
, length
, self
.atype
)
1020 rtnh_len
= self
.RTNH_LEN
+ self
.HEADER_LEN
+ ip_len
1022 for (nexthop
, rtnh_ifindex
) in self
.value
:
1025 raw
+= pack(self
.RTNH_PACK
, rtnh_len
, rtnh_flags
, rtnh_hops
, rtnh_ifindex
)
1028 raw
+= pack(self
.HEADER_PACK
, self
.HEADER_LEN
+ ip_len
, Route
.RTA_GATEWAY
)
1030 if self
.family
== AF_INET
:
1031 raw
+= pack('>L', nexthop
)
1032 elif self
.family
== AF_INET6
:
1033 raw
+= pack('>QQ', nexthop
>> 64, nexthop
& 0x0000000000000000FFFFFFFFFFFFFFFF)
1035 raw
= self
.pad(length
, raw
)
1038 def decode(self
, parent_msg
, data
):
1039 self
.decode_length_type(data
)
1042 data
= self
.data
[4:]
1045 (rtnh_len
, rtnh_flags
, rtnh_hops
, rtnh_ifindex
) = unpack(self
.RTNH_PACK
, data
[:self
.RTNH_LEN
])
1046 data
= data
[self
.RTNH_LEN
:]
1048 (attr_type
, attr_length
) = unpack(self
.HEADER_PACK
, self
.data
[:self
.HEADER_LEN
])
1049 data
= data
[self
.HEADER_LEN
:]
1051 if self
.family
== AF_INET
:
1052 if len(data
) < self
.IPV4_LEN
:
1054 nexthop
= IPv4Address(unpack('>L', data
[:self
.IPV4_LEN
])[0])
1055 self
.value
.append((nexthop
, rtnh_ifindex
, rtnh_flags
, rtnh_hops
))
1057 elif self
.family
== AF_INET6
:
1058 if len(data
) < self
.IPV6_LEN
:
1060 (data1
, data2
) = unpack('>QQ', data
[:self
.IPV6_LEN
])
1061 nexthop
= IPv6Address(data1
<< 64 | data2
)
1062 self
.value
.append((nexthop
, rtnh_ifindex
, rtnh_flags
, rtnh_hops
))
1064 data
= data
[(rtnh_len
-self
.RTNH_LEN
-self
.HEADER_LEN
):]
1066 self
.value
= tuple(self
.value
)
1069 class AttributeIFLA_LINKINFO(Attribute
):
1071 value is a dictionary such as:
1074 Link.IFLA_INFO_KIND : 'vlan',
1075 Link.IFLA_INFO_DATA : {
1076 Link.IFLA_VLAN_ID : vlanid,
1080 def __init__(self
, atype
, string
, family
, logger
):
1081 Attribute
.__init
__(self
, atype
, string
, logger
)
1084 pack_layout
= [self
.HEADER_PACK
]
1085 payload
= [0, self
.atype | NLA_F_NESTED
]
1086 attr_length_index
= 0
1088 kind
= self
.value
.get(Link
.IFLA_INFO_KIND
)
1089 slave_kind
= self
.value
.get(Link
.IFLA_INFO_SLAVE_KIND
)
1091 if not slave_kind
and kind
not in ('vlan', 'macvlan', 'vxlan', 'bond', 'bridge'):
1092 raise Exception('Unsupported IFLA_INFO_KIND %s' % kind
)
1093 elif not kind
and slave_kind
!= 'bridge':
1094 # only support brport for now.
1095 raise Exception('Unsupported IFLA_INFO_SLAVE_KIND %s' % slave_kind
)
1097 # For now this assumes that all data will be packed in the native endian
1098 # order (=). If a field is added that needs to be packed via network
1099 # order (>) then some smarts will need to be added to split the pack_layout
1100 # string at the >, split the payload and make the needed pack() calls.
1102 # Until we cross that bridge though we will keep things nice and simple and
1103 # pack everything via a single pack() call.
1104 for (sub_attr_type
, sub_attr_value
) in self
.value
.iteritems():
1105 sub_attr_pack_layout
= ['=', 'HH']
1106 sub_attr_payload
= [0, sub_attr_type
]
1107 sub_attr_length_index
= 0
1109 if sub_attr_type
== Link
.IFLA_INFO_KIND
:
1110 sub_attr_pack_layout
.append('%ds' % len(sub_attr_value
))
1111 sub_attr_payload
.append(sub_attr_value
)
1113 elif sub_attr_type
== Link
.IFLA_INFO_DATA
:
1115 sub_attr_payload
= [0, sub_attr_type | NLA_F_NESTED
]
1117 for (info_data_type
, info_data_value
) in sub_attr_value
.iteritems():
1120 if info_data_type
== Link
.IFLA_VLAN_ID
:
1121 sub_attr_pack_layout
.append('HH')
1122 sub_attr_payload
.append(6) # length
1123 sub_attr_payload
.append(info_data_type
)
1126 sub_attr_pack_layout
.append('H')
1127 sub_attr_payload
.append(info_data_value
)
1130 sub_attr_pack_layout
.extend('xx')
1132 elif info_data_type
== Link
.IFLA_VLAN_PROTOCOL
:
1133 sub_attr_pack_layout
.append('HH')
1134 sub_attr_payload
.append(6) # length
1135 sub_attr_payload
.append(info_data_type
)
1138 vlan_protocol
= Link
.ifla_vlan_protocol_dict
.get(info_data_value
)
1139 if not vlan_protocol
:
1140 raise NotImplementedError('vlan protocol %s not implemented' % info_data_value
)
1142 sub_attr_pack_layout
.append('H')
1143 sub_attr_payload
.append(htons(vlan_protocol
))
1146 sub_attr_pack_layout
.extend('xx')
1148 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA vlan sub-attribute type %d' % info_data_type
)
1150 elif kind
== 'macvlan':
1151 if info_data_type
== Link
.IFLA_MACVLAN_MODE
:
1152 sub_attr_pack_layout
.append('HH')
1153 sub_attr_payload
.append(8) # length
1154 sub_attr_payload
.append(info_data_type
)
1157 sub_attr_pack_layout
.append('L')
1158 sub_attr_payload
.append(info_data_value
)
1161 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA macvlan sub-attribute type %d' % info_data_type
)
1163 elif kind
== 'vxlan':
1164 if info_data_type
in (Link
.IFLA_VXLAN_ID
,
1165 Link
.IFLA_VXLAN_LINK
,
1166 Link
.IFLA_VXLAN_AGEING
,
1167 Link
.IFLA_VXLAN_LIMIT
,
1168 Link
.IFLA_VXLAN_PORT_RANGE
):
1169 sub_attr_pack_layout
.append('HH')
1170 sub_attr_payload
.append(8) # length
1171 sub_attr_payload
.append(info_data_type
)
1173 sub_attr_pack_layout
.append('L')
1174 sub_attr_payload
.append(info_data_value
)
1176 elif info_data_type
in (Link
.IFLA_VXLAN_GROUP
,
1177 Link
.IFLA_VXLAN_LOCAL
):
1178 sub_attr_pack_layout
.append('HH')
1179 sub_attr_payload
.append(8) # length
1180 sub_attr_payload
.append(info_data_type
)
1182 sub_attr_pack_layout
.append('L')
1184 reorder
= unpack('<L', IPv4Address(info_data_value
).packed
)[0]
1185 sub_attr_payload
.append(IPv4Address(reorder
))
1187 elif info_data_type
in (Link
.IFLA_VXLAN_PORT
,):
1188 sub_attr_pack_layout
.append('HH')
1189 sub_attr_payload
.append(6)
1190 sub_attr_payload
.append(info_data_type
)
1192 sub_attr_pack_layout
.append('H')
1195 swaped
= pack(">H", info_data_value
)
1196 sub_attr_payload
.append(unpack("<H", swaped
)[0])
1198 sub_attr_pack_layout
.extend('xx')
1200 elif info_data_type
in (Link
.IFLA_VXLAN_TTL
,
1201 Link
.IFLA_VXLAN_TOS
,
1202 Link
.IFLA_VXLAN_LEARNING
,
1203 Link
.IFLA_VXLAN_PROXY
,
1204 Link
.IFLA_VXLAN_RSC
,
1205 Link
.IFLA_VXLAN_L2MISS
,
1206 Link
.IFLA_VXLAN_L3MISS
,
1207 Link
.IFLA_VXLAN_UDP_CSUM
,
1208 Link
.IFLA_VXLAN_UDP_ZERO_CSUM6_TX
,
1209 Link
.IFLA_VXLAN_UDP_ZERO_CSUM6_RX
,
1210 Link
.IFLA_VXLAN_REMCSUM_TX
,
1211 Link
.IFLA_VXLAN_REMCSUM_RX
,
1212 Link
.IFLA_VXLAN_REPLICATION_TYPE
):
1213 sub_attr_pack_layout
.append('HH')
1214 sub_attr_payload
.append(6)
1215 sub_attr_payload
.append(info_data_type
)
1217 sub_attr_pack_layout
.append('B')
1218 sub_attr_payload
.append(info_data_value
)
1219 sub_attr_pack_layout
.extend('xxx')
1222 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA vxlan sub-attribute type %d' % info_data_type
)
1224 elif kind
== 'bond':
1225 if info_data_type
in (Link
.IFLA_BOND_AD_ACTOR_SYSTEM
, ):
1226 sub_attr_pack_layout
.append('HH')
1227 sub_attr_payload
.append(10) # length
1228 sub_attr_payload
.append(info_data_type
)
1230 sub_attr_pack_layout
.append('6B')
1231 for mbyte
in info_data_value
.replace('.', ' ').replace(':', ' ').split():
1232 sub_attr_payload
.append(int(mbyte
, 16))
1233 sub_attr_pack_layout
.extend('xx')
1235 elif info_data_type
== Link
.IFLA_BOND_AD_ACTOR_SYS_PRIO
:
1236 sub_attr_pack_layout
.append('HH')
1237 sub_attr_payload
.append(6) # length
1238 sub_attr_payload
.append(info_data_type
)
1241 sub_attr_pack_layout
.append('H')
1242 sub_attr_payload
.append(int(info_data_value
))
1245 sub_attr_pack_layout
.extend('xx')
1247 elif info_data_type
== Link
.IFLA_BOND_NUM_PEER_NOTIF
:
1248 sub_attr_pack_layout
.append('HH')
1249 sub_attr_payload
.append(5) # length
1250 sub_attr_payload
.append(info_data_type
)
1253 sub_attr_pack_layout
.append('B')
1254 sub_attr_payload
.append(int(info_data_value
))
1257 sub_attr_pack_layout
.extend('xxx')
1260 elif info_data_type
in (Link
.IFLA_BOND_AD_LACP_RATE
,
1261 Link
.IFLA_BOND_AD_LACP_BYPASS
,
1262 Link
.IFLA_BOND_USE_CARRIER
):
1263 # converts yes/no/on/off/0/1 strings to boolean value
1264 bool_value
= self
.get_bool_value(info_data_value
)
1266 sub_attr_pack_layout
.append('HH')
1267 sub_attr_payload
.append(5) # length
1268 sub_attr_payload
.append(info_data_type
)
1271 sub_attr_pack_layout
.append('B')
1272 sub_attr_payload
.append(bool_value
)
1275 sub_attr_pack_layout
.extend('xxx')
1277 elif info_data_type
== Link
.IFLA_BOND_XMIT_HASH_POLICY
:
1278 index
= self
.get_index(Link
.ifla_bond_xmit_hash_policy_tbl
,
1279 'bond xmit hash policy',
1282 sub_attr_pack_layout
.append('HH')
1283 sub_attr_payload
.append(5) # length
1284 sub_attr_payload
.append(info_data_type
)
1287 sub_attr_pack_layout
.append('B')
1288 sub_attr_payload
.append(index
)
1291 sub_attr_pack_layout
.extend('xxx')
1293 elif info_data_type
== Link
.IFLA_BOND_MODE
:
1294 index
= self
.get_index(Link
.ifla_bond_mode_tbl
,
1298 sub_attr_pack_layout
.append('HH')
1299 sub_attr_payload
.append(5) # length
1300 sub_attr_payload
.append(info_data_type
)
1303 sub_attr_pack_layout
.append('B')
1304 sub_attr_payload
.append(index
)
1307 sub_attr_pack_layout
.extend('xxx')
1309 elif info_data_type
in (Link
.IFLA_BOND_MIIMON
,
1310 Link
.IFLA_BOND_UPDELAY
,
1311 Link
.IFLA_BOND_DOWNDELAY
,
1312 Link
.IFLA_BOND_MIN_LINKS
):
1313 sub_attr_pack_layout
.append('HH')
1314 sub_attr_payload
.append(8) # length
1315 sub_attr_payload
.append(info_data_type
)
1317 sub_attr_pack_layout
.append('L')
1318 sub_attr_payload
.append(int(info_data_value
))
1321 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA bond sub-attribute type %d' % info_data_type
)
1323 elif kind
== 'bridge':
1324 if info_data_type
== Link
.IFLA_BR_VLAN_PROTOCOL
:
1325 sub_attr_pack_layout
.append('HH')
1326 sub_attr_payload
.append(6) # length
1327 sub_attr_payload
.append(info_data_type
)
1330 vlan_protocol
= Link
.ifla_vlan_protocol_dict
.get(info_data_value
)
1331 if not vlan_protocol
:
1332 raise NotImplementedError('vlan protocol %s not implemented' % info_data_value
)
1334 sub_attr_pack_layout
.append('H')
1335 sub_attr_payload
.append(htons(vlan_protocol
))
1338 sub_attr_pack_layout
.extend('xx')
1341 elif info_data_type
in (Link
.IFLA_BR_VLAN_FILTERING
,
1342 Link
.IFLA_BR_TOPOLOGY_CHANGE
,
1343 Link
.IFLA_BR_TOPOLOGY_CHANGE_DETECTED
,
1344 Link
.IFLA_BR_MCAST_ROUTER
,
1345 Link
.IFLA_BR_MCAST_SNOOPING
,
1346 Link
.IFLA_BR_MCAST_QUERY_USE_IFADDR
,
1347 Link
.IFLA_BR_MCAST_QUERIER
,
1348 Link
.IFLA_BR_NF_CALL_IPTABLES
,
1349 Link
.IFLA_BR_NF_CALL_IP6TABLES
,
1350 Link
.IFLA_BR_NF_CALL_ARPTABLES
,
1351 Link
.IFLA_BR_VLAN_STATS_ENABLED
,
1352 Link
.IFLA_BR_MCAST_STATS_ENABLED
,
1353 Link
.IFLA_BR_MCAST_IGMP_VERSION
,
1354 Link
.IFLA_BR_MCAST_MLD_VERSION
):
1355 sub_attr_pack_layout
.append('HH')
1356 sub_attr_payload
.append(5) # length
1357 sub_attr_payload
.append(info_data_type
)
1360 sub_attr_pack_layout
.append('B')
1361 sub_attr_payload
.append(int(info_data_value
))
1364 sub_attr_pack_layout
.extend('xxx')
1367 elif info_data_type
in (Link
.IFLA_BR_PRIORITY
,
1368 Link
.IFLA_BR_GROUP_FWD_MASK
,
1369 Link
.IFLA_BR_ROOT_PORT
,
1370 Link
.IFLA_BR_VLAN_DEFAULT_PVID
):
1371 sub_attr_pack_layout
.append('HH')
1372 sub_attr_payload
.append(6) # length
1373 sub_attr_payload
.append(info_data_type
)
1376 sub_attr_pack_layout
.append('H')
1377 sub_attr_payload
.append(int(info_data_value
))
1380 sub_attr_pack_layout
.extend('xx')
1383 elif info_data_type
in (Link
.IFLA_BR_FORWARD_DELAY
,
1384 Link
.IFLA_BR_HELLO_TIME
,
1385 Link
.IFLA_BR_MAX_AGE
,
1386 Link
.IFLA_BR_AGEING_TIME
,
1387 Link
.IFLA_BR_STP_STATE
,
1388 Link
.IFLA_BR_ROOT_PATH_COST
,
1389 Link
.IFLA_BR_MCAST_QUERIER
,
1390 Link
.IFLA_BR_MCAST_HASH_ELASTICITY
,
1391 Link
.IFLA_BR_MCAST_HASH_MAX
,
1392 Link
.IFLA_BR_MCAST_LAST_MEMBER_CNT
,
1393 Link
.IFLA_BR_MCAST_STARTUP_QUERY_CNT
):
1394 sub_attr_pack_layout
.append('HH')
1395 sub_attr_payload
.append(8) # length
1396 sub_attr_payload
.append(info_data_type
)
1398 sub_attr_pack_layout
.append('L')
1399 sub_attr_payload
.append(int(info_data_value
))
1402 elif info_data_type
in (Link
.IFLA_BR_MCAST_LAST_MEMBER_INTVL
,
1403 Link
.IFLA_BR_MCAST_MEMBERSHIP_INTVL
,
1404 Link
.IFLA_BR_MCAST_QUERIER_INTVL
,
1405 Link
.IFLA_BR_MCAST_QUERY_INTVL
,
1406 Link
.IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
,
1407 Link
.IFLA_BR_MCAST_STARTUP_QUERY_INTVL
):
1408 sub_attr_pack_layout
.append('HH')
1409 sub_attr_payload
.append(12) # length
1410 sub_attr_payload
.append(info_data_type
)
1412 sub_attr_pack_layout
.append('Q')
1413 sub_attr_payload
.append(int(info_data_value
))
1416 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA bridge sub-attribute type %d' % info_data_type
)
1418 elif sub_attr_type
== Link
.IFLA_INFO_SLAVE_DATA
:
1420 sub_attr_payload
= [0, sub_attr_type | NLA_F_NESTED
]
1422 for (info_slave_data_type
, info_slave_data_value
) in sub_attr_value
.iteritems():
1424 if slave_kind
== 'bridge':
1427 if info_slave_data_type
in (Link
.IFLA_BRPORT_STATE
,
1428 Link
.IFLA_BRPORT_MODE
,
1429 Link
.IFLA_BRPORT_GUARD
,
1430 Link
.IFLA_BRPORT_PROTECT
,
1431 Link
.IFLA_BRPORT_FAST_LEAVE
,
1432 Link
.IFLA_BRPORT_LEARNING
,
1433 Link
.IFLA_BRPORT_UNICAST_FLOOD
,
1434 Link
.IFLA_BRPORT_PROXYARP
,
1435 Link
.IFLA_BRPORT_LEARNING_SYNC
,
1436 Link
.IFLA_BRPORT_PROXYARP_WIFI
,
1437 Link
.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
,
1438 Link
.IFLA_BRPORT_CONFIG_PENDING
,
1439 Link
.IFLA_BRPORT_MULTICAST_ROUTER
,
1440 Link
.IFLA_BRPORT_MCAST_FLOOD
,
1441 Link
.IFLA_BRPORT_MCAST_TO_UCAST
,
1442 Link
.IFLA_BRPORT_VLAN_TUNNEL
,
1443 Link
.IFLA_BRPORT_BCAST_FLOOD
,
1444 Link
.IFLA_BRPORT_PEER_LINK
,
1445 Link
.IFLA_BRPORT_DUAL_LINK
,
1446 Link
.IFLA_BRPORT_ARP_SUPPRESS
,
1447 Link
.IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
):
1448 sub_attr_pack_layout
.append('HH')
1449 sub_attr_payload
.append(5) # length
1450 sub_attr_payload
.append(info_slave_data_type
)
1453 sub_attr_pack_layout
.append('B')
1454 sub_attr_payload
.append(int(info_slave_data_value
))
1457 sub_attr_pack_layout
.extend('xxx')
1460 elif info_slave_data_type
in (Link
.IFLA_BRPORT_PRIORITY
,
1461 Link
.IFLA_BRPORT_DESIGNATED_PORT
,
1462 Link
.IFLA_BRPORT_DESIGNATED_COST
,
1463 Link
.IFLA_BRPORT_ID
,
1464 Link
.IFLA_BRPORT_NO
,
1465 Link
.IFLA_BRPORT_GROUP_FWD_MASK
,
1466 Link
.IFLA_BRPORT_GROUP_FWD_MASKHI
):
1467 sub_attr_pack_layout
.append('HH')
1468 sub_attr_payload
.append(6) # length
1469 sub_attr_payload
.append(info_slave_data_type
)
1472 sub_attr_pack_layout
.append('H')
1473 sub_attr_payload
.append(int(info_slave_data_value
))
1476 sub_attr_pack_layout
.extend('xx')
1479 elif info_slave_data_type
== Link
.IFLA_BRPORT_COST
:
1480 sub_attr_pack_layout
.append('HH')
1481 sub_attr_payload
.append(8) # length
1482 sub_attr_payload
.append(info_slave_data_type
)
1484 sub_attr_pack_layout
.append('L')
1485 sub_attr_payload
.append(int(info_slave_data_value
))
1488 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_SLAVE_DATA bond sub-attribute type %d' % info_slave_data_type
)
1491 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_LINKINFO kind %s' % slave_kind
)
1494 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_LINKINFO sub-attribute type %d' % sub_attr_type
)
1497 sub_attr_length
= calcsize(''.join(sub_attr_pack_layout
))
1498 sub_attr_payload
[sub_attr_length_index
] = sub_attr_length
1501 for x
in xrange(self
.pad_bytes_needed(sub_attr_length
)):
1502 sub_attr_pack_layout
.append('x')
1504 # The [1:] is to remove the leading = so that when we do the ''.join() later
1505 # we do not end up with an = in the middle of the pack layout string. There
1506 # will be an = at the beginning via self.HEADER_PACK
1507 sub_attr_pack_layout
= sub_attr_pack_layout
[1:]
1509 # Now extend the ovarall attribute pack_layout/payload to include this sub-attribute
1510 pack_layout
.extend(sub_attr_pack_layout
)
1511 payload
.extend(sub_attr_payload
)
1513 pack_layout
= ''.join(pack_layout
)
1515 # Fill in the length field
1516 length
= calcsize(pack_layout
)
1517 payload
[attr_length_index
] = length
1519 raw
= pack(pack_layout
, *payload
)
1520 raw
= self
.pad(length
, raw
)
1523 def get_bool_value(self
, value
, default
=None):
1525 return value_to_bool_dict
[value
]
1527 self
.log
.debug('%s: unsupported boolean value' % value
)
1530 def get_index(self
, tbl
, attr
, value
, default
=None):
1534 self
.log
.debug('unsupported %s value %s (%s)' % (attr
, value
, tbl
.keys()))
1537 def decode(self
, parent_msg
, data
):
1539 value is a dictionary such as:
1542 Link.IFLA_INFO_KIND : 'vlan',
1543 Link.IFLA_INFO_DATA : {
1544 Link.IFLA_VLAN_ID : vlanid,
1548 self
.decode_length_type(data
)
1551 data
= self
.data
[4:]
1553 # IFLA_MACVLAN_MODE and IFLA_VLAN_ID both have a value of 1 and both are
1554 # valid IFLA_INFO_DATA entries :( The sender must TX IFLA_INFO_KIND
1555 # first in order for us to know if "1" is IFLA_MACVLAN_MODE vs IFLA_VLAN_ID.
1558 (sub_attr_length
, sub_attr_type
) = unpack('=HH', data
[:4])
1559 sub_attr_end
= padded_length(sub_attr_length
)
1561 if not sub_attr_length
:
1562 self
.log
.error('parsed a zero length sub-attr')
1565 if sub_attr_type
in (Link
.IFLA_INFO_KIND
, Link
.IFLA_INFO_SLAVE_KIND
):
1566 self
.value
[sub_attr_type
] = remove_trailing_null(unpack('%ds' % (sub_attr_length
- 4), data
[4:sub_attr_length
])[0])
1568 elif sub_attr_type
== Link
.IFLA_INFO_SLAVE_DATA
:
1569 sub_attr_data
= data
[4:sub_attr_end
]
1571 ifla_info_slave_data
= dict()
1572 ifla_info_slave_kind
= self
.value
.get(Link
.IFLA_INFO_SLAVE_KIND
)
1574 if not ifla_info_slave_kind
:
1575 self
.log
.warning('IFLA_INFO_SLAVE_KIND is not known...we cannot parse IFLA_INFO_SLAVE_DATA')
1577 while sub_attr_data
:
1578 (info_data_length
, info_data_type
) = unpack('=HH', sub_attr_data
[:4])
1579 info_data_end
= padded_length(info_data_length
)
1581 if ifla_info_slave_kind
== 'bridge':
1583 if info_data_type
in (Link
.IFLA_BRPORT_STATE
,
1584 Link
.IFLA_BRPORT_MODE
,
1585 Link
.IFLA_BRPORT_GUARD
,
1586 Link
.IFLA_BRPORT_PROTECT
,
1587 Link
.IFLA_BRPORT_FAST_LEAVE
,
1588 Link
.IFLA_BRPORT_LEARNING
,
1589 Link
.IFLA_BRPORT_UNICAST_FLOOD
,
1590 Link
.IFLA_BRPORT_PROXYARP
,
1591 Link
.IFLA_BRPORT_LEARNING_SYNC
,
1592 Link
.IFLA_BRPORT_PROXYARP_WIFI
,
1593 Link
.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
,
1594 Link
.IFLA_BRPORT_CONFIG_PENDING
,
1595 Link
.IFLA_BRPORT_MULTICAST_ROUTER
,
1596 Link
.IFLA_BRPORT_MCAST_FLOOD
,
1597 Link
.IFLA_BRPORT_MCAST_TO_UCAST
,
1598 Link
.IFLA_BRPORT_VLAN_TUNNEL
,
1599 Link
.IFLA_BRPORT_PEER_LINK
,
1600 Link
.IFLA_BRPORT_DUAL_LINK
,
1601 Link
.IFLA_BRPORT_ARP_SUPPRESS
,
1602 Link
.IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
):
1603 ifla_info_slave_data
[info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1606 elif info_data_type
in (Link
.IFLA_BRPORT_PRIORITY
,
1607 Link
.IFLA_BRPORT_DESIGNATED_PORT
,
1608 Link
.IFLA_BRPORT_DESIGNATED_COST
,
1609 Link
.IFLA_BRPORT_ID
,
1610 Link
.IFLA_BRPORT_NO
,
1611 Link
.IFLA_BRPORT_GROUP_FWD_MASK
,
1612 Link
.IFLA_BRPORT_GROUP_FWD_MASKHI
):
1613 ifla_info_slave_data
[info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1616 elif info_data_type
== Link
.IFLA_BRPORT_COST
:
1617 ifla_info_slave_data
[info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1619 elif ifla_info_slave_kind
== 'bond':
1622 if info_data_type
in (
1623 Link
.IFLA_BOND_SLAVE_STATE
,
1624 Link
.IFLA_BOND_SLAVE_MII_STATUS
,
1625 Link
.IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE
,
1626 Link
.IFLA_BOND_SLAVE_AD_RX_BYPASS
,
1628 ifla_info_slave_data
[info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1631 elif info_data_type
in (
1632 Link
.IFLA_BOND_SLAVE_QUEUE_ID
,
1633 Link
.IFLA_BOND_SLAVE_AD_AGGREGATOR_ID
1635 ifla_info_slave_data
[info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1638 elif info_data_type
== (
1639 Link
.IFLA_BOND_SLAVE_PERM_HWADDR
,
1640 Link
.IFLA_BOND_SLAVE_LINK_FAILURE_COUNT
1642 ifla_info_slave_data
[info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1644 except Exception as e
:
1645 self
.log
.debug('%s: attribute %s: %s'
1646 % (self
.value
[Link
.IFLA_INFO_SLAVE_KIND
],
1649 sub_attr_data
= sub_attr_data
[info_data_end
:]
1651 self
.value
[Link
.IFLA_INFO_SLAVE_DATA
] = ifla_info_slave_data
1653 elif sub_attr_type
== Link
.IFLA_INFO_DATA
:
1654 sub_attr_data
= data
[4:sub_attr_end
]
1655 self
.value
[Link
.IFLA_INFO_DATA
] = {}
1657 ifla_info_kind
= self
.value
.get(Link
.IFLA_INFO_KIND
)
1658 if not ifla_info_kind
:
1659 self
.log
.warning('IFLA_INFO_KIND is not known...we cannot parse IFLA_INFO_DATA')
1661 while sub_attr_data
:
1662 (info_data_length
, info_data_type
) = unpack('=HH', sub_attr_data
[:4])
1663 info_data_end
= padded_length(info_data_length
)
1665 if ifla_info_kind
== 'vlan':
1666 if info_data_type
== Link
.IFLA_VLAN_ID
:
1667 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1669 elif info_data_type
== Link
.IFLA_VLAN_PROTOCOL
:
1670 hex_value
= '0x%s' % sub_attr_data
[4:6].encode('hex')
1671 vlan_protocol
= Link
.ifla_vlan_protocol_dict
.get(int(hex_value
, base
=16))
1674 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = vlan_protocol
1676 self
.log
.warning('IFLA_VLAN_PROTOCOL: cannot decode vlan protocol %s' % hex_value
)
1679 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND vlan type %s (%d), length %d, padded to %d' %
1680 (parent_msg
.get_ifla_vlan_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1682 elif ifla_info_kind
== 'macvlan':
1683 if info_data_type
== Link
.IFLA_MACVLAN_MODE
:
1684 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1686 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND macvlan type %s (%d), length %d, padded to %d' %
1687 (parent_msg
.get_ifla_macvlan_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1689 elif ifla_info_kind
== 'vxlan':
1692 if info_data_type
in (Link
.IFLA_VXLAN_GROUP
,
1693 Link
.IFLA_VXLAN_LOCAL
):
1694 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = IPv4Address(unpack('>L', sub_attr_data
[4:8])[0])
1697 elif info_data_type
in (Link
.IFLA_VXLAN_ID
,
1698 Link
.IFLA_VXLAN_LINK
,
1699 Link
.IFLA_VXLAN_AGEING
,
1700 Link
.IFLA_VXLAN_LIMIT
,
1701 Link
.IFLA_VXLAN_PORT_RANGE
):
1702 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1705 elif info_data_type
in (Link
.IFLA_VXLAN_PORT
, ):
1706 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('!H', sub_attr_data
[4:6])[0]
1707 # The form '!' is available for those poor souls who claim they can't
1708 # remember whether network byte order is big-endian or little-endian.
1711 elif info_data_type
in (Link
.IFLA_VXLAN_TTL
,
1712 Link
.IFLA_VXLAN_TOS
,
1713 Link
.IFLA_VXLAN_LEARNING
,
1714 Link
.IFLA_VXLAN_PROXY
,
1715 Link
.IFLA_VXLAN_RSC
,
1716 Link
.IFLA_VXLAN_L2MISS
,
1717 Link
.IFLA_VXLAN_L3MISS
,
1718 Link
.IFLA_VXLAN_UDP_CSUM
,
1719 Link
.IFLA_VXLAN_UDP_ZERO_CSUM6_TX
,
1720 Link
.IFLA_VXLAN_UDP_ZERO_CSUM6_RX
,
1721 Link
.IFLA_VXLAN_REMCSUM_TX
,
1722 Link
.IFLA_VXLAN_REMCSUM_RX
,
1723 Link
.IFLA_VXLAN_REPLICATION_TYPE
):
1724 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1727 # sub_attr_end = padded_length(sub_attr_length)
1728 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND vxlan type %s (%d), length %d, padded to %d' %
1729 (parent_msg
.get_ifla_vxlan_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1731 elif ifla_info_kind
== 'bond':
1733 if info_data_type
in (Link
.IFLA_BOND_AD_INFO
, ):
1734 ad_attr_data
= sub_attr_data
[4:info_data_end
]
1735 self
.value
[Link
.IFLA_INFO_DATA
][Link
.IFLA_BOND_AD_INFO
] = {}
1738 (ad_data_length
, ad_data_type
) = unpack('=HH', ad_attr_data
[:4])
1739 ad_data_end
= padded_length(ad_data_length
)
1741 if ad_data_type
in (Link
.IFLA_BOND_AD_INFO_PARTNER_MAC
,):
1742 (data1
, data2
) = unpack('>LHxx', ad_attr_data
[4:12])
1743 self
.value
[Link
.IFLA_INFO_DATA
][Link
.IFLA_BOND_AD_INFO
][ad_data_type
] = mac_int_to_str(data1
<< 16 | data2
)
1745 ad_attr_data
= ad_attr_data
[ad_data_end
:]
1748 elif info_data_type
in (Link
.IFLA_BOND_MODE
,
1749 Link
.IFLA_BOND_USE_CARRIER
,
1750 Link
.IFLA_BOND_AD_LACP_RATE
,
1751 Link
.IFLA_BOND_AD_LACP_BYPASS
,
1752 Link
.IFLA_BOND_XMIT_HASH_POLICY
,
1753 Link
.IFLA_BOND_NUM_PEER_NOTIF
):
1754 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1757 elif info_data_type
== Link
.IFLA_BOND_AD_ACTOR_SYS_PRIO
:
1758 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1761 elif info_data_type
in (Link
.IFLA_BOND_MIIMON
,
1762 Link
.IFLA_BOND_UPDELAY
,
1763 Link
.IFLA_BOND_DOWNDELAY
,
1764 Link
.IFLA_BOND_MIN_LINKS
):
1765 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1768 elif info_data_type
in (Link
.IFLA_BOND_AD_ACTOR_SYSTEM
, ):
1769 (data1
, data2
) = unpack('>LHxx', sub_attr_data
[4:12])
1770 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = mac_int_to_str(data1
<< 16 | data2
)
1773 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND bond type %s (%d), length %d, padded to %d' %
1774 (parent_msg
.get_ifla_bond_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1776 elif ifla_info_kind
== 'bridge':
1778 if info_data_type
in (Link
.IFLA_BR_AGEING_TIME
,
1779 Link
.IFLA_BR_FORWARD_DELAY
,
1780 Link
.IFLA_BR_HELLO_TIME
,
1781 Link
.IFLA_BR_MAX_AGE
,
1782 Link
.IFLA_BR_STP_STATE
,
1783 Link
.IFLA_BR_ROOT_PATH_COST
,
1784 Link
.IFLA_BR_MCAST_HASH_ELASTICITY
,
1785 Link
.IFLA_BR_MCAST_HASH_MAX
,
1786 Link
.IFLA_BR_MCAST_LAST_MEMBER_CNT
,
1787 Link
.IFLA_BR_MCAST_STARTUP_QUERY_CNT
):
1788 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1791 elif info_data_type
in (Link
.IFLA_BR_PRIORITY
,
1792 Link
.IFLA_BR_GROUP_FWD_MASK
,
1793 Link
.IFLA_BR_ROOT_PORT
,
1794 Link
.IFLA_BR_VLAN_DEFAULT_PVID
):
1795 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1797 elif info_data_type
== Link
.IFLA_BR_VLAN_PROTOCOL
:
1798 hex_value
= '0x%s' % sub_attr_data
[4:6].encode('hex')
1799 vlan_protocol
= Link
.ifla_vlan_protocol_dict
.get(int(hex_value
, base
=16))
1802 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = vlan_protocol
1804 self
.log
.warning('IFLA_VLAN_PROTOCOL: cannot decode vlan protocol %s' % hex_value
)
1807 elif info_data_type
in (Link
.IFLA_BR_MCAST_MEMBERSHIP_INTVL
,
1808 Link
.IFLA_BR_MCAST_QUERIER_INTVL
,
1809 Link
.IFLA_BR_MCAST_LAST_MEMBER_INTVL
,
1810 Link
.IFLA_BR_MCAST_MEMBERSHIP_INTVL
,
1811 Link
.IFLA_BR_MCAST_QUERIER_INTVL
,
1812 Link
.IFLA_BR_MCAST_QUERY_INTVL
,
1813 Link
.IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
,
1814 Link
.IFLA_BR_MCAST_STARTUP_QUERY_INTVL
):
1815 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=Q', sub_attr_data
[4:12])[0]
1818 elif info_data_type
in (Link
.IFLA_BR_VLAN_FILTERING
,
1819 Link
.IFLA_BR_TOPOLOGY_CHANGE
,
1820 Link
.IFLA_BR_TOPOLOGY_CHANGE_DETECTED
,
1821 Link
.IFLA_BR_MCAST_ROUTER
,
1822 Link
.IFLA_BR_MCAST_SNOOPING
,
1823 Link
.IFLA_BR_MCAST_QUERY_USE_IFADDR
,
1824 Link
.IFLA_BR_MCAST_QUERIER
,
1825 Link
.IFLA_BR_NF_CALL_IPTABLES
,
1826 Link
.IFLA_BR_NF_CALL_IP6TABLES
,
1827 Link
.IFLA_BR_NF_CALL_ARPTABLES
,
1828 Link
.IFLA_BR_VLAN_STATS_ENABLED
,
1829 Link
.IFLA_BR_MCAST_STATS_ENABLED
,
1830 Link
.IFLA_BR_MCAST_IGMP_VERSION
,
1831 Link
.IFLA_BR_MCAST_MLD_VERSION
):
1832 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1834 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND bridge type %s (%d), length %d, padded to %d' %
1835 (parent_msg
.get_ifla_br_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1837 elif ifla_info_kind
== 'vrf':
1839 if info_data_type
in (Link
.IFLA_VRF_TABLE
,):
1840 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1844 self
.log
.log(SYSLOG_EXTRA_DEBUG
, "Add support for decoding IFLA_INFO_KIND %s (%d), length %d, padded to %d" %
1845 (ifla_info_kind
, info_data_type
, info_data_length
, info_data_end
))
1847 except Exception as e
:
1848 self
.log
.debug('%s: attribute %s: %s'
1849 % (self
.value
[Link
.IFLA_INFO_KIND
],
1852 sub_attr_data
= sub_attr_data
[info_data_end
:]
1855 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_LINKINFO sub-attribute type %s (%d), length %d, padded to %d' %
1856 (parent_msg
.get_ifla_info_string(sub_attr_type
), sub_attr_type
, sub_attr_length
, sub_attr_end
))
1858 data
= data
[sub_attr_end
:]
1860 # self.log.info('IFLA_LINKINFO values %s' % pformat(self.value))
1862 def dump_lines(self
, dump_buffer
, line_number
, color
):
1863 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
1866 next_sub_attr_line
= 0
1867 sub_attr_line
= True
1869 for x
in xrange(1, self
.attr_end
/4):
1873 if line_number
== next_sub_attr_line
:
1874 sub_attr_line
= True
1877 sub_attr_line
= False
1879 (sub_attr_length
, sub_attr_type
) = unpack('=HH', self
.data
[start
:start
+4])
1880 sub_attr_end
= padded_length(sub_attr_length
)
1882 next_sub_attr_line
= line_number
+ (sub_attr_end
/4)
1884 if sub_attr_end
== sub_attr_length
:
1887 padded_to
= ' padded to %d, ' % sub_attr_end
1889 extra
= 'Nested Attribute - Length %s (%d)%s Type %s (%d) %s' % \
1890 (zfilled_hex(sub_attr_length
, 4), sub_attr_length
,
1892 zfilled_hex(sub_attr_type
, 4), sub_attr_type
,
1893 Link
.ifla_info_to_string
.get(sub_attr_type
))
1897 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], extra
))
1902 def get_pretty_value(self
, obj
=None):
1904 if obj
and callable(obj
):
1905 return obj(self
.value
)
1907 value_pretty
= self
.value
1908 ifla_info_kind
= self
.value
.get(Link
.IFLA_INFO_KIND
)
1909 ifla_info_slave_kind
= self
.value
.get(Link
.IFLA_INFO_SLAVE_KIND
)
1913 # We do this so we can print a more human readable dictionary
1914 # with the names of the nested keys instead of their numbers
1916 # Most of these are placeholders...we need to add support
1917 # for more human readable dictionaries for bond, bridge, etc
1918 kind_dict
[Link
.IFLA_INFO_DATA
] = {
1919 'bond': Link
.ifla_bond_to_string
,
1920 'vlan': Link
.ifla_vlan_to_string
,
1921 'vxlan': Link
.ifla_vxlan_to_string
,
1922 'bridge': Link
.ifla_br_to_string
,
1923 'macvlan': Link
.ifla_macvlan_to_string
1924 }.get(ifla_info_kind
, {})
1926 kind_dict
[Link
.IFLA_INFO_SLAVE_DATA
] = {
1927 'bridge': Link
.ifla_brport_to_string
,
1928 'bond': Link
.ifla_bond_slave_to_string
1929 }.get(ifla_info_slave_kind
, {})
1931 if ifla_info_kind
or ifla_info_slave_kind
:
1934 for (sub_key
, sub_value
) in self
.value
.iteritems():
1935 sub_key_pretty
= "(%2d) %s" % (sub_key
, Link
.ifla_info_to_string
.get(sub_key
, 'UNKNOWN'))
1936 sub_value_pretty
= sub_value
1938 if sub_key
in (Link
.IFLA_INFO_DATA
, Link
.IFLA_INFO_SLAVE_DATA
):
1939 kind_to_string_dict
= kind_dict
.get(sub_key
, {})
1940 sub_value_pretty
= {}
1942 for (sub_sub_key
, sub_sub_value
) in sub_value
.iteritems():
1943 sub_sub_key_pretty
= "(%2d) %s" % (sub_sub_key
, kind_to_string_dict
.get(sub_sub_key
, 'UNKNOWN'))
1944 sub_value_pretty
[sub_sub_key_pretty
] = sub_sub_value
1946 value_pretty
[sub_key_pretty
] = sub_value_pretty
1951 class AttributeIFLA_PROTINFO(Attribute
):
1953 IFLA_PROTINFO nested attributes.
1955 def __init__(self
, atype
, string
, family
, logger
):
1956 Attribute
.__init
__(self
, atype
, string
, logger
)
1957 self
.family
= family
1960 pack_layout
= [self
.HEADER_PACK
]
1961 payload
= [0, self
.atype | NLA_F_NESTED
]
1962 attr_length_index
= 0
1964 if self
.family
not in (AF_BRIDGE
,):
1965 raise Exception('Unsupported IFLA_PROTINFO family %d' % self
.family
)
1967 # For now this assumes that all data will be packed in the native endian
1968 # order (=). If a field is added that needs to be packed via network
1969 # order (>) then some smarts will need to be added to split the pack_layout
1970 # string at the >, split the payload and make the needed pack() calls.
1972 # Until we cross that bridge though we will keep things nice and simple and
1973 # pack everything via a single pack() call.
1974 for (sub_attr_type
, sub_attr_value
) in self
.value
.iteritems():
1975 sub_attr_pack_layout
= ['=', 'HH']
1976 sub_attr_payload
= [0, sub_attr_type
]
1977 sub_attr_length_index
= 0
1979 if self
.family
== AF_BRIDGE
:
1981 if sub_attr_type
in (Link
.IFLA_BRPORT_STATE
,
1982 Link
.IFLA_BRPORT_MODE
,
1983 Link
.IFLA_BRPORT_GUARD
,
1984 Link
.IFLA_BRPORT_PROTECT
,
1985 Link
.IFLA_BRPORT_FAST_LEAVE
,
1986 Link
.IFLA_BRPORT_LEARNING
,
1987 Link
.IFLA_BRPORT_UNICAST_FLOOD
,
1988 Link
.IFLA_BRPORT_PROXYARP
,
1989 Link
.IFLA_BRPORT_LEARNING_SYNC
,
1990 Link
.IFLA_BRPORT_PROXYARP_WIFI
,
1991 Link
.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
,
1992 Link
.IFLA_BRPORT_CONFIG_PENDING
,
1993 Link
.IFLA_BRPORT_FLUSH
,
1994 Link
.IFLA_BRPORT_MULTICAST_ROUTER
,
1995 Link
.IFLA_BRPORT_PEER_LINK
,
1996 Link
.IFLA_BRPORT_DUAL_LINK
,
1997 Link
.IFLA_BRPORT_ARP_SUPPRESS
,
1998 Link
.IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
):
1999 sub_attr_pack_layout
.append('B')
2000 sub_attr_payload
.append(sub_attr_value
)
2001 sub_attr_pack_layout
.extend('xxx')
2004 elif sub_attr_type
in (Link
.IFLA_BRPORT_PRIORITY
,
2005 Link
.IFLA_BRPORT_DESIGNATED_PORT
,
2006 Link
.IFLA_BRPORT_DESIGNATED_COST
,
2007 Link
.IFLA_BRPORT_ID
,
2008 Link
.IFLA_BRPORT_NO
):
2009 sub_attr_pack_layout
.append('H')
2010 sub_attr_payload
.append(sub_attr_value
)
2011 sub_attr_pack_layout
.extend('xx')
2014 elif sub_attr_type
in (Link
.IFLA_BRPORT_COST
,):
2015 sub_attr_pack_layout
.append('L')
2016 sub_attr_payload
.append(sub_attr_value
)
2019 elif sub_attr_type
in (Link
.IFLA_BRPORT_MESSAGE_AGE_TIMER
,
2020 Link
.IFLA_BRPORT_FORWARD_DELAY_TIMER
,
2021 Link
.IFLA_BRPORT_HOLD_TIMER
):
2022 sub_attr_pack_layout
.append('Q')
2023 sub_attr_payload
.append(sub_attr_value
)
2026 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_PROTINFO sub-attribute type %d' % sub_attr_type
)
2028 sub_attr_length
= calcsize(''.join(sub_attr_pack_layout
))
2029 sub_attr_payload
[sub_attr_length_index
] = sub_attr_length
2032 for x
in xrange(self
.pad_bytes_needed(sub_attr_length
)):
2033 sub_attr_pack_layout
.append('x')
2035 # The [1:] is to remove the leading = so that when we do the ''.join() later
2036 # we do not end up with an = in the middle of the pack layout string. There
2037 # will be an = at the beginning via self.HEADER_PACK
2038 sub_attr_pack_layout
= sub_attr_pack_layout
[1:]
2040 # Now extend the ovarall attribute pack_layout/payload to include this sub-attribute
2041 pack_layout
.extend(sub_attr_pack_layout
)
2042 payload
.extend(sub_attr_payload
)
2044 pack_layout
= ''.join(pack_layout
)
2046 # Fill in the length field
2047 length
= calcsize(pack_layout
)
2048 payload
[attr_length_index
] = length
2050 raw
= pack(pack_layout
, *payload
)
2051 raw
= self
.pad(length
, raw
)
2054 def decode(self
, parent_msg
, data
):
2056 value is a dictionary such as:
2058 Link.IFLA_BRPORT_STATE : 3,
2059 Link.IFLA_BRPORT_PRIORITY : 8
2060 Link.IFLA_BRPORT_COST : 2
2064 self
.decode_length_type(data
)
2067 data
= self
.data
[4:]
2070 (sub_attr_length
, sub_attr_type
) = unpack('=HH', data
[:4])
2071 sub_attr_end
= padded_length(sub_attr_length
)
2073 if not sub_attr_length
:
2074 self
.log
.error('parsed a zero length sub-attr')
2077 if self
.family
== AF_BRIDGE
:
2080 if sub_attr_type
in (Link
.IFLA_BRPORT_STATE
,
2081 Link
.IFLA_BRPORT_MODE
,
2082 Link
.IFLA_BRPORT_GUARD
,
2083 Link
.IFLA_BRPORT_PROTECT
,
2084 Link
.IFLA_BRPORT_FAST_LEAVE
,
2085 Link
.IFLA_BRPORT_LEARNING
,
2086 Link
.IFLA_BRPORT_UNICAST_FLOOD
,
2087 Link
.IFLA_BRPORT_PROXYARP
,
2088 Link
.IFLA_BRPORT_LEARNING_SYNC
,
2089 Link
.IFLA_BRPORT_PROXYARP_WIFI
,
2090 Link
.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
,
2091 Link
.IFLA_BRPORT_CONFIG_PENDING
,
2092 Link
.IFLA_BRPORT_FLUSH
,
2093 Link
.IFLA_BRPORT_MULTICAST_ROUTER
,
2094 Link
.IFLA_BRPORT_PEER_LINK
,
2095 Link
.IFLA_BRPORT_DUAL_LINK
,
2096 Link
.IFLA_BRPORT_ARP_SUPPRESS
,
2097 Link
.IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
):
2098 self
.value
[sub_attr_type
] = unpack('=B', data
[4])[0]
2101 elif sub_attr_type
in (Link
.IFLA_BRPORT_PRIORITY
,
2102 Link
.IFLA_BRPORT_DESIGNATED_PORT
,
2103 Link
.IFLA_BRPORT_DESIGNATED_COST
,
2104 Link
.IFLA_BRPORT_ID
,
2105 Link
.IFLA_BRPORT_NO
):
2106 self
.value
[sub_attr_type
] = unpack('=H', data
[4:6])[0]
2109 elif sub_attr_type
in (Link
.IFLA_BRPORT_COST
,):
2110 self
.value
[sub_attr_type
] = unpack('=L', data
[4:8])[0]
2113 elif sub_attr_type
in (Link
.IFLA_BRPORT_MESSAGE_AGE_TIMER
,
2114 Link
.IFLA_BRPORT_FORWARD_DELAY_TIMER
,
2115 Link
.IFLA_BRPORT_HOLD_TIMER
):
2116 self
.value
[sub_attr_type
] = unpack('=Q', data
[4:12])[0]
2119 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_PROTINFO sub-attribute type %s (%d), length %d, padded to %d' %
2120 (parent_msg
.get_ifla_brport_string(sub_attr_type
), sub_attr_type
, sub_attr_length
, sub_attr_end
))
2122 data
= data
[sub_attr_end
:]
2124 def dump_lines(self
, dump_buffer
, line_number
, color
):
2125 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
2128 next_sub_attr_line
= 0
2129 sub_attr_line
= True
2131 for x
in xrange(1, self
.attr_end
/4):
2135 if line_number
== next_sub_attr_line
:
2136 sub_attr_line
= True
2139 sub_attr_line
= False
2141 (sub_attr_length
, sub_attr_type
) = unpack('=HH', self
.data
[start
:start
+4])
2142 sub_attr_end
= padded_length(sub_attr_length
)
2144 next_sub_attr_line
= line_number
+ (sub_attr_end
/4)
2146 if sub_attr_end
== sub_attr_length
:
2149 padded_to
= ' padded to %d, ' % sub_attr_end
2151 extra
= 'Nested Attribute - Length %s (%d)%s Type %s (%d) %s' % \
2152 (zfilled_hex(sub_attr_length
, 4), sub_attr_length
,
2154 zfilled_hex(sub_attr_type
, 4), sub_attr_type
,
2155 Link
.ifla_brport_to_string
.get(sub_attr_type
))
2159 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], extra
))
2164 def get_pretty_value(self
, obj
=None):
2166 if obj
and callable(obj
):
2167 return obj(self
.value
)
2171 for (sub_key
, sub_value
) in self
.value
.iteritems():
2172 sub_key_pretty
= "(%2d) %s" % (sub_key
, Link
.ifla_brport_to_string
.get(sub_key
, 'UNKNOWN'))
2173 sub_value_pretty
= sub_value
2174 value_pretty
[sub_key_pretty
] = sub_value_pretty
2180 class NetlinkPacket(object):
2185 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
2186 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2188 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2190 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2192 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2193 | Process ID (PID) |
2194 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2197 header_PACK
= 'IHHII'
2198 header_LEN
= calcsize(header_PACK
)
2200 # Netlink packet types
2201 # /usr/include/linux/rtnetlink.h
2203 NLMSG_NOOP
: 'NLMSG_NOOP',
2204 NLMSG_ERROR
: 'NLMSG_ERROR',
2205 NLMSG_DONE
: 'NLMSG_DONE',
2206 NLMSG_OVERRUN
: 'NLMSG_OVERRUN',
2207 RTM_NEWLINK
: 'RTM_NEWLINK',
2208 RTM_DELLINK
: 'RTM_DELLINK',
2209 RTM_GETLINK
: 'RTM_GETLINK',
2210 RTM_SETLINK
: 'RTM_SETLINK',
2211 RTM_NEWADDR
: 'RTM_NEWADDR',
2212 RTM_DELADDR
: 'RTM_DELADDR',
2213 RTM_GETADDR
: 'RTM_GETADDR',
2214 RTM_NEWNEIGH
: 'RTM_NEWNEIGH',
2215 RTM_DELNEIGH
: 'RTM_DELNEIGH',
2216 RTM_GETNEIGH
: 'RTM_GETNEIGH',
2217 RTM_NEWROUTE
: 'RTM_NEWROUTE',
2218 RTM_DELROUTE
: 'RTM_DELROUTE',
2219 RTM_GETROUTE
: 'RTM_GETROUTE',
2220 RTM_NEWQDISC
: 'RTM_NEWQDISC',
2221 RTM_DELQDISC
: 'RTM_DELQDISC',
2222 RTM_GETQDISC
: 'RTM_GETQDISC'
2225 af_family_to_string
= {
2230 def __init__(self
, msgtype
, debug
, owner_logger
=None, use_color
=True):
2231 self
.msgtype
= msgtype
2232 self
.attributes
= {}
2233 self
.dump_buffer
= ['']
2234 self
.line_number
= 1
2237 self
.use_color
= use_color
2241 self
.log
= owner_logger
2246 return self
.get_type_string()
2248 def get_string(self
, to_string
, index
):
2250 Used to do lookups in all of the various FOO_to_string dictionaries
2251 but returns 'UNKNOWN' if the key is bogus
2253 if index
in to_string
:
2254 return to_string
[index
]
2257 def get_type_string(self
, msgtype
=None):
2259 msgtype
= self
.msgtype
2260 return self
.get_string(self
.type_to_string
, msgtype
)
2262 def get_flags_string(self
):
2265 for (flag
, flag_string
) in self
.flag_to_string
.iteritems():
2266 if self
.flags
& flag
:
2267 foo
.append(flag_string
)
2269 return ', '.join(foo
)
2271 def decode_packet(self
, length
, flags
, seq
, pid
, data
):
2272 self
.length
= length
2276 self
.header_data
= data
[0:self
.header_LEN
]
2277 self
.msg_data
= data
[self
.header_LEN
:length
]
2279 self
.decode_netlink_header()
2280 self
.decode_service_header()
2282 # NLMSG_ERROR is special case, it does not have attributes to decode
2283 if self
.msgtype
!= NLMSG_ERROR
:
2284 self
.decode_attributes()
2286 def get_netlink_header_flags_string(self
, msg_type
, flags
):
2289 if flags
& NLM_F_REQUEST
:
2290 foo
.append('NLM_F_REQUEST')
2292 if flags
& NLM_F_MULTI
:
2293 foo
.append('NLM_F_MULTI')
2295 if flags
& NLM_F_ACK
:
2296 foo
.append('NLM_F_ACK')
2298 if flags
& NLM_F_ECHO
:
2299 foo
.append('NLM_F_ECHO')
2301 # Modifiers to GET query
2302 if msg_type
in (RTM_GETLINK
, RTM_GETADDR
, RTM_GETNEIGH
, RTM_GETROUTE
, RTM_GETQDISC
):
2303 if flags
& NLM_F_DUMP
:
2304 foo
.append('NLM_F_DUMP')
2306 if flags
& NLM_F_MATCH
:
2307 foo
.append('NLM_F_MATCH')
2309 if flags
& NLM_F_ROOT
:
2310 foo
.append('NLM_F_ROOT')
2312 if flags
& NLM_F_ATOMIC
:
2313 foo
.append('NLM_F_ATOMIC')
2315 # Modifiers to NEW query
2316 elif msg_type
in (RTM_NEWLINK
, RTM_NEWADDR
, RTM_NEWNEIGH
, RTM_NEWROUTE
, RTM_NEWQDISC
):
2317 if flags
& NLM_F_REPLACE
:
2318 foo
.append('NLM_F_REPLACE')
2320 if flags
& NLM_F_EXCL
:
2321 foo
.append('NLM_F_EXCL')
2323 if flags
& NLM_F_CREATE
:
2324 foo
.append('NLM_F_CREATE')
2326 if flags
& NLM_F_APPEND
:
2327 foo
.append('NLM_F_APPEND')
2329 return ', '.join(foo
)
2331 # When we first RXed the netlink message we had to decode the header to
2332 # determine what type of netlink message we were dealing with. So the
2333 # header has actually already been decoded...what we do here is
2334 # populate the dump_buffer lines with the header content.
2335 def decode_netlink_header(self
):
2340 header_data
= self
.header_data
2342 # Print the netlink header in red
2343 netlink_header_length
= 16
2344 color
= red
if self
.use_color
else None
2345 color_start
= "\033[%dm" % color
if color
else ""
2346 color_end
= "\033[0m" if color
else ""
2347 self
.dump_buffer
.append(" %sNetlink Header%s" % (color_start
, color_end
))
2349 for x
in range(0, netlink_header_length
/4):
2353 if self
.line_number
== 1:
2354 data
= unpack('=L', header_data
[start
:end
])[0]
2355 extra
= "Length %s (%d)" % (zfilled_hex(data
, 8), data
)
2357 elif self
.line_number
== 2:
2358 (data1
, data2
) = unpack('HH', header_data
[start
:end
])
2359 extra
= "Type %s (%d - %s), Flags %s (%s)" % \
2360 (zfilled_hex(data1
, 4), data1
, self
.get_type_string(data1
),
2361 zfilled_hex(data2
, 4), self
.get_netlink_header_flags_string(data1
, data2
))
2363 elif self
.line_number
== 3:
2364 data
= unpack('=L', header_data
[start
:end
])[0]
2365 extra
= "Sequence Number %s (%d)" % (zfilled_hex(data
, 8), data
)
2367 elif self
.line_number
== 4:
2368 data
= unpack('=L', header_data
[start
:end
])[0]
2369 extra
= "Process ID %s (%d)" % (zfilled_hex(data
, 8), data
)
2371 extra
= "Unexpected line number %d" % self
.line_number
2373 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, header_data
[start
:end
], extra
))
2374 self
.line_number
+= 1
2376 def decode_attributes(self
):
2378 Decode the attributes and populate the dump_buffer
2382 self
.dump_buffer
.append(" Attributes")
2383 color
= green
if self
.use_color
else None
2385 data
= self
.msg_data
[self
.LEN
:]
2388 (length
, attr_type
) = unpack('=HH', data
[:4])
2390 # If this is zero we will stay in this loop for forever
2392 self
.log
.error('Length is zero')
2395 if len(data
) < length
:
2396 self
.log
.error("Buffer underrun %d < %d" % (len(data
), length
))
2399 attr
= self
.add_attribute(attr_type
, None)
2401 # Find the end of 'data' for this attribute and decode our section
2402 # of 'data'. attributes are padded for alignment thus the attr_end.
2404 # How the attribute is decoded/unpacked is specific per AttributeXXXX class.
2405 attr_end
= padded_length(length
)
2406 attr
.decode(self
, data
[0:attr_end
])
2409 self
.line_number
= attr
.dump_lines(self
.dump_buffer
, self
.line_number
, color
)
2411 # Alternate back and forth between green and blue
2418 data
= data
[attr_end
:]
2420 def add_attribute(self
, attr_type
, value
):
2421 nested
= True if attr_type
& NLA_F_NESTED
else False
2422 net_byteorder
= True if attr_type
& NLA_F_NET_BYTEORDER
else False
2423 attr_type
= attr_type
& NLA_TYPE_MASK
2425 # Given an attr_type (say RTA_DST) find the type of AttributeXXXX class
2426 # that we will use to store this attribute...AttributeIPAddress in the
2428 if attr_type
in self
.attribute_to_class
:
2429 (attr_string
, attr_class
) = self
.attribute_to_class
[attr_type
]
2432 attribute_to_class is a dictionary where the key is the attr_type, it doesn't
2433 take the family into account. For now we'll handle this as a special case for
2434 MPLS but long term we may need to make key a tuple of the attr_type and family.
2436 if attr_type
== Route
.RTA_DST
and self
.family
== AF_MPLS
:
2437 attr_string
= 'RTA_DST'
2438 attr_class
= AttributeMplsLabel
2441 attr_string
= "UNKNOWN_ATTRIBUTE_%d" % attr_type
2442 attr_class
= AttributeGeneric
2443 self
.log
.debug("Attribute %d is not defined in %s.attribute_to_class, assuming AttributeGeneric" %
2444 (attr_type
, self
.__class
__.__name
__))
2446 attr
= attr_class(attr_type
, attr_string
, self
.family
, self
.log
)
2448 attr
.set_value(value
)
2449 attr
.set_nested(nested
)
2450 attr
.set_net_byteorder(net_byteorder
)
2452 # self.attributes is a dictionary keyed by the attribute type where
2453 # the value is an instance of the corresponding AttributeXXXX class.
2454 self
.attributes
[attr_type
] = attr
2458 def get_attribute_value(self
, attr_type
, default
=None):
2459 if attr_type
not in self
.attributes
:
2462 return self
.attributes
[attr_type
].value
2464 def get_attr_string(self
, attr_type
):
2466 Example: If attr_type is Address.IFA_CACHEINFO return the string 'IFA_CACHEINFO'
2468 if attr_type
in self
.attribute_to_class
:
2469 (attr_string
, attr_class
) = self
.attribute_to_class
[attr_type
]
2471 return str(attr_type
)
2473 def build_message(self
, seq
, pid
):
2478 for attr
in self
.attributes
.itervalues():
2479 attrs
+= attr
.encode()
2481 self
.length
= self
.header_LEN
+ len(self
.body
) + len(attrs
)
2482 self
.header_data
= pack(self
.header_PACK
, self
.length
, self
.msgtype
, self
.flags
, self
.seq
, self
.pid
)
2483 self
.msg_data
= self
.body
+ attrs
2484 self
.message
= self
.header_data
+ self
.msg_data
2487 self
.decode_netlink_header()
2488 self
.decode_service_header()
2489 self
.decode_attributes()
2490 self
.dump("TXed %s, length %d, seq %d, pid %d, flags 0x%x (%s)" %
2491 (self
, self
.length
, self
.seq
, self
.pid
, self
.flags
,
2492 self
.get_netlink_header_flags_string(self
.msgtype
, self
.flags
)))
2494 def pretty_display_dict(self
, dic
, level
):
2495 for k
,v
in dic
.iteritems():
2496 if isinstance(v
, dict):
2497 self
.log
.debug(' '*level
+ str(k
) + ':')
2498 self
.pretty_display_dict(v
, level
+5)
2500 self
.log
.debug(' '*level
+ str(k
) + ': ' + str(v
))
2502 # Print the netlink message in hex. This is only used for debugging.
2503 def dump(self
, desc
=None):
2507 desc
= "RXed %s, length %d, seq %d, pid %d, flags 0x%x" % (self
, self
.length
, self
.seq
, self
.pid
, self
.flags
)
2509 for (attr_type
, attr_obj
) in self
.attributes
.iteritems():
2510 key_string
= "(%2d) %s" % (attr_type
, self
.get_attr_string(attr_type
))
2511 attr_string
[key_string
] = attr_obj
.get_pretty_value()
2514 self
.log
.debug("%s\n%s\n\nAttributes Summary\n%s\n" %
2515 (desc
, '\n'.join(self
.dump_buffer
), pformat(attr_string
)))
2517 # Assume if we are not allowing color output we also don't want embedded
2518 # newline characters in the output. Output each line individually.
2519 self
.log
.debug(desc
)
2520 for line
in self
.dump_buffer
:
2521 self
.log
.debug(line
)
2523 self
.log
.debug("Attributes Summary")
2524 self
.pretty_display_dict(attr_string
, 1)
2527 class Address(NetlinkPacket
):
2531 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
2532 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2533 | Family | Length | Flags | Scope |
2534 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2536 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2539 # Address attributes
2540 # /usr/include/linux/if_addr.h
2545 IFA_BROADCAST
= 0x04
2547 IFA_CACHEINFO
= 0x06
2548 IFA_MULTICAST
= 0x07
2551 attribute_to_class
= {
2552 IFA_UNSPEC
: ('IFA_UNSPEC', AttributeGeneric
),
2553 IFA_ADDRESS
: ('IFA_ADDRESS', AttributeIPAddress
),
2554 IFA_LOCAL
: ('IFA_LOCAL', AttributeIPAddress
),
2555 IFA_LABEL
: ('IFA_LABEL', AttributeString
),
2556 IFA_BROADCAST
: ('IFA_BROADCAST', AttributeIPAddress
),
2557 IFA_ANYCAST
: ('IFA_ANYCAST', AttributeIPAddress
),
2558 IFA_CACHEINFO
: ('IFA_CACHEINFO', AttributeGeneric
),
2559 IFA_MULTICAST
: ('IFA_MULTICAST', AttributeIPAddress
),
2560 IFA_FLAGS
: ('IFA_FLAGS', AttributeGeneric
)
2564 # /usr/include/linux/if_addr.h
2565 IFA_F_SECONDARY
= 0x01
2567 IFA_F_OPTIMISTIC
= 0x04
2568 IFA_F_DADFAILED
= 0x08
2569 IFA_F_HOMEADDRESS
= 0x10
2570 IFA_F_DEPRECATED
= 0x20
2571 IFA_F_TENTATIVE
= 0x40
2572 IFA_F_PERMANENT
= 0x80
2575 IFA_F_SECONDARY
: 'IFA_F_SECONDARY',
2576 IFA_F_NODAD
: 'IFA_F_NODAD',
2577 IFA_F_OPTIMISTIC
: 'IFA_F_OPTIMISTIC',
2578 IFA_F_DADFAILED
: 'IFA_F_DADFAILED',
2579 IFA_F_HOMEADDRESS
: 'IFA_F_HOMEADDRESS',
2580 IFA_F_DEPRECATED
: 'IFA_F_DEPRECATED',
2581 IFA_F_TENTATIVE
: 'IFA_F_TENTATIVE',
2582 IFA_F_PERMANENT
: 'IFA_F_PERMANENT'
2585 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
2586 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
2588 self
.LEN
= calcsize(self
.PACK
)
2590 def decode_service_header(self
):
2592 # Nothing to do if the message did not contain a service header
2593 if self
.length
== self
.header_LEN
:
2596 (self
.family
, self
.prefixlen
, self
.flags
, self
.scope
,
2598 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
2601 color
= yellow
if self
.use_color
else None
2602 color_start
= "\033[%dm" % color
if color
else ""
2603 color_end
= "\033[0m" if color
else ""
2604 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
2606 for x
in range(0, self
.LEN
/4):
2607 if self
.line_number
== 5:
2608 extra
= "Family %s (%d), Length %s (%d), Flags %s, Scope %s (%d)" % \
2609 (zfilled_hex(self
.family
, 2), self
.family
,
2610 zfilled_hex(self
.prefixlen
, 2), self
.prefixlen
,
2611 zfilled_hex(self
.flags
, 2),
2612 zfilled_hex(self
.scope
, 2), self
.scope
)
2613 elif self
.line_number
== 6:
2614 extra
= "Interface Index %s (%d)" % (zfilled_hex(self
.ifindex
, 8), self
.ifindex
)
2616 extra
= "Unexpected line number %d" % self
.line_number
2620 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
2621 self
.line_number
+= 1
2624 class Error(NetlinkPacket
):
2627 # /include/netlink/errno.h
2638 NLE_OPNOTSUPP
= 0x0A
2639 NLE_AF_NOSUPPORT
= 0x0B
2640 NLE_OBJ_NOTFOUND
= 0x0C
2642 NLE_MISSING_ATTR
= 0x0E
2643 NLE_AF_MISMATCH
= 0x0F
2644 NLE_SEQ_MISMATCH
= 0x10
2645 NLE_MSG_OVERFLOW
= 0x11
2646 NLE_MSG_TRUNC
= 0x12
2648 NLE_SRCRT_NOSUPPORT
= 0x14
2649 NLE_MSG_TOOSHORT
= 0x15
2650 NLE_MSGTYPE_NOSUPPORT
= 0x16
2651 NLE_OBJ_MISMATCH
= 0x17
2654 NLE_PROTO_MISMATCH
= 0x1A
2657 NLE_PKTLOC_FILE
= 0x1D
2658 NLE_PARSE_ERR
= 0x1E
2660 NLE_IMMUTABLE
= 0x20
2661 NLE_DUMP_INTR
= 0x21
2664 NLE_SUCCESS
: 'NLE_SUCCESS',
2665 NLE_FAILURE
: 'NLE_FAILURE',
2666 NLE_INTR
: 'NLE_INTR',
2667 NLE_BAD_SOCK
: 'NLE_BAD_SOCK',
2668 NLE_AGAIN
: 'NLE_AGAIN',
2669 NLE_NOMEM
: 'NLE_NOMEM',
2670 NLE_EXIST
: 'NLE_EXIST',
2671 NLE_INVAL
: 'NLE_INVAL',
2672 NLE_RANGE
: 'NLE_RANGE',
2673 NLE_MSGSIZE
: 'NLE_MSGSIZE',
2674 NLE_OPNOTSUPP
: 'NLE_OPNOTSUPP',
2675 NLE_AF_NOSUPPORT
: 'NLE_AF_NOSUPPORT',
2676 NLE_OBJ_NOTFOUND
: 'NLE_OBJ_NOTFOUND',
2677 NLE_NOATTR
: 'NLE_NOATTR',
2678 NLE_MISSING_ATTR
: 'NLE_MISSING_ATTR',
2679 NLE_AF_MISMATCH
: 'NLE_AF_MISMATCH',
2680 NLE_SEQ_MISMATCH
: 'NLE_SEQ_MISMATCH',
2681 NLE_MSG_OVERFLOW
: 'NLE_MSG_OVERFLOW',
2682 NLE_MSG_TRUNC
: 'NLE_MSG_TRUNC',
2683 NLE_NOADDR
: 'NLE_NOADDR',
2684 NLE_SRCRT_NOSUPPORT
: 'NLE_SRCRT_NOSUPPORT',
2685 NLE_MSG_TOOSHORT
: 'NLE_MSG_TOOSHORT',
2686 NLE_MSGTYPE_NOSUPPORT
: 'NLE_MSGTYPE_NOSUPPORT',
2687 NLE_OBJ_MISMATCH
: 'NLE_OBJ_MISMATCH',
2688 NLE_NOCACHE
: 'NLE_NOCACHE',
2689 NLE_BUSY
: 'NLE_BUSY',
2690 NLE_PROTO_MISMATCH
: 'NLE_PROTO_MISMATCH',
2691 NLE_NOACCESS
: 'NLE_NOACCESS',
2692 NLE_PERM
: 'NLE_PERM',
2693 NLE_PKTLOC_FILE
: 'NLE_PKTLOC_FILE',
2694 NLE_PARSE_ERR
: 'NLE_PARSE_ERR',
2695 NLE_NODEV
: 'NLE_NODEV',
2696 NLE_IMMUTABLE
: 'NLE_IMMUTABLE',
2697 NLE_DUMP_INTR
: 'NLE_DUMP_INTR'
2700 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
2701 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
2702 self
.PACK
= '=iLHHLL'
2703 self
.LEN
= calcsize(self
.PACK
)
2705 def decode_service_header(self
):
2707 # Nothing to do if the message did not contain a service header
2708 if self
.length
== self
.header_LEN
:
2711 (self
.negative_errno
, self
.bad_msg_len
, self
.bad_msg_type
,
2712 self
.bad_msg_flag
, self
.bad_msg_seq
, self
.bad_msg_pid
) =\
2713 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
2716 color
= yellow
if self
.use_color
else None
2717 color_start
= "\033[%dm" % color
if color
else ""
2718 color_end
= "\033[0m" if color
else ""
2719 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
2721 for x
in range(0, self
.LEN
/4):
2723 if self
.line_number
== 5:
2724 extra
= "Error Number %s is %s" % (self
.negative_errno
, self
.error_to_string
.get(abs(self
.negative_errno
)))
2725 # zfilled_hex(self.negative_errno, 2)
2727 elif self
.line_number
== 6:
2728 extra
= "Length %s (%d)" % (zfilled_hex(self
.bad_msg_len
, 8), self
.bad_msg_len
)
2730 elif self
.line_number
== 7:
2731 extra
= "Type %s (%d - %s), Flags %s (%s)" % \
2732 (zfilled_hex(self
.bad_msg_type
, 4), self
.bad_msg_type
, self
.get_type_string(self
.bad_msg_type
),
2733 zfilled_hex(self
.bad_msg_flag
, 4), self
.get_netlink_header_flags_string(self
.bad_msg_type
, self
.bad_msg_flag
))
2735 elif self
.line_number
== 8:
2736 extra
= "Sequence Number %s (%d)" % (zfilled_hex(self
.bad_msg_seq
, 8), self
.bad_msg_seq
)
2738 elif self
.line_number
== 9:
2739 extra
= "Process ID %s (%d)" % (zfilled_hex(self
.bad_msg_pid
, 8), self
.bad_msg_pid
)
2742 extra
= "Unexpected line number %d" % self
.line_number
2746 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
2747 self
.line_number
+= 1
2750 class Link(NetlinkPacket
):
2755 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
2756 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2757 | Family | Reserved | Device Type |
2758 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2760 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2762 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2764 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2768 # /usr/include/linux/if_link.h
2788 IFLA_NET_NS_PID
= 19
2791 IFLA_VFINFO_LIST
= 22
2799 IFLA_PROMISCUITY
= 30
2800 IFLA_NUM_TX_QUEUES
= 31
2801 IFLA_NUM_RX_QUEUES
= 32
2803 IFLA_PHYS_PORT_ID
= 34
2804 IFLA_CARRIER_CHANGES
= 35
2805 IFLA_PHYS_SWITCH_ID
= 36
2806 IFLA_LINK_NETNSID
= 37
2807 IFLA_PHYS_PORT_NAME
= 38
2808 IFLA_PROTO_DOWN
= 39
2809 IFLA_GSO_MAX_SEGS
= 40
2810 IFLA_GSO_MAX_SIZE
= 41
2812 attribute_to_class
= {
2813 IFLA_UNSPEC
: ('IFLA_UNSPEC', AttributeGeneric
),
2814 IFLA_ADDRESS
: ('IFLA_ADDRESS', AttributeMACAddress
),
2815 IFLA_BROADCAST
: ('IFLA_BROADCAST', AttributeMACAddress
),
2816 IFLA_IFNAME
: ('IFLA_IFNAME', AttributeStringInterfaceName
),
2817 IFLA_MTU
: ('IFLA_MTU', AttributeFourByteValue
),
2818 IFLA_LINK
: ('IFLA_LINK', AttributeFourByteValue
),
2819 IFLA_QDISC
: ('IFLA_QDISC', AttributeString
),
2820 IFLA_STATS
: ('IFLA_STATS', AttributeGeneric
),
2821 IFLA_COST
: ('IFLA_COST', AttributeGeneric
),
2822 IFLA_PRIORITY
: ('IFLA_PRIORITY', AttributeGeneric
),
2823 IFLA_MASTER
: ('IFLA_MASTER', AttributeFourByteValue
),
2824 IFLA_WIRELESS
: ('IFLA_WIRELESS', AttributeGeneric
),
2825 IFLA_PROTINFO
: ('IFLA_PROTINFO', AttributeIFLA_PROTINFO
),
2826 IFLA_TXQLEN
: ('IFLA_TXQLEN', AttributeFourByteValue
),
2827 IFLA_MAP
: ('IFLA_MAP', AttributeGeneric
),
2828 IFLA_WEIGHT
: ('IFLA_WEIGHT', AttributeGeneric
),
2829 IFLA_OPERSTATE
: ('IFLA_OPERSTATE', AttributeOneByteValue
),
2830 IFLA_LINKMODE
: ('IFLA_LINKMODE', AttributeOneByteValue
),
2831 IFLA_LINKINFO
: ('IFLA_LINKINFO', AttributeIFLA_LINKINFO
),
2832 IFLA_NET_NS_PID
: ('IFLA_NET_NS_PID', AttributeGeneric
),
2833 IFLA_IFALIAS
: ('IFLA_IFALIAS', AttributeGeneric
),
2834 IFLA_NUM_VF
: ('IFLA_NUM_VF', AttributeGeneric
),
2835 IFLA_VFINFO_LIST
: ('IFLA_VFINFO_LIST', AttributeGeneric
),
2836 IFLA_STATS64
: ('IFLA_STATS64', AttributeGeneric
),
2837 IFLA_VF_PORTS
: ('IFLA_VF_PORTS', AttributeGeneric
),
2838 IFLA_PORT_SELF
: ('IFLA_PORT_SELF', AttributeGeneric
),
2839 IFLA_AF_SPEC
: ('IFLA_AF_SPEC', AttributeIFLA_AF_SPEC
),
2840 IFLA_GROUP
: ('IFLA_GROUP', AttributeFourByteValue
),
2841 IFLA_NET_NS_FD
: ('IFLA_NET_NS_FD', AttributeGeneric
),
2842 IFLA_EXT_MASK
: ('IFLA_EXT_MASK', AttributeFourByteValue
),
2843 IFLA_PROMISCUITY
: ('IFLA_PROMISCUITY', AttributeGeneric
),
2844 IFLA_NUM_TX_QUEUES
: ('IFLA_NUM_TX_QUEUES', AttributeGeneric
),
2845 IFLA_NUM_RX_QUEUES
: ('IFLA_NUM_RX_QUEUES', AttributeGeneric
),
2846 IFLA_CARRIER
: ('IFLA_CARRIER', AttributeGeneric
),
2847 IFLA_PHYS_PORT_ID
: ('IFLA_PHYS_PORT_ID', AttributeGeneric
),
2848 IFLA_CARRIER_CHANGES
: ('IFLA_CARRIER_CHANGES', AttributeGeneric
),
2849 IFLA_PHYS_SWITCH_ID
: ('IFLA_PHYS_SWITCH_ID', AttributeGeneric
),
2850 IFLA_LINK_NETNSID
: ('IFLA_LINK_NETNSID', AttributeGeneric
),
2851 IFLA_PHYS_PORT_NAME
: ('IFLA_PHYS_PORT_NAME', AttributeGeneric
),
2852 IFLA_PROTO_DOWN
: ('IFLA_PROTO_DOWN', AttributeOneByteValue
),
2853 IFLA_GSO_MAX_SEGS
: ('IFLA_GSO_MAX_SEGS', AttributeFourByteValue
),
2854 IFLA_GSO_MAX_SIZE
: ('IFLA_GSO_MAX_SIZE', AttributeFourByteValue
)
2858 # /usr/include/linux/if.h
2859 IFF_UP
= 0x0001 # Interface is administratively up.
2860 IFF_BROADCAST
= 0x0002 # Valid broadcast address set.
2861 IFF_DEBUG
= 0x0004 # Internal debugging flag.
2862 IFF_LOOPBACK
= 0x0008 # Interface is a loopback interface.
2863 IFF_POINTOPOINT
= 0x0010 # Interface is a point-to-point link.
2864 IFF_NOTRAILERS
= 0x0020 # Avoid use of trailers.
2865 IFF_RUNNING
= 0x0040 # Interface is operationally up.
2866 IFF_NOARP
= 0x0080 # No ARP protocol needed for this interface.
2867 IFF_PROMISC
= 0x0100 # Interface is in promiscuous mode.
2868 IFF_ALLMULTI
= 0x0200 # Receive all multicast packets.
2869 IFF_MASTER
= 0x0400 # Master of a load balancing bundle.
2870 IFF_SLAVE
= 0x0800 # Slave of a load balancing bundle.
2871 IFF_MULTICAST
= 0x1000 # Supports multicast.
2872 IFF_PORTSEL
= 0x2000 # Is able to select media type via ifmap.
2873 IFF_AUTOMEDIA
= 0x4000 # Auto media selection active.
2874 IFF_DYNAMIC
= 0x8000 # Interface was dynamically created.
2875 IFF_LOWER_UP
= 0x10000 # driver signals L1 up
2876 IFF_DORMANT
= 0x20000 # driver signals dormant
2877 IFF_ECHO
= 0x40000 # echo sent packet
2878 IFF_PROTO_DOWN
= 0x1000000 # protocol is down on the interface
2882 IFF_BROADCAST
: 'IFF_BROADCAST',
2883 IFF_DEBUG
: 'IFF_DEBUG',
2884 IFF_LOOPBACK
: 'IFF_LOOPBACK',
2885 IFF_POINTOPOINT
: 'IFF_POINTOPOINT',
2886 IFF_NOTRAILERS
: 'IFF_NOTRAILERS',
2887 IFF_RUNNING
: 'IFF_RUNNING',
2888 IFF_NOARP
: 'IFF_NOARP',
2889 IFF_PROMISC
: 'IFF_PROMISC',
2890 IFF_ALLMULTI
: 'IFF_ALLMULTI',
2891 IFF_MASTER
: 'IFF_MASTER',
2892 IFF_SLAVE
: 'IFF_SLAVE',
2893 IFF_MULTICAST
: 'IFF_MULTICAST',
2894 IFF_PORTSEL
: 'IFF_PORTSEL',
2895 IFF_AUTOMEDIA
: 'IFF_AUTOMEDIA',
2896 IFF_DYNAMIC
: 'IFF_DYNAMIC',
2897 IFF_LOWER_UP
: 'IFF_LOWER_UP',
2898 IFF_DORMANT
: 'IFF_DORMANT',
2899 IFF_ECHO
: 'IFF_ECHO',
2900 IFF_PROTO_DOWN
: 'IFF_PROTO_DOWN'
2903 # RFC 2863 operational status
2905 IF_OPER_NOTPRESENT
= 1
2907 IF_OPER_LOWERLAYERDOWN
= 3
2913 IF_OPER_UNKNOWN
: 'IF_OPER_UNKNOWN',
2914 IF_OPER_NOTPRESENT
: 'IF_OPER_NOTPRESENT',
2915 IF_OPER_DOWN
: 'IF_OPER_DOWN',
2916 IF_OPER_LOWERLAYERDOWN
: 'IF_OPER_LOWERLAYERDOWN',
2917 IF_OPER_TESTING
: 'IF_OPER_TESTING',
2918 IF_OPER_DORMANT
: 'IF_OPER_DORMANT',
2919 IF_OPER_UP
: 'IF_OPER_UP'
2923 # /usr/include/linux/if_arp.h
2924 # ARP protocol HARDWARE identifiers
2925 ARPHRD_NETROM
= 0 # from KA9Q: NET/ROM pseudo
2926 ARPHRD_ETHER
= 1 # Ethernet 10Mbps
2927 ARPHRD_EETHER
= 2 # Experimental Ethernet
2928 ARPHRD_AX25
= 3 # AX.25 Level 2
2929 ARPHRD_PRONET
= 4 # PROnet token ring
2930 ARPHRD_CHAOS
= 5 # Chaosnet
2931 ARPHRD_IEEE802
= 6 # IEEE 802.2 Ethernet/TR/TB
2932 ARPHRD_ARCNET
= 7 # ARCnet
2933 ARPHRD_APPLETLK
= 8 # APPLEtalk
2934 ARPHRD_DLCI
= 15 # Frame Relay DLCI
2935 ARPHRD_ATM
= 19 # ATM
2936 ARPHRD_METRICOM
= 23 # Metricom STRIP (new IANA id)
2937 ARPHRD_IEEE1394
= 24 # IEEE 1394 IPv4 - RFC 2734
2938 ARPHRD_EUI64
= 27 # EUI-64
2939 ARPHRD_INFINIBAND
= 32 # InfiniBand
2940 # Dummy types for non ARP hardware
2945 ARPHRD_RSRVD
= 260 # Notional KISS type
2948 ARPHRD_X25
= 271 # CCITT X.25
2949 ARPHRD_HWX25
= 272 # Boards with X.25 in firmware
2950 ARPHRD_CAN
= 280 # Controller Area Network
2952 ARPHRD_CISCO
= 513 # Cisco HDLC
2953 ARPHRD_HDLC
= ARPHRD_CISCO
2954 ARPHRD_LAPB
= 516 # LAPB
2955 ARPHRD_DDCMP
= 517 # Digital's DDCMP protocol
2956 ARPHRD_RAWHDLC
= 518 # Raw HDLC
2957 ARPHRD_TUNNEL
= 768 # IPIP tunnel
2958 ARPHRD_TUNNEL6
= 769 # IP6IP6 tunnel
2959 ARPHRD_FRAD
= 770 # Frame Relay Access Device
2960 ARPHRD_SKIP
= 771 # SKIP vif
2961 ARPHRD_LOOPBACK
= 772 # Loopback device
2962 ARPHRD_LOCALTLK
= 773 # Localtalk device
2963 ARPHRD_FDDI
= 774 # Fiber Distributed Data Interface
2964 ARPHRD_BIF
= 775 # AP1000 BIF
2965 ARPHRD_SIT
= 776 # sit0 device - IPv6-in-IPv4
2966 ARPHRD_IPDDP
= 777 # IP over DDP tunneller
2967 ARPHRD_IPGRE
= 778 # GRE over IP
2968 ARPHRD_PIMREG
= 779 # PIMSM register interface
2969 ARPHRD_HIPPI
= 780 # High Performance Parallel Interface
2970 ARPHRD_ASH
= 781 # Nexus 64Mbps Ash
2971 ARPHRD_ECONET
= 782 # Acorn Econet
2972 ARPHRD_IRDA
= 783 # Linux-IrDA
2973 ARPHRD_FCPP
= 784 # Point to point fibrechannel
2974 ARPHRD_FCAL
= 785 # Fibrechannel arbitrated loop
2975 ARPHRD_FCPL
= 786 # Fibrechannel public loop
2976 ARPHRD_FCFABRIC
= 787 # Fibrechannel fabric
2977 # 787->799 reserved for fibrechannel media types
2978 ARPHRD_IEEE802_TR
= 800 # Magic type ident for TR
2979 ARPHRD_IEEE80211
= 801 # IEEE 802.11
2980 ARPHRD_IEEE80211_PRISM
= 802 # IEEE 802.11 + Prism2 header
2981 ARPHRD_IEEE80211_RADIOTAP
= 803 # IEEE 802.11 + radiotap header
2982 ARPHRD_IEEE802154
= 804
2983 ARPHRD_PHONET
= 820 # PhoNet media type
2984 ARPHRD_PHONET_PIPE
= 821 # PhoNet pipe header
2985 ARPHRD_CAIF
= 822 # CAIF media type
2986 ARPHRD_VOID
= 0xFFFF # Void type, nothing is known
2987 ARPHRD_NONE
= 0xFFFE # zero header length
2989 link_type_to_string
= {
2990 ARPHRD_NETROM
: 'ARPHRD_NETROM',
2991 ARPHRD_ETHER
: 'ARPHRD_ETHER',
2992 ARPHRD_EETHER
: 'ARPHRD_EETHER',
2993 ARPHRD_AX25
: 'ARPHRD_AX25',
2994 ARPHRD_PRONET
: 'ARPHRD_PRONET',
2995 ARPHRD_CHAOS
: 'ARPHRD_CHAOS',
2996 ARPHRD_IEEE802
: 'ARPHRD_IEEE802',
2997 ARPHRD_ARCNET
: 'ARPHRD_ARCNET',
2998 ARPHRD_APPLETLK
: 'ARPHRD_APPLETLK',
2999 ARPHRD_DLCI
: 'ARPHRD_DLCI',
3000 ARPHRD_ATM
: 'ARPHRD_ATM',
3001 ARPHRD_METRICOM
: 'ARPHRD_METRICOM',
3002 ARPHRD_IEEE1394
: 'ARPHRD_IEEE1394',
3003 ARPHRD_EUI64
: 'ARPHRD_EUI64',
3004 ARPHRD_INFINIBAND
: 'ARPHRD_INFINIBAND',
3005 ARPHRD_SLIP
: 'ARPHRD_SLIP',
3006 ARPHRD_CSLIP
: 'ARPHRD_CSLIP',
3007 ARPHRD_SLIP6
: 'ARPHRD_SLIP6',
3008 ARPHRD_CSLIP6
: 'ARPHRD_CSLIP6',
3009 ARPHRD_RSRVD
: 'ARPHRD_RSRVD',
3010 ARPHRD_ADAPT
: 'ARPHRD_ADAPT',
3011 ARPHRD_ROSE
: 'ARPHRD_ROSE',
3012 ARPHRD_X25
: 'ARPHRD_X25',
3013 ARPHRD_HWX25
: 'ARPHRD_HWX25',
3014 ARPHRD_CAN
: 'ARPHRD_CAN',
3015 ARPHRD_PPP
: 'ARPHRD_PPP',
3016 ARPHRD_CISCO
: 'ARPHRD_CISCO',
3017 ARPHRD_HDLC
: 'ARPHRD_HDLC',
3018 ARPHRD_LAPB
: 'ARPHRD_LAPB',
3019 ARPHRD_DDCMP
: 'ARPHRD_DDCMP',
3020 ARPHRD_RAWHDLC
: 'ARPHRD_RAWHDLC',
3021 ARPHRD_TUNNEL
: 'ARPHRD_TUNNEL',
3022 ARPHRD_TUNNEL6
: 'ARPHRD_TUNNEL6',
3023 ARPHRD_FRAD
: 'ARPHRD_FRAD',
3024 ARPHRD_SKIP
: 'ARPHRD_SKIP',
3025 ARPHRD_LOOPBACK
: 'ARPHRD_LOOPBACK',
3026 ARPHRD_LOCALTLK
: 'ARPHRD_LOCALTLK',
3027 ARPHRD_FDDI
: 'ARPHRD_FDDI',
3028 ARPHRD_BIF
: 'ARPHRD_BIF',
3029 ARPHRD_SIT
: 'ARPHRD_SIT',
3030 ARPHRD_IPDDP
: 'ARPHRD_IPDDP',
3031 ARPHRD_IPGRE
: 'ARPHRD_IPGRE',
3032 ARPHRD_PIMREG
: 'ARPHRD_PIMREG',
3033 ARPHRD_HIPPI
: 'ARPHRD_HIPPI',
3034 ARPHRD_ASH
: 'ARPHRD_ASH',
3035 ARPHRD_ECONET
: 'ARPHRD_ECONET',
3036 ARPHRD_IRDA
: 'ARPHRD_IRDA',
3037 ARPHRD_FCPP
: 'ARPHRD_FCPP',
3038 ARPHRD_FCAL
: 'ARPHRD_FCAL',
3039 ARPHRD_FCPL
: 'ARPHRD_FCPL',
3040 ARPHRD_FCFABRIC
: 'ARPHRD_FCFABRIC',
3041 ARPHRD_IEEE802_TR
: 'ARPHRD_IEEE802_TR',
3042 ARPHRD_IEEE80211
: 'ARPHRD_IEEE80211',
3043 ARPHRD_IEEE80211_PRISM
: 'ARPHRD_IEEE80211_PRISM',
3044 ARPHRD_IEEE80211_RADIOTAP
: 'ARPHRD_IEEE80211_RADIOTAP',
3045 ARPHRD_IEEE802154
: 'ARPHRD_IEEE802154',
3046 ARPHRD_PHONET
: 'ARPHRD_PHONET',
3047 ARPHRD_PHONET_PIPE
: 'ARPHRD_PHONET_PIPE',
3048 ARPHRD_CAIF
: 'ARPHRD_CAIF',
3049 ARPHRD_VOID
: 'ARPHRD_VOID',
3050 ARPHRD_NONE
: 'ARPHRD_NONE'
3053 # =========================================
3054 # IFLA_LINKINFO attributes
3055 # =========================================
3056 IFLA_INFO_UNSPEC
= 0
3059 IFLA_INFO_XSTATS
= 3
3060 IFLA_INFO_SLAVE_KIND
= 4
3061 IFLA_INFO_SLAVE_DATA
= 5
3064 ifla_info_to_string
= {
3065 IFLA_INFO_UNSPEC
: 'IFLA_INFO_UNSPEC',
3066 IFLA_INFO_KIND
: 'IFLA_INFO_KIND',
3067 IFLA_INFO_DATA
: 'IFLA_INFO_DATA',
3068 IFLA_INFO_XSTATS
: 'IFLA_INFO_XSTATS',
3069 IFLA_INFO_SLAVE_KIND
: 'IFLA_INFO_SLAVE_KIND',
3070 IFLA_INFO_SLAVE_DATA
: 'IFLA_INFO_SLAVE_DATA',
3071 IFLA_INFO_MAX
: 'IFLA_INFO_MAX'
3074 # =========================================
3075 # IFLA_INFO_DATA attributes for vlan
3076 # =========================================
3077 IFLA_VLAN_UNSPEC
= 0
3080 IFLA_VLAN_EGRESS_QOS
= 3
3081 IFLA_VLAN_INGRESS_QOS
= 4
3082 IFLA_VLAN_PROTOCOL
= 5
3084 ifla_vlan_to_string
= {
3085 IFLA_VLAN_UNSPEC
: 'IFLA_VLAN_UNSPEC',
3086 IFLA_VLAN_ID
: 'IFLA_VLAN_ID',
3087 IFLA_VLAN_FLAGS
: 'IFLA_VLAN_FLAGS',
3088 IFLA_VLAN_EGRESS_QOS
: 'IFLA_VLAN_EGRESS_QOS',
3089 IFLA_VLAN_INGRESS_QOS
: 'IFLA_VLAN_INGRESS_QOS',
3090 IFLA_VLAN_PROTOCOL
: 'IFLA_VLAN_PROTOCOL'
3093 ifla_vlan_protocol_dict
= {
3106 # =========================================
3107 # IFLA_INFO_DATA attributes for macvlan
3108 # =========================================
3109 IFLA_MACVLAN_UNSPEC
= 0
3110 IFLA_MACVLAN_MODE
= 1
3112 ifla_macvlan_to_string
= {
3113 IFLA_MACVLAN_UNSPEC
: 'IFLA_MACVLAN_UNSPEC',
3114 IFLA_MACVLAN_MODE
: 'IFLA_MACVLAN_MODE'
3118 MACVLAN_MODE_PRIVATE
= 1
3119 MACVLAN_MODE_VEPA
= 2
3120 MACVLAN_MODE_BRIDGE
= 3
3121 MACVLAN_MODE_PASSTHRU
= 4
3123 macvlan_mode_to_string
= {
3124 MACVLAN_MODE_PRIVATE
: 'MACVLAN_MODE_PRIVATE',
3125 MACVLAN_MODE_VEPA
: 'MACVLAN_MODE_VEPA',
3126 MACVLAN_MODE_BRIDGE
: 'MACVLAN_MODE_BRIDGE',
3127 MACVLAN_MODE_PASSTHRU
: 'MACVLAN_MODE_PASSTHRU'
3130 # =========================================
3131 # IFLA_INFO_DATA attributes for vxlan
3132 # =========================================
3133 IFLA_VXLAN_UNSPEC
= 0
3135 IFLA_VXLAN_GROUP
= 2
3137 IFLA_VXLAN_LOCAL
= 4
3140 IFLA_VXLAN_LEARNING
= 7
3141 IFLA_VXLAN_AGEING
= 8
3142 IFLA_VXLAN_LIMIT
= 9
3143 IFLA_VXLAN_PORT_RANGE
= 10
3144 IFLA_VXLAN_PROXY
= 11
3146 IFLA_VXLAN_L2MISS
= 13
3147 IFLA_VXLAN_L3MISS
= 14
3148 IFLA_VXLAN_PORT
= 15
3149 IFLA_VXLAN_GROUP6
= 16
3150 IFLA_VXLAN_LOCAL6
= 17
3151 IFLA_VXLAN_UDP_CSUM
= 18
3152 IFLA_VXLAN_UDP_ZERO_CSUM6_TX
= 19
3153 IFLA_VXLAN_UDP_ZERO_CSUM6_RX
= 20
3154 IFLA_VXLAN_REMCSUM_TX
= 21
3155 IFLA_VXLAN_REMCSUM_RX
= 22
3157 IFLA_VXLAN_REMCSUM_NOPARTIAL
= 24
3158 IFLA_VXLAN_COLLECT_METADATA
= 25
3159 IFLA_VXLAN_REPLICATION_NODE
= 253
3160 IFLA_VXLAN_REPLICATION_TYPE
= 254
3162 ifla_vxlan_to_string
= {
3163 IFLA_VXLAN_UNSPEC
: 'IFLA_VXLAN_UNSPEC',
3164 IFLA_VXLAN_ID
: 'IFLA_VXLAN_ID',
3165 IFLA_VXLAN_GROUP
: 'IFLA_VXLAN_GROUP',
3166 IFLA_VXLAN_LINK
: 'IFLA_VXLAN_LINK',
3167 IFLA_VXLAN_LOCAL
: 'IFLA_VXLAN_LOCAL',
3168 IFLA_VXLAN_TTL
: 'IFLA_VXLAN_TTL',
3169 IFLA_VXLAN_TOS
: 'IFLA_VXLAN_TOS',
3170 IFLA_VXLAN_LEARNING
: 'IFLA_VXLAN_LEARNING',
3171 IFLA_VXLAN_AGEING
: 'IFLA_VXLAN_AGEING',
3172 IFLA_VXLAN_LIMIT
: 'IFLA_VXLAN_LIMIT',
3173 IFLA_VXLAN_PORT_RANGE
: 'IFLA_VXLAN_PORT_RANGE',
3174 IFLA_VXLAN_PROXY
: 'IFLA_VXLAN_PROXY',
3175 IFLA_VXLAN_RSC
: 'IFLA_VXLAN_RSC',
3176 IFLA_VXLAN_L2MISS
: 'IFLA_VXLAN_L2MISS',
3177 IFLA_VXLAN_L3MISS
: 'IFLA_VXLAN_L3MISS',
3178 IFLA_VXLAN_PORT
: 'IFLA_VXLAN_PORT',
3179 IFLA_VXLAN_GROUP6
: 'IFLA_VXLAN_GROUP6',
3180 IFLA_VXLAN_LOCAL6
: 'IFLA_VXLAN_LOCAL6',
3181 IFLA_VXLAN_UDP_CSUM
: 'IFLA_VXLAN_UDP_CSUM',
3182 IFLA_VXLAN_UDP_ZERO_CSUM6_TX
: 'IFLA_VXLAN_UDP_ZERO_CSUM6_TX',
3183 IFLA_VXLAN_UDP_ZERO_CSUM6_RX
: 'IFLA_VXLAN_UDP_ZERO_CSUM6_RX',
3184 IFLA_VXLAN_REMCSUM_TX
: 'IFLA_VXLAN_REMCSUM_TX',
3185 IFLA_VXLAN_REMCSUM_RX
: 'IFLA_VXLAN_REMCSUM_RX',
3186 IFLA_VXLAN_GBP
: 'IFLA_VXLAN_GBP',
3187 IFLA_VXLAN_REMCSUM_NOPARTIAL
: 'IFLA_VXLAN_REMCSUM_NOPARTIAL',
3188 IFLA_VXLAN_COLLECT_METADATA
: 'IFLA_VXLAN_COLLECT_METADATA',
3189 IFLA_VXLAN_REPLICATION_NODE
: 'IFLA_VXLAN_REPLICATION_NODE',
3190 IFLA_VXLAN_REPLICATION_TYPE
: 'IFLA_VXLAN_REPLICATION_TYPE'
3193 # =========================================
3194 # IFLA_INFO_DATA attributes for bonds
3195 # =========================================
3196 IFLA_BOND_UNSPEC
= 0
3198 IFLA_BOND_ACTIVE_SLAVE
= 2
3199 IFLA_BOND_MIIMON
= 3
3200 IFLA_BOND_UPDELAY
= 4
3201 IFLA_BOND_DOWNDELAY
= 5
3202 IFLA_BOND_USE_CARRIER
= 6
3203 IFLA_BOND_ARP_INTERVAL
= 7
3204 IFLA_BOND_ARP_IP_TARGET
= 8
3205 IFLA_BOND_ARP_VALIDATE
= 9
3206 IFLA_BOND_ARP_ALL_TARGETS
= 10
3207 IFLA_BOND_PRIMARY
= 11
3208 IFLA_BOND_PRIMARY_RESELECT
= 12
3209 IFLA_BOND_FAIL_OVER_MAC
= 13
3210 IFLA_BOND_XMIT_HASH_POLICY
= 14
3211 IFLA_BOND_RESEND_IGMP
= 15
3212 IFLA_BOND_NUM_PEER_NOTIF
= 16
3213 IFLA_BOND_ALL_SLAVES_ACTIVE
= 17
3214 IFLA_BOND_MIN_LINKS
= 18
3215 IFLA_BOND_LP_INTERVAL
= 19
3216 IFLA_BOND_PACKETS_PER_SLAVE
= 20
3217 IFLA_BOND_AD_LACP_RATE
= 21
3218 IFLA_BOND_AD_SELECT
= 22
3219 IFLA_BOND_AD_INFO
= 23
3220 IFLA_BOND_AD_ACTOR_SYS_PRIO
= 24
3221 IFLA_BOND_AD_USER_PORT_KEY
= 25
3222 IFLA_BOND_AD_ACTOR_SYSTEM
= 26
3223 IFLA_BOND_AD_LACP_BYPASS
= 100
3225 ifla_bond_to_string
= {
3226 IFLA_BOND_UNSPEC
: 'IFLA_BOND_UNSPEC',
3227 IFLA_BOND_MODE
: 'IFLA_BOND_MODE',
3228 IFLA_BOND_ACTIVE_SLAVE
: 'IFLA_BOND_ACTIVE_SLAVE',
3229 IFLA_BOND_MIIMON
: 'IFLA_BOND_MIIMON',
3230 IFLA_BOND_UPDELAY
: 'IFLA_BOND_UPDELAY',
3231 IFLA_BOND_DOWNDELAY
: 'IFLA_BOND_DOWNDELAY',
3232 IFLA_BOND_USE_CARRIER
: 'IFLA_BOND_USE_CARRIER',
3233 IFLA_BOND_ARP_INTERVAL
: 'IFLA_BOND_ARP_INTERVAL',
3234 IFLA_BOND_ARP_IP_TARGET
: 'IFLA_BOND_ARP_IP_TARGET',
3235 IFLA_BOND_ARP_VALIDATE
: 'IFLA_BOND_ARP_VALIDATE',
3236 IFLA_BOND_ARP_ALL_TARGETS
: 'IFLA_BOND_ARP_ALL_TARGETS',
3237 IFLA_BOND_PRIMARY
: 'IFLA_BOND_PRIMARY',
3238 IFLA_BOND_PRIMARY_RESELECT
: 'IFLA_BOND_PRIMARY_RESELECT',
3239 IFLA_BOND_FAIL_OVER_MAC
: 'IFLA_BOND_FAIL_OVER_MAC',
3240 IFLA_BOND_XMIT_HASH_POLICY
: 'IFLA_BOND_XMIT_HASH_POLICY',
3241 IFLA_BOND_RESEND_IGMP
: 'IFLA_BOND_RESEND_IGMP',
3242 IFLA_BOND_NUM_PEER_NOTIF
: 'IFLA_BOND_NUM_PEER_NOTIF',
3243 IFLA_BOND_ALL_SLAVES_ACTIVE
: 'IFLA_BOND_ALL_SLAVES_ACTIVE',
3244 IFLA_BOND_MIN_LINKS
: 'IFLA_BOND_MIN_LINKS',
3245 IFLA_BOND_LP_INTERVAL
: 'IFLA_BOND_LP_INTERVAL',
3246 IFLA_BOND_PACKETS_PER_SLAVE
: 'IFLA_BOND_PACKETS_PER_SLAVE',
3247 IFLA_BOND_AD_LACP_RATE
: 'IFLA_BOND_AD_LACP_RATE',
3248 IFLA_BOND_AD_SELECT
: 'IFLA_BOND_AD_SELECT',
3249 IFLA_BOND_AD_INFO
: 'IFLA_BOND_AD_INFO',
3250 IFLA_BOND_AD_ACTOR_SYS_PRIO
: 'IFLA_BOND_AD_ACTOR_SYS_PRIO',
3251 IFLA_BOND_AD_USER_PORT_KEY
: 'IFLA_BOND_AD_USER_PORT_KEY',
3252 IFLA_BOND_AD_ACTOR_SYSTEM
: 'IFLA_BOND_AD_ACTOR_SYSTEM',
3253 IFLA_BOND_AD_LACP_BYPASS
: 'IFLA_BOND_AD_LACP_BYPASS'
3256 IFLA_BOND_AD_INFO_UNSPEC
= 0
3257 IFLA_BOND_AD_INFO_AGGREGATOR
= 1
3258 IFLA_BOND_AD_INFO_NUM_PORTS
= 2
3259 IFLA_BOND_AD_INFO_ACTOR_KEY
= 3
3260 IFLA_BOND_AD_INFO_PARTNER_KEY
= 4
3261 IFLA_BOND_AD_INFO_PARTNER_MAC
= 5
3263 ifla_bond_ad_to_string
= {
3264 IFLA_BOND_AD_INFO_UNSPEC
: 'IFLA_BOND_AD_INFO_UNSPEC',
3265 IFLA_BOND_AD_INFO_AGGREGATOR
: 'IFLA_BOND_AD_INFO_AGGREGATOR',
3266 IFLA_BOND_AD_INFO_NUM_PORTS
: 'IFLA_BOND_AD_INFO_NUM_PORTS',
3267 IFLA_BOND_AD_INFO_ACTOR_KEY
: 'IFLA_BOND_AD_INFO_ACTOR_KEY',
3268 IFLA_BOND_AD_INFO_PARTNER_KEY
: 'IFLA_BOND_AD_INFO_PARTNER_KEY',
3269 IFLA_BOND_AD_INFO_PARTNER_MAC
: 'IFLA_BOND_AD_INFO_PARTNER_MAC'
3272 ifla_bond_mode_tbl
= {
3296 ifla_bond_mode_pretty_tbl
= {
3306 ifla_bond_xmit_hash_policy_tbl
= {
3324 ifla_bond_xmit_hash_policy_pretty_tbl
= {
3332 # =========================================
3333 # IFLA_INFO_SLAVE_DATA attributes for bonds
3334 # =========================================
3335 IFLA_BOND_SLAVE_UNSPEC
= 0
3336 IFLA_BOND_SLAVE_STATE
= 1
3337 IFLA_BOND_SLAVE_MII_STATUS
= 2
3338 IFLA_BOND_SLAVE_LINK_FAILURE_COUNT
= 3
3339 IFLA_BOND_SLAVE_PERM_HWADDR
= 4
3340 IFLA_BOND_SLAVE_QUEUE_ID
= 5
3341 IFLA_BOND_SLAVE_AD_AGGREGATOR_ID
= 6
3342 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE
= 7
3343 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
= 8
3344 IFLA_BOND_SLAVE_CL_START
= 50
3345 IFLA_BOND_SLAVE_AD_RX_BYPASS
= IFLA_BOND_SLAVE_CL_START
3347 ifla_bond_slave_to_string
= {
3348 IFLA_BOND_SLAVE_UNSPEC
: 'IFLA_BOND_SLAVE_UNSPEC',
3349 IFLA_BOND_SLAVE_STATE
: 'IFLA_BOND_SLAVE_STATE',
3350 IFLA_BOND_SLAVE_MII_STATUS
: 'IFLA_BOND_SLAVE_MII_STATUS',
3351 IFLA_BOND_SLAVE_LINK_FAILURE_COUNT
: 'IFLA_BOND_SLAVE_LINK_FAILURE_COUNT',
3352 IFLA_BOND_SLAVE_PERM_HWADDR
: 'IFLA_BOND_SLAVE_PERM_HWADDR',
3353 IFLA_BOND_SLAVE_QUEUE_ID
: 'IFLA_BOND_SLAVE_QUEUE_ID',
3354 IFLA_BOND_SLAVE_AD_AGGREGATOR_ID
: 'IFLA_BOND_SLAVE_AD_AGGREGATOR_ID',
3355 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE
: 'IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE',
3356 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
: 'IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE',
3357 IFLA_BOND_SLAVE_CL_START
: 'IFLA_BOND_SLAVE_CL_START',
3358 IFLA_BOND_SLAVE_AD_RX_BYPASS
: 'IFLA_BOND_SLAVE_AD_RX_BYPASS'
3361 # =========================================
3362 # IFLA_PROTINFO attributes for bridge ports
3363 # =========================================
3364 IFLA_BRPORT_UNSPEC
= 0
3365 IFLA_BRPORT_STATE
= 1
3366 IFLA_BRPORT_PRIORITY
= 2
3367 IFLA_BRPORT_COST
= 3
3368 IFLA_BRPORT_MODE
= 4
3369 IFLA_BRPORT_GUARD
= 5
3370 IFLA_BRPORT_PROTECT
= 6
3371 IFLA_BRPORT_FAST_LEAVE
= 7
3372 IFLA_BRPORT_LEARNING
= 8
3373 IFLA_BRPORT_UNICAST_FLOOD
= 9
3374 IFLA_BRPORT_PROXYARP
= 10
3375 IFLA_BRPORT_LEARNING_SYNC
= 11
3376 IFLA_BRPORT_PROXYARP_WIFI
= 12
3377 IFLA_BRPORT_ROOT_ID
= 13
3378 IFLA_BRPORT_BRIDGE_ID
= 14
3379 IFLA_BRPORT_DESIGNATED_PORT
= 15
3380 IFLA_BRPORT_DESIGNATED_COST
= 16
3383 IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
= 19
3384 IFLA_BRPORT_CONFIG_PENDING
= 20
3385 IFLA_BRPORT_MESSAGE_AGE_TIMER
= 21
3386 IFLA_BRPORT_FORWARD_DELAY_TIMER
= 22
3387 IFLA_BRPORT_HOLD_TIMER
= 23
3388 IFLA_BRPORT_FLUSH
= 24
3389 IFLA_BRPORT_MULTICAST_ROUTER
= 25
3390 IFLA_BRPORT_PAD
= 26
3391 IFLA_BRPORT_MCAST_FLOOD
= 27
3392 IFLA_BRPORT_MCAST_TO_UCAST
= 28
3393 IFLA_BRPORT_VLAN_TUNNEL
= 29
3394 IFLA_BRPORT_BCAST_FLOOD
= 30
3395 IFLA_BRPORT_GROUP_FWD_MASK
= 31
3396 IFLA_BRPORT_ARP_SUPPRESS
= 32
3397 IFLA_BRPORT_PEER_LINK
= 150
3398 IFLA_BRPORT_DUAL_LINK
= 151
3399 IFLA_BRPORT_GROUP_FWD_MASKHI
= 153
3400 IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
= 154
3402 ifla_brport_to_string
= {
3403 IFLA_BRPORT_UNSPEC
: 'IFLA_BRPORT_UNSPEC',
3404 IFLA_BRPORT_STATE
: 'IFLA_BRPORT_STATE',
3405 IFLA_BRPORT_PRIORITY
: 'IFLA_BRPORT_PRIORITY',
3406 IFLA_BRPORT_COST
: 'IFLA_BRPORT_COST',
3407 IFLA_BRPORT_MODE
: 'IFLA_BRPORT_MODE',
3408 IFLA_BRPORT_GUARD
: 'IFLA_BRPORT_GUARD',
3409 IFLA_BRPORT_PROTECT
: 'IFLA_BRPORT_PROTECT',
3410 IFLA_BRPORT_FAST_LEAVE
: 'IFLA_BRPORT_FAST_LEAVE',
3411 IFLA_BRPORT_LEARNING
: 'IFLA_BRPORT_LEARNING',
3412 IFLA_BRPORT_UNICAST_FLOOD
: 'IFLA_BRPORT_UNICAST_FLOOD',
3413 IFLA_BRPORT_PROXYARP
: 'IFLA_BRPORT_PROXYARP',
3414 IFLA_BRPORT_LEARNING_SYNC
: 'IFLA_BRPORT_LEARNING_SYNC',
3415 IFLA_BRPORT_PROXYARP_WIFI
: 'IFLA_BRPORT_PROXYARP_WIFI',
3416 IFLA_BRPORT_ROOT_ID
: 'IFLA_BRPORT_ROOT_ID',
3417 IFLA_BRPORT_BRIDGE_ID
: 'IFLA_BRPORT_BRIDGE_ID',
3418 IFLA_BRPORT_DESIGNATED_PORT
: 'IFLA_BRPORT_DESIGNATED_PORT',
3419 IFLA_BRPORT_DESIGNATED_COST
: 'IFLA_BRPORT_DESIGNATED_COST',
3420 IFLA_BRPORT_ID
: 'IFLA_BRPORT_ID',
3421 IFLA_BRPORT_NO
: 'IFLA_BRPORT_NO',
3422 IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
: 'IFLA_BRPORT_TOPOLOGY_CHANGE_ACK',
3423 IFLA_BRPORT_CONFIG_PENDING
: 'IFLA_BRPORT_CONFIG_PENDING',
3424 IFLA_BRPORT_MESSAGE_AGE_TIMER
: 'IFLA_BRPORT_MESSAGE_AGE_TIMER',
3425 IFLA_BRPORT_FORWARD_DELAY_TIMER
: 'IFLA_BRPORT_FORWARD_DELAY_TIMER',
3426 IFLA_BRPORT_HOLD_TIMER
: 'IFLA_BRPORT_HOLD_TIMER',
3427 IFLA_BRPORT_FLUSH
: 'IFLA_BRPORT_FLUSH',
3428 IFLA_BRPORT_MULTICAST_ROUTER
: 'IFLA_BRPORT_MULTICAST_ROUTER',
3429 IFLA_BRPORT_PAD
: 'IFLA_BRPORT_PAD',
3430 IFLA_BRPORT_MCAST_FLOOD
: 'IFLA_BRPORT_MCAST_FLOOD',
3431 IFLA_BRPORT_MCAST_TO_UCAST
: 'IFLA_BRPORT_MCAST_TO_UCAST',
3432 IFLA_BRPORT_VLAN_TUNNEL
: 'IFLA_BRPORT_VLAN_TUNNEL',
3433 IFLA_BRPORT_BCAST_FLOOD
: 'IFLA_BRPORT_BCAST_FLOOD',
3434 IFLA_BRPORT_GROUP_FWD_MASK
: 'IFLA_BRPORT_GROUP_FWD_MASK',
3435 IFLA_BRPORT_PEER_LINK
: 'IFLA_BRPORT_PEER_LINK',
3436 IFLA_BRPORT_DUAL_LINK
: 'IFLA_BRPORT_DUAL_LINK',
3437 IFLA_BRPORT_ARP_SUPPRESS
: 'IFLA_BRPORT_ARP_SUPPRESS',
3438 IFLA_BRPORT_GROUP_FWD_MASKHI
: 'IFLA_BRPORT_GROUP_FWD_MASKHI',
3439 IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
: 'IFLA_BRPORT_DOWN_PEERLINK_REDIRECT'
3442 # Subtype attributes for IFLA_AF_SPEC
3443 IFLA_INET6_UNSPEC
= 0
3444 IFLA_INET6_FLAGS
= 1 # link flags
3445 IFLA_INET6_CONF
= 2 # sysctl parameters
3446 IFLA_INET6_STATS
= 3 # statistics
3447 IFLA_INET6_MCAST
= 4 # MC things. What of them?
3448 IFLA_INET6_CACHEINFO
= 5 # time values and max reasm size
3449 IFLA_INET6_ICMP6STATS
= 6 # statistics (icmpv6)
3450 IFLA_INET6_TOKEN
= 7 # device token
3451 IFLA_INET6_ADDR_GEN_MODE
= 8 # implicit address generator mode
3452 __IFLA_INET6_MAX
= 9
3454 ifla_inet6_af_spec_to_string
= {
3455 IFLA_INET6_UNSPEC
: 'IFLA_INET6_UNSPEC',
3456 IFLA_INET6_FLAGS
: 'IFLA_INET6_FLAGS',
3457 IFLA_INET6_CONF
: 'IFLA_INET6_CONF',
3458 IFLA_INET6_STATS
: 'IFLA_INET6_STATS',
3459 IFLA_INET6_MCAST
: 'IFLA_INET6_MCAST',
3460 IFLA_INET6_CACHEINFO
: 'IFLA_INET6_CACHEINFO',
3461 IFLA_INET6_ICMP6STATS
: 'IFLA_INET6_ICMP6STATS',
3462 IFLA_INET6_TOKEN
: 'IFLA_INET6_TOKEN',
3463 IFLA_INET6_ADDR_GEN_MODE
: 'IFLA_INET6_ADDR_GEN_MODE',
3466 # Subtype attrbutes AF_INET
3467 IFLA_INET_UNSPEC
= 0
3471 ifla_inet_af_spec_to_string
= {
3472 IFLA_INET_UNSPEC
: 'IFLA_INET_UNSPEC',
3473 IFLA_INET_CONF
: 'IFLA_INET_CONF',
3476 # BRIDGE IFLA_AF_SPEC attributes
3477 IFLA_BRIDGE_FLAGS
= 0
3478 IFLA_BRIDGE_MODE
= 1
3479 IFLA_BRIDGE_VLAN_INFO
= 2
3481 ifla_bridge_af_spec_to_string
= {
3482 IFLA_BRIDGE_FLAGS
: 'IFLA_BRIDGE_FLAGS',
3483 IFLA_BRIDGE_MODE
: 'IFLA_BRIDGE_MODE',
3484 IFLA_BRIDGE_VLAN_INFO
: 'IFLA_BRIDGE_VLAN_INFO'
3487 # BRIDGE_VLAN_INFO flags
3488 BRIDGE_VLAN_INFO_MASTER
= 1 << 0 # Operate on Bridge device as well
3489 BRIDGE_VLAN_INFO_PVID
= 1 << 1 # VLAN is PVID, ingress untagged
3490 BRIDGE_VLAN_INFO_UNTAGGED
= 1 << 2 # VLAN egresses untagged
3491 BRIDGE_VLAN_INFO_RANGE_BEGIN
= 1 << 3 # VLAN is start of vlan range
3492 BRIDGE_VLAN_INFO_RANGE_END
= 1 << 4 # VLAN is end of vlan range
3493 BRIDGE_VLAN_INFO_BRENTRY
= 1 << 5 # Global bridge VLAN entry
3495 bridge_vlan_to_string
= {
3496 BRIDGE_VLAN_INFO_MASTER
: 'BRIDGE_VLAN_INFO_MASTER',
3497 BRIDGE_VLAN_INFO_PVID
: 'BRIDGE_VLAN_INFO_PVID',
3498 BRIDGE_VLAN_INFO_UNTAGGED
: 'BRIDGE_VLAN_INFO_UNTAGGED',
3499 BRIDGE_VLAN_INFO_RANGE_BEGIN
: 'BRIDGE_VLAN_INFO_RANGE_BEGIN',
3500 BRIDGE_VLAN_INFO_RANGE_END
: 'BRIDGE_VLAN_INFO_RANGE_END',
3501 BRIDGE_VLAN_INFO_BRENTRY
: 'BRIDGE_VLAN_INFO_BRENTRY'
3505 BRIDGE_FLAGS_MASTER
= 1
3506 BRIDGE_FLAGS_SELF
= 2
3508 bridge_flags_to_string
= {
3509 BRIDGE_FLAGS_MASTER
: 'BRIDGE_FLAGS_MASTER',
3510 BRIDGE_FLAGS_SELF
: 'BRIDGE_FLAGS_SELF'
3513 # filters for IFLA_EXT_MASK
3514 RTEXT_FILTER_VF
= 1 << 0
3515 RTEXT_FILTER_BRVLAN
= 1 << 1
3516 RTEXT_FILTER_BRVLAN_COMPRESSED
= 1 << 2
3517 RTEXT_FILTER_SKIP_STATS
= 1 << 3
3520 RTEXT_FILTER_VF
: 'RTEXT_FILTER_VF',
3521 RTEXT_FILTER_BRVLAN
: 'RTEXT_FILTER_BRVLAN',
3522 RTEXT_FILTER_BRVLAN_COMPRESSED
: 'RTEXT_FILTER_BRVLAN_COMPRESSED',
3523 RTEXT_FILTER_SKIP_STATS
: 'RTEXT_FILTER_SKIP_STATS'
3527 IFLA_BR_FORWARD_DELAY
= 1
3528 IFLA_BR_HELLO_TIME
= 2
3530 IFLA_BR_AGEING_TIME
= 4
3531 IFLA_BR_STP_STATE
= 5
3532 IFLA_BR_PRIORITY
= 6
3533 IFLA_BR_VLAN_FILTERING
= 7
3534 IFLA_BR_VLAN_PROTOCOL
= 8
3535 IFLA_BR_GROUP_FWD_MASK
= 9
3536 IFLA_BR_ROOT_ID
= 10
3537 IFLA_BR_BRIDGE_ID
= 11
3538 IFLA_BR_ROOT_PORT
= 12
3539 IFLA_BR_ROOT_PATH_COST
= 13
3540 IFLA_BR_TOPOLOGY_CHANGE
= 14
3541 IFLA_BR_TOPOLOGY_CHANGE_DETECTED
= 15
3542 IFLA_BR_HELLO_TIMER
= 16
3543 IFLA_BR_TCN_TIMER
= 17
3544 IFLA_BR_TOPOLOGY_CHANGE_TIMER
= 18
3545 IFLA_BR_GC_TIMER
= 19
3546 IFLA_BR_GROUP_ADDR
= 20
3547 IFLA_BR_FDB_FLUSH
= 21
3548 IFLA_BR_MCAST_ROUTER
= 22
3549 IFLA_BR_MCAST_SNOOPING
= 23
3550 IFLA_BR_MCAST_QUERY_USE_IFADDR
= 24
3551 IFLA_BR_MCAST_QUERIER
= 25
3552 IFLA_BR_MCAST_HASH_ELASTICITY
= 26
3553 IFLA_BR_MCAST_HASH_MAX
= 27
3554 IFLA_BR_MCAST_LAST_MEMBER_CNT
= 28
3555 IFLA_BR_MCAST_STARTUP_QUERY_CNT
= 29
3556 IFLA_BR_MCAST_LAST_MEMBER_INTVL
= 30
3557 IFLA_BR_MCAST_MEMBERSHIP_INTVL
= 31
3558 IFLA_BR_MCAST_QUERIER_INTVL
= 32
3559 IFLA_BR_MCAST_QUERY_INTVL
= 33
3560 IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
= 34
3561 IFLA_BR_MCAST_STARTUP_QUERY_INTVL
= 35
3562 IFLA_BR_NF_CALL_IPTABLES
= 36
3563 IFLA_BR_NF_CALL_IP6TABLES
= 37
3564 IFLA_BR_NF_CALL_ARPTABLES
= 38
3565 IFLA_BR_VLAN_DEFAULT_PVID
= 39
3567 IFLA_BR_VLAN_STATS_ENABLED
= 41
3568 IFLA_BR_MCAST_STATS_ENABLED
= 42
3569 IFLA_BR_MCAST_IGMP_VERSION
= 43
3570 IFLA_BR_MCAST_MLD_VERSION
= 44
3572 ifla_br_to_string
= {
3573 IFLA_BR_UNSPEC
: 'IFLA_BR_UNSPEC',
3574 IFLA_BR_FORWARD_DELAY
: 'IFLA_BR_FORWARD_DELAY',
3575 IFLA_BR_HELLO_TIME
: 'IFLA_BR_HELLO_TIME',
3576 IFLA_BR_MAX_AGE
: 'IFLA_BR_MAX_AGE',
3577 IFLA_BR_AGEING_TIME
: 'IFLA_BR_AGEING_TIME',
3578 IFLA_BR_STP_STATE
: 'IFLA_BR_STP_STATE',
3579 IFLA_BR_PRIORITY
: 'IFLA_BR_PRIORITY',
3580 IFLA_BR_VLAN_FILTERING
: 'IFLA_BR_VLAN_FILTERING',
3581 IFLA_BR_VLAN_PROTOCOL
: 'IFLA_BR_VLAN_PROTOCOL',
3582 IFLA_BR_GROUP_FWD_MASK
: 'IFLA_BR_GROUP_FWD_MASK',
3583 IFLA_BR_ROOT_ID
: 'IFLA_BR_ROOT_ID',
3584 IFLA_BR_BRIDGE_ID
: 'IFLA_BR_BRIDGE_ID',
3585 IFLA_BR_ROOT_PORT
: 'IFLA_BR_ROOT_PORT',
3586 IFLA_BR_ROOT_PATH_COST
: 'IFLA_BR_ROOT_PATH_COST',
3587 IFLA_BR_TOPOLOGY_CHANGE
: 'IFLA_BR_TOPOLOGY_CHANGE',
3588 IFLA_BR_TOPOLOGY_CHANGE_DETECTED
: 'IFLA_BR_TOPOLOGY_CHANGE_DETECTED',
3589 IFLA_BR_HELLO_TIMER
: 'IFLA_BR_HELLO_TIMER',
3590 IFLA_BR_TCN_TIMER
: 'IFLA_BR_TCN_TIMER',
3591 IFLA_BR_TOPOLOGY_CHANGE_TIMER
: 'IFLA_BR_TOPOLOGY_CHANGE_TIMER',
3592 IFLA_BR_GC_TIMER
: 'IFLA_BR_GC_TIMER',
3593 IFLA_BR_GROUP_ADDR
: 'IFLA_BR_GROUP_ADDR',
3594 IFLA_BR_FDB_FLUSH
: 'IFLA_BR_FDB_FLUSH',
3595 IFLA_BR_MCAST_ROUTER
: 'IFLA_BR_MCAST_ROUTER',
3596 IFLA_BR_MCAST_SNOOPING
: 'IFLA_BR_MCAST_SNOOPING',
3597 IFLA_BR_MCAST_QUERY_USE_IFADDR
: 'IFLA_BR_MCAST_QUERY_USE_IFADDR',
3598 IFLA_BR_MCAST_QUERIER
: 'IFLA_BR_MCAST_QUERIER',
3599 IFLA_BR_MCAST_HASH_ELASTICITY
: 'IFLA_BR_MCAST_HASH_ELASTICITY',
3600 IFLA_BR_MCAST_HASH_MAX
: 'IFLA_BR_MCAST_HASH_MAX',
3601 IFLA_BR_MCAST_LAST_MEMBER_CNT
: 'IFLA_BR_MCAST_LAST_MEMBER_CNT',
3602 IFLA_BR_MCAST_STARTUP_QUERY_CNT
: 'IFLA_BR_MCAST_STARTUP_QUERY_CNT',
3603 IFLA_BR_MCAST_LAST_MEMBER_INTVL
: 'IFLA_BR_MCAST_LAST_MEMBER_INTVL',
3604 IFLA_BR_MCAST_MEMBERSHIP_INTVL
: 'IFLA_BR_MCAST_MEMBERSHIP_INTVL',
3605 IFLA_BR_MCAST_QUERIER_INTVL
: 'IFLA_BR_MCAST_QUERIER_INTVL',
3606 IFLA_BR_MCAST_QUERY_INTVL
: 'IFLA_BR_MCAST_QUERY_INTVL',
3607 IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
: 'IFLA_BR_MCAST_QUERY_RESPONSE_INTVL',
3608 IFLA_BR_MCAST_STARTUP_QUERY_INTVL
: 'IFLA_BR_MCAST_STARTUP_QUERY_INTVL',
3609 IFLA_BR_NF_CALL_IPTABLES
: 'IFLA_BR_NF_CALL_IPTABLES',
3610 IFLA_BR_NF_CALL_IP6TABLES
: 'IFLA_BR_NF_CALL_IP6TABLES',
3611 IFLA_BR_NF_CALL_ARPTABLES
: 'IFLA_BR_NF_CALL_ARPTABLES',
3612 IFLA_BR_VLAN_DEFAULT_PVID
: 'IFLA_BR_VLAN_DEFAULT_PVID',
3613 IFLA_BR_PAD
: 'IFLA_BR_PAD',
3614 IFLA_BR_VLAN_STATS_ENABLED
: 'IFLA_BR_VLAN_STATS_ENABLED',
3615 IFLA_BR_MCAST_STATS_ENABLED
: 'IFLA_BR_MCAST_STATS_ENABLED',
3616 IFLA_BR_MCAST_IGMP_VERSION
: 'IFLA_BR_MCAST_IGMP_VERSION',
3617 IFLA_BR_MCAST_MLD_VERSION
: 'IFLA_BR_MCAST_MLD_VERSION'
3620 # =========================================
3621 # IFLA_INFO_DATA attributes for vrfs
3622 # =========================================
3626 ifla_vrf_to_string
= {
3627 IFLA_VRF_UNSPEC
: 'IFLA_VRF_UNSPEC',
3628 IFLA_VRF_TABLE
: 'IFLA_VRF_TABLE'
3631 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
3632 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
3633 self
.PACK
= 'BxHiII'
3634 self
.LEN
= calcsize(self
.PACK
)
3636 def get_link_type_string(self
, index
):
3637 return self
.get_string(self
.link_type_to_string
, index
)
3639 def get_ifla_inet6_af_spec_to_string(self
, index
):
3640 return self
.get_string(self
.ifla_inet6_af_spec_to_string
, index
)
3642 def get_ifla_inet_af_spec_to_string(self
, index
):
3643 return self
.get_string(self
.ifla_inet_af_spec_to_string
, index
)
3645 def get_ifla_bridge_af_spec_to_string(self
, index
):
3646 return self
.get_string(self
.ifla_bridge_af_spec_to_string
, index
)
3648 def get_ifla_info_string(self
, index
):
3649 return self
.get_string(self
.ifla_info_to_string
, index
)
3651 def get_ifla_vlan_string(self
, index
):
3652 return self
.get_string(self
.ifla_vlan_to_string
, index
)
3654 def get_ifla_vxlan_string(self
, index
):
3655 return self
.get_string(self
.ifla_vxlan_to_string
, index
)
3657 def get_ifla_macvlan_string(self
, index
):
3658 return self
.get_string(self
.ifla_macvlan_to_string
, index
)
3660 def get_macvlan_mode_string(self
, index
):
3661 return self
.get_string(self
.macvlan_mode_to_string
, index
)
3663 def get_ifla_bond_string(self
, index
):
3664 return self
.get_string(self
.ifla_bond_to_string
, index
)
3666 def get_ifla_bond_ad_string(self
, index
):
3667 return self
.get_string(self
.ifla_bond_ad_to_string
, index
)
3669 def get_ifla_brport_string(self
, index
):
3670 return self
.get_string(self
.ifla_brport_to_string
, index
)
3672 def get_ifla_br_string(self
, index
):
3673 return self
.get_string(self
.ifla_br_to_string
, index
)
3675 def get_bridge_vlan_string(self
, index
):
3676 return self
.get_string(self
.bridge_vlan_to_string
, index
)
3678 def get_bridge_flags_string(self
, index
):
3679 return self
.get_string(self
.bridge_flags_to_string
, index
)
3681 def decode_service_header(self
):
3683 # Nothing to do if the message did not contain a service header
3684 if self
.length
== self
.header_LEN
:
3687 (self
.family
, self
.device_type
,
3690 self
.change_mask
) = \
3691 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
3694 color
= yellow
if self
.use_color
else None
3695 color_start
= "\033[%dm" % color
if color
else ""
3696 color_end
= "\033[0m" if color
else ""
3697 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
3699 for x
in range(0, self
.LEN
/4):
3700 if self
.line_number
== 5:
3701 extra
= "Family %s (%d), Device Type %s (%d - %s)" % \
3702 (zfilled_hex(self
.family
, 2), self
.family
,
3703 zfilled_hex(self
.device_type
, 4), self
.device_type
, self
.get_link_type_string(self
.device_type
))
3704 elif self
.line_number
== 6:
3705 extra
= "Interface Index %s (%d)" % (zfilled_hex(self
.ifindex
, 8), self
.ifindex
)
3706 elif self
.line_number
== 7:
3707 extra
= "Device Flags %s (%s)" % (zfilled_hex(self
.flags
, 8), self
.get_flags_string())
3708 elif self
.line_number
== 8:
3709 extra
= "Change Mask %s" % zfilled_hex(self
.change_mask
, 8)
3711 extra
= "Unexpected line number %d" % self
.line_number
3715 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
3716 self
.line_number
+= 1
3719 if self
.flags
& Link
.IFF_UP
:
3724 class Neighbor(NetlinkPacket
):
3729 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
3730 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3731 | Family | Reserved1 | Reserved2 |
3732 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3734 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3735 | State | Flags | Type |
3736 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3739 # Neighbor attributes
3740 # /usr/include/linux/neighbour.h
3741 NDA_UNSPEC
= 0x00 # Unknown type
3742 NDA_DST
= 0x01 # A neighbour cache network. layer destination address
3743 NDA_LLADDR
= 0x02 # A neighbor cache link layer address.
3744 NDA_CACHEINFO
= 0x03 # Cache statistics
3751 NDA_LINK_NETNSID
= 0x0A
3753 attribute_to_class
= {
3754 NDA_UNSPEC
: ('NDA_UNSPEC', AttributeGeneric
),
3755 NDA_DST
: ('NDA_DST', AttributeIPAddress
),
3756 NDA_LLADDR
: ('NDA_LLADDR', AttributeMACAddress
),
3757 NDA_CACHEINFO
: ('NDA_CACHEINFO', AttributeFourByteList
),
3758 NDA_PROBES
: ('NDA_PROBES', AttributeFourByteValue
),
3759 NDA_VLAN
: ('NDA_VLAN', AttributeTwoByteValue
),
3760 NDA_PORT
: ('NDA_PORT', AttributeGeneric
),
3761 NDA_VNI
: ('NDA_VNI', AttributeFourByteValue
),
3762 NDA_IFINDEX
: ('NDA_IFINDEX', AttributeFourByteValue
),
3763 NDA_MASTER
: ('NDA_MASTER', AttributeFourByteValue
),
3764 NDA_LINK_NETNSID
: ('NDA_LINK_NETNSID', AttributeGeneric
)
3768 # /usr/include/linux/neighbour.h
3772 NTF_PROXY
= 0x08 # A proxy ARP entry
3773 NTF_EXT_LEARNED
= 0x10 # neigh entry installed by an external APP
3774 NTF_ROUTER
= 0x80 # An IPv6 router
3777 NTF_USE
: 'NTF_USE',
3778 NTF_SELF
: 'NTF_SELF',
3779 NTF_MASTER
: 'NTF_MASTER',
3780 NTF_PROXY
: 'NTF_PROXY',
3781 NTF_EXT_LEARNED
: 'NTF_EXT_LEARNED',
3782 NTF_ROUTER
: 'NTF_ROUTER'
3786 # /usr/include/linux/neighbour.h
3788 NUD_INCOMPLETE
= 0x01 # Still attempting to resolve
3789 NUD_REACHABLE
= 0x02 # A confirmed working cache entry
3790 NUD_STALE
= 0x04 # an expired cache entry
3791 NUD_DELAY
= 0x08 # Neighbor no longer reachable. Traffic sent, waiting for confirmatio.
3792 NUD_PROBE
= 0x10 # A cache entry that is currently being re-solicited
3793 NUD_FAILED
= 0x20 # An invalid cache entry
3794 NUD_NOARP
= 0x40 # A device which does not do neighbor discovery(ARP)
3795 NUD_PERMANENT
= 0x80 # A static entry
3798 NUD_NONE
: 'NUD_NONE',
3799 NUD_INCOMPLETE
: 'NUD_INCOMPLETE',
3800 NUD_REACHABLE
: 'NUD_REACHABLE',
3801 NUD_STALE
: 'NUD_STALE',
3802 NUD_DELAY
: 'NUD_DELAY',
3803 NUD_PROBE
: 'NUD_PROBE',
3804 NUD_FAILED
: 'NUD_FAILED',
3805 NUD_NOARP
: 'NUD_NOARP',
3806 NUD_PERMANENT
: 'NUD_PERMANENT'
3809 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
3810 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
3811 self
.PACK
= 'BxxxiHBB'
3812 self
.LEN
= calcsize(self
.PACK
)
3814 def get_state_string(self
, index
):
3815 return self
.get_string(self
.state_to_string
, index
)
3817 def get_states_string(self
, states
):
3820 if states
& Neighbor
.NUD_INCOMPLETE
:
3821 for_string
.append('NUD_INCOMPLETE')
3823 if states
& Neighbor
.NUD_REACHABLE
:
3824 for_string
.append('NUD_REACHABLE')
3826 if states
& Neighbor
.NUD_STALE
:
3827 for_string
.append('NUD_STALE')
3829 if states
& Neighbor
.NUD_DELAY
:
3830 for_string
.append('NUD_DELAY')
3832 if states
& Neighbor
.NUD_PROBE
:
3833 for_string
.append('NUD_PROBE')
3835 if states
& Neighbor
.NUD_FAILED
:
3836 for_string
.append('NUD_FAILED')
3838 if states
& Neighbor
.NUD_NOARP
:
3839 for_string
.append('NUD_NOARP')
3841 if states
& Neighbor
.NUD_PERMANENT
:
3842 for_string
.append('NUD_PERMANENT')
3844 return ', '.join(for_string
)
3846 def get_flags_string(self
, flags
):
3849 if flags
& Neighbor
.NTF_USE
:
3850 for_string
.append('NTF_USE')
3852 if flags
& Neighbor
.NTF_SELF
:
3853 for_string
.append('NTF_SELF')
3855 if flags
& Neighbor
.NTF_MASTER
:
3856 for_string
.append('NTF_MASTER')
3858 if flags
& Neighbor
.NTF_PROXY
:
3859 for_string
.append('NTF_PROXY')
3861 if flags
& Neighbor
.NTF_ROUTER
:
3862 for_string
.append('NTF_ROUTER')
3864 return ', '.join(for_string
)
3866 def decode_service_header(self
):
3868 # Nothing to do if the message did not contain a service header
3869 if self
.length
== self
.header_LEN
:
3874 self
.state
, self
.flags
, self
.neighbor_type
) = \
3875 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
3878 color
= yellow
if self
.use_color
else None
3879 color_start
= "\033[%dm" % color
if color
else ""
3880 color_end
= "\033[0m" if color
else ""
3881 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
3883 for x
in range(0, self
.LEN
/4):
3884 if self
.line_number
== 5:
3885 extra
= "Family %s (%d)" % (zfilled_hex(self
.family
, 2), self
.family
)
3886 elif self
.line_number
== 6:
3887 extra
= "Interface Index %s (%d)" % (zfilled_hex(self
.ifindex
, 8), self
.ifindex
)
3888 elif self
.line_number
== 7:
3889 extra
= "State %s (%d) %s, Flags %s (%s) %s, Type %s (%d)" % \
3890 (zfilled_hex(self
.state
, 4), self
.state
, self
.get_states_string(self
.state
),
3891 zfilled_hex(self
.flags
, 2), self
.flags
, self
.get_flags_string(self
.flags
),
3892 zfilled_hex(self
.neighbor_type
, 4), self
.neighbor_type
)
3894 extra
= "Unexpected line number %d" % self
.line_number
3898 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
3899 self
.line_number
+= 1
3902 class Route(NetlinkPacket
):
3907 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
3908 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3909 | Family | Dest length | Src length | TOS |
3910 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3911 | Table ID | Protocol | Scope | Type |
3912 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3914 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3918 # /usr/include/linux/rtnetlink.h
3919 RTA_UNSPEC
= 0x00 # Ignored.
3920 RTA_DST
= 0x01 # Protocol address for route destination address.
3921 RTA_SRC
= 0x02 # Protocol address for route source address.
3922 RTA_IIF
= 0x03 # Input interface index.
3923 RTA_OIF
= 0x04 # Output interface index.
3924 RTA_GATEWAY
= 0x05 # Protocol address for the gateway of the route
3925 RTA_PRIORITY
= 0x06 # Priority of broker.
3926 RTA_PREFSRC
= 0x07 # Preferred source address in cases where more than one source address could be used.
3927 RTA_METRICS
= 0x08 # Route metrics attributed to route and associated protocols(e.g., RTT, initial TCP window, etc.).
3928 RTA_MULTIPATH
= 0x09 # Multipath route next hop's attributes.
3929 RTA_PROTOINFO
= 0x0A # Firewall based policy routing attribute.
3930 RTA_FLOW
= 0x0B # Route realm.
3931 RTA_CACHEINFO
= 0x0C # Cached route information.
3936 RTA_MFC_STATS
= 0x11
3940 RTA_ENCAP_TYPE
= 0x15
3943 attribute_to_class
= {
3944 RTA_UNSPEC
: ('RTA_UNSPEC', AttributeGeneric
),
3945 RTA_DST
: ('RTA_DST', AttributeIPAddress
),
3946 RTA_SRC
: ('RTA_SRC', AttributeIPAddress
),
3947 RTA_IIF
: ('RTA_IIF', AttributeFourByteValue
),
3948 RTA_OIF
: ('RTA_OIF', AttributeFourByteValue
),
3949 RTA_GATEWAY
: ('RTA_GATEWAY', AttributeIPAddress
),
3950 RTA_PRIORITY
: ('RTA_PRIORITY', AttributeFourByteValue
),
3951 RTA_PREFSRC
: ('RTA_PREFSRC', AttributeIPAddress
),
3952 RTA_METRICS
: ('RTA_METRICS', AttributeGeneric
),
3953 RTA_MULTIPATH
: ('RTA_MULTIPATH', AttributeRTA_MULTIPATH
),
3954 RTA_PROTOINFO
: ('RTA_PROTOINFO', AttributeGeneric
),
3955 RTA_FLOW
: ('RTA_FLOW', AttributeGeneric
),
3956 RTA_CACHEINFO
: ('RTA_CACHEINFO', AttributeGeneric
),
3957 RTA_SESSION
: ('RTA_SESSION', AttributeGeneric
),
3958 RTA_MP_ALGO
: ('RTA_MP_ALGO', AttributeGeneric
),
3959 RTA_TABLE
: ('RTA_TABLE', AttributeFourByteValue
),
3960 RTA_MARK
: ('RTA_MARK', AttributeGeneric
),
3961 RTA_MFC_STATS
: ('RTA_MFC_STATS', AttributeGeneric
),
3962 RTA_VIA
: ('RTA_VIA', AttributeGeneric
),
3963 RTA_NEWDST
: ('RTA_NEWDST', AttributeGeneric
),
3964 RTA_PREF
: ('RTA_PREF', AttributeGeneric
),
3965 RTA_ENCAP_TYPE
: ('RTA_ENCAP_TYPE', AttributeGeneric
),
3966 RTA_ENCAP
: ('RTA_ENCAP', AttributeGeneric
)
3970 # /usr/include/linux/rtnetlink.h
3971 RT_TABLE_UNSPEC
= 0x00 # An unspecified routing table
3972 RT_TABLE_COMPAT
= 0xFC
3973 RT_TABLE_DEFAULT
= 0xFD # The default table
3974 RT_TABLE_MAIN
= 0xFE # The main table
3975 RT_TABLE_LOCAL
= 0xFF # The local table
3978 RT_TABLE_UNSPEC
: 'RT_TABLE_UNSPEC',
3979 RT_TABLE_COMPAT
: 'RT_TABLE_COMPAT',
3980 RT_TABLE_DEFAULT
: 'RT_TABLE_DEFAULT',
3981 RT_TABLE_MAIN
: 'RT_TABLE_MAIN',
3982 RT_TABLE_LOCAL
: 'RT_TABLE_LOCAL'
3986 # /usr/include/linux/rtnetlink.h
3987 RT_SCOPE_UNIVERSE
= 0x00 # Global route
3988 RT_SCOPE_SITE
= 0xC8 # Interior route in the local autonomous system
3989 RT_SCOPE_LINK
= 0xFD # Route on this link
3990 RT_SCOPE_HOST
= 0xFE # Route on the local host
3991 RT_SCOPE_NOWHERE
= 0xFF # Destination does not exist
3994 RT_SCOPE_UNIVERSE
: 'RT_SCOPE_UNIVERSE',
3995 RT_SCOPE_SITE
: 'RT_SCOPE_SITE',
3996 RT_SCOPE_LINK
: 'RT_SCOPE_LINK',
3997 RT_SCOPE_HOST
: 'RT_SCOPE_HOST',
3998 RT_SCOPE_NOWHERE
: 'RT_SCOPE_NOWHERE'
4001 # Route scope to string
4002 # iproute2/lib/rt_names.c
4003 rtnl_rtscope_tab
= {
4004 RT_SCOPE_UNIVERSE
: 'global',
4005 RT_SCOPE_NOWHERE
: 'nowhere',
4006 RT_SCOPE_HOST
: 'host',
4007 RT_SCOPE_LINK
: 'link',
4008 RT_SCOPE_SITE
: 'site'
4012 # /usr/include/linux/rtnetlink.h
4013 RT_PROT_UNSPEC
= 0x00 # Identifies what/who added the route
4014 RT_PROT_REDIRECT
= 0x01 # By an ICMP redirect
4015 RT_PROT_KERNEL
= 0x02 # By the kernel
4016 RT_PROT_BOOT
= 0x03 # During bootup
4017 RT_PROT_STATIC
= 0x04 # By the administrator
4018 RT_PROT_GATED
= 0x08 # GateD
4019 RT_PROT_RA
= 0x09 # RDISC/ND router advertissements
4020 RT_PROT_MRT
= 0x0A # Merit MRT
4021 RT_PROT_ZEBRA
= 0x0B # ZEBRA
4022 RT_PROT_BIRD
= 0x0C # BIRD
4023 RT_PROT_DNROUTED
= 0x0D # DECnet routing daemon
4024 RT_PROT_XORP
= 0x0E # XORP
4025 RT_PROT_NTK
= 0x0F # Netsukuku
4026 RT_PROT_DHCP
= 0x10 # DHCP client
4027 RT_PROT_EXABGP
= 0x11 # Exa Networks ExaBGP
4030 RT_PROT_UNSPEC
: 'RT_PROT_UNSPEC',
4031 RT_PROT_REDIRECT
: 'RT_PROT_REDIRECT',
4032 RT_PROT_KERNEL
: 'RT_PROT_KERNEL',
4033 RT_PROT_BOOT
: 'RT_PROT_BOOT',
4034 RT_PROT_STATIC
: 'RT_PROT_STATIC',
4035 RT_PROT_GATED
: 'RT_PROT_GATED',
4036 RT_PROT_RA
: 'RT_PROT_RA',
4037 RT_PROT_MRT
: 'RT_PROT_MRT',
4038 RT_PROT_ZEBRA
: 'RT_PROT_ZEBRA',
4039 RT_PROT_BIRD
: 'RT_PROT_BIRD',
4040 RT_PROT_DNROUTED
: 'RT_PROT_DNROUTED',
4041 RT_PROT_XORP
: 'RT_PROT_XORP',
4042 RT_PROT_NTK
: 'RT_PROT_NTK',
4043 RT_PROT_DHCP
: 'RT_PROT_DHCP',
4044 RT_PROT_EXABGP
: 'RT_PROT_EXABGP'
4048 # /usr/include/linux/rtnetlink.h
4049 RTN_UNSPEC
= 0x00 # Unknown broker.
4050 RTN_UNICAST
= 0x01 # A gateway or direct broker.
4051 RTN_LOCAL
= 0x02 # A local interface broker.
4052 RTN_BROADCAST
= 0x03 # A local broadcast route(sent as a broadcast).
4053 RTN_ANYCAST
= 0x04 # An anycast broker.
4054 RTN_MULTICAST
= 0x05 # A multicast broker.
4055 RTN_BLACKHOLE
= 0x06 # A silent packet dropping broker.
4056 RTN_UNREACHABLE
= 0x07 # An unreachable destination. Packets dropped and
4057 # host unreachable ICMPs are sent to the originator.
4058 RTN_PROHIBIT
= 0x08 # A packet rejection broker. Packets are dropped and
4059 # communication prohibited ICMPs are sent to the originator.
4060 RTN_THROW
= 0x09 # When used with policy routing, continue routing lookup
4061 # in another table. Under normal routing, packets are
4062 # dropped and net unreachable ICMPs are sent to the originator.
4063 RTN_NAT
= 0x0A # A network address translation rule.
4064 RTN_XRESOLVE
= 0x0B # Refer to an external resolver(not implemented).
4066 rt_type_to_string
= {
4067 RTN_UNSPEC
: 'RTN_UNSPEC',
4068 RTN_UNICAST
: 'RTN_UNICAST',
4069 RTN_LOCAL
: 'RTN_LOCAL',
4070 RTN_BROADCAST
: 'RTN_BROADCAST',
4071 RTN_ANYCAST
: 'RTN_ANYCAST',
4072 RTN_MULTICAST
: 'RTN_MULTICAST',
4073 RTN_BLACKHOLE
: 'RTN_BLACKHOLE',
4074 RTN_UNREACHABLE
: 'RTN_UNREACHABLE',
4075 RTN_PROHIBIT
: 'RTN_PROHIBIT',
4076 RTN_THROW
: 'RTN_THROW',
4077 RTN_NAT
: 'RTN_NAT',
4078 RTN_XRESOLVE
: 'RTN_XRESOLVE'
4082 # /usr/include/linux/rtnetlink.h
4083 RTM_F_NOTIFY
= 0x100 # If the route changes, notify the user
4084 RTM_F_CLONED
= 0x200 # Route is cloned from another route
4085 RTM_F_EQUALIZE
= 0x400 # Allow randomization of next hop path in multi-path routing(currently not implemented)
4086 RTM_F_PREFIX
= 0x800 # Prefix Address
4089 RTM_F_NOTIFY
: 'RTM_F_NOTIFY',
4090 RTM_F_CLONED
: 'RTM_F_CLONED',
4091 RTM_F_EQUALIZE
: 'RTM_F_EQUALIZE',
4092 RTM_F_PREFIX
: 'RTM_F_PREFIX'
4095 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
4096 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
4097 self
.PACK
= '=8BI' # or is it 8Bi ?
4098 self
.LEN
= calcsize(self
.PACK
)
4100 def get_prefix_string(self
):
4101 dst
= self
.get_attribute_value(self
.RTA_DST
)
4104 return "%s/%d" % (dst
, self
.src_len
)
4106 if self
.family
== AF_INET
:
4108 elif self
.family
== AF_INET6
:
4111 def get_protocol_string(self
, index
=None):
4113 index
= self
.protocol
4114 return self
.get_string(self
.prot_to_string
, index
)
4116 def get_rt_type_string(self
, index
=None):
4118 index
= self
.route_type
4119 return self
.get_string(self
.rt_type_to_string
, index
)
4121 def get_scope_string(self
, index
=None):
4124 return self
.get_string(self
.scope_to_string
, index
)
4126 def get_table_id_string(self
, index
=None):
4128 index
= self
.table_id
4129 return self
.get_string(self
.table_to_string
, index
)
4131 def _get_ifname_from_index(self
, ifindex
, ifname_by_index
):
4133 ifname
= ifname_by_index
.get(ifindex
)
4136 ifname
= str(ifindex
)
4142 def get_nexthops(self
, ifname_by_index
={}):
4143 nexthop
= self
.get_attribute_value(self
.RTA_GATEWAY
)
4144 multipath
= self
.get_attribute_value(self
.RTA_MULTIPATH
)
4148 rta_oif
= self
.get_attribute_value(self
.RTA_OIF
)
4149 ifname
= self
._get
_ifname
_from
_index
(rta_oif
, ifname_by_index
)
4150 nexthops
.append((nexthop
, ifname
))
4153 for (nexthop
, rtnh_ifindex
, rtnh_flags
, rtnh_hops
) in multipath
:
4154 ifname
= self
._get
_ifname
_from
_index
(rtnh_ifindex
, ifname_by_index
)
4155 nexthops
.append((nexthop
, ifname
))
4159 def get_nexthops_string(self
, ifname_by_index
={}):
4162 for (nexthop
, ifname
) in self
.get_nexthops(ifname_by_index
):
4163 output
.append(" via %s on %s" % (nexthop
, ifname
))
4165 return ",".join(output
)
4167 def decode_service_header(self
):
4169 # Nothing to do if the message did not contain a service header
4170 if self
.length
== self
.header_LEN
:
4173 (self
.family
, self
.src_len
, self
.dst_len
, self
.tos
,
4174 self
.table_id
, self
.protocol
, self
.scope
, self
.route_type
,
4176 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
4179 color
= yellow
if self
.use_color
else None
4180 color_start
= "\033[%dm" % color
if color
else ""
4181 color_end
= "\033[0m" if color
else ""
4182 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
4184 for x
in range(0, self
.LEN
/4):
4185 if self
.line_number
== 5:
4186 extra
= "Family %s (%d), Source Length %s (%d), Destination Length %s (%d), TOS %s (%d)" % \
4187 (zfilled_hex(self
.family
, 2), self
.family
,
4188 zfilled_hex(self
.src_len
, 2), self
.src_len
,
4189 zfilled_hex(self
.dst_len
, 2), self
.dst_len
,
4190 zfilled_hex(self
.tos
, 2), self
.tos
)
4191 elif self
.line_number
== 6:
4192 extra
= "Table ID %s (%d - %s), Protocol %s (%d - %s), Scope %s (%d - %s), Type %s (%d - %s)" % \
4193 (zfilled_hex(self
.table_id
, 2), self
.table_id
, self
.get_table_id_string(),
4194 zfilled_hex(self
.protocol
, 2), self
.protocol
, self
.get_protocol_string(),
4195 zfilled_hex(self
.scope
, 2), self
.scope
, self
.get_scope_string(),
4196 zfilled_hex(self
.route_type
, 2), self
.route_type
, self
.get_rt_type_string())
4197 elif self
.line_number
== 7:
4198 extra
= "Flags %s" % zfilled_hex(self
.flags
, 8)
4200 extra
= "Unexpected line number %d" % self
.line_number
4204 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
4205 self
.line_number
+= 1
4207 class Done(NetlinkPacket
):
4213 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
4214 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4216 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4219 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
4220 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
4222 self
.LEN
= calcsize(self
.PACK
)
4224 def decode_service_header(self
):
4225 foo
= unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
4228 color
= yellow
if self
.use_color
else None
4229 color_start
= "\033[%dm" % color
if color
else ""
4230 color_end
= "\033[0m" if color
else ""
4231 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
4233 for x
in range(0, self
.LEN
/4):
4237 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
4238 self
.line_number
+= 1