1 # Copyright (c) 2009-2013, Exa Networks Limited
2 # Copyright (c) 2009-2013, Thomas Mangin
3 # Copyright (c) 2015-2017 Cumulus Networks, Inc.
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are met:
9 # Redistributions of source code must retain the above copyright notice, this
10 # list of conditions and the following disclaimer.
12 # Redistributions in binary form must reproduce the above copyright notice,
13 # this list of conditions and the following disclaimer in the documentation
14 # and/or other materials provided with the distribution.
16 # The names of the Exa Networks Limited, Cumulus Networks, Inc. nor the names
17 # of its contributors may be used to endorse or promote products derived from
18 # this software without specific prior written permission.
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
26 # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 from ipaddr
import IPv4Address
, IPv6Address
, IPAddress
34 from binascii
import hexlify
35 from pprint
import pformat
36 from socket
import AF_UNSPEC
, AF_INET
, AF_INET6
, AF_BRIDGE
, htons
37 from string
import printable
38 from struct
import pack
, unpack
, calcsize
40 log
= logging
.getLogger(__name__
)
41 SYSLOG_EXTRA_DEBUG
= 5
44 # Interface name buffer size #define IFNAMSIZ 16 (kernel source)
45 IF_NAME_SIZE
= 15 # 15 because python doesn't have \0
47 # Netlink message types
53 RTM_NEWLINK
= 0x10 # Create a new network interface
54 RTM_DELLINK
= 0x11 # Destroy a network interface
55 RTM_GETLINK
= 0x12 # Retrieve information about a network interface(ifinfomsg)
77 # Netlink message flags
78 NLM_F_REQUEST
= 0x01 # It is query message.
79 NLM_F_MULTI
= 0x02 # Multipart message, terminated by NLMSG_DONE
80 NLM_F_ACK
= 0x04 # Reply with ack, with zero or error code
81 NLM_F_ECHO
= 0x08 # Echo this query
83 # Modifiers to GET query
84 NLM_F_ROOT
= 0x100 # specify tree root
85 NLM_F_MATCH
= 0x200 # return all matching
86 NLM_F_DUMP
= NLM_F_ROOT | NLM_F_MATCH
87 NLM_F_ATOMIC
= 0x400 # atomic GET
89 # Modifiers to NEW query
90 NLM_F_REPLACE
= 0x100 # Override existing
91 NLM_F_EXCL
= 0x200 # Do not touch, if it exists
92 NLM_F_CREATE
= 0x400 # Create, if it does not exist
93 NLM_F_APPEND
= 0x800 # Add to end of list
96 NLA_F_NET_BYTEORDER
= 0x4000
97 NLA_TYPE_MASK
= ~
(NLA_F_NESTED | NLA_F_NET_BYTEORDER
)
104 RTMGRP_IPV4_IFADDR
= 0x10
105 RTMGRP_IPV4_MROUTE
= 0x20
106 RTMGRP_IPV4_ROUTE
= 0x40
107 RTMGRP_IPV4_RULE
= 0x80
108 RTMGRP_IPV6_IFADDR
= 0x100
109 RTMGRP_IPV6_MROUTE
= 0x200
110 RTMGRP_IPV6_ROUTE
= 0x400
111 RTMGRP_IPV6_IFINFO
= 0x800
112 RTMGRP_DECnet_IFADDR
= 0x1000
113 RTMGRP_DECnet_ROUTE
= 0x4000
114 RTMGRP_IPV6_PREFIX
= 0x20000
116 RTMGRP_ALL
= (RTMGRP_LINK | RTMGRP_NOTIFY | RTMGRP_NEIGH | RTMGRP_TC |
117 RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_MROUTE | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_RULE |
118 RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_MROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFINFO |
119 RTMGRP_DECnet_IFADDR | RTMGRP_DECnet_ROUTE |
129 for family
in [attr
for attr
in dir(socket
) if attr
.startswith('AF_')]:
130 AF_FAMILY
[getattr(socket
, family
)] = family
132 AF_FAMILY
[AF_MPLS
] = 'AF_MPLS'
135 def get_family_str(family
):
136 return AF_FAMILY
.get(family
, 'UNKNOWN')
144 value_to_bool_dict
= {
162 def set_log_level(level
):
166 def zfilled_hex(value
, digits
):
167 return '0x' + hex(value
)[2:].zfill(digits
)
170 def remove_trailing_null(line
):
172 Remove the last character if it is a NULL...having that NULL
173 causes python to print a garbage character
176 if ord(line
[-1]) == 0:
182 def mac_int_to_str(mac_int
):
184 Return an integer in MAC string format
187 # [2:] to remove the leading 0x, then fill out to 12 zeroes, then uppercase
188 all_caps
= hex(int(mac_int
))[2:].zfill(12).upper()
190 if all_caps
[-1] == 'L':
191 all_caps
= all_caps
[:-1]
192 all_caps
= all_caps
.zfill(12).upper()
194 return "%s.%s.%s" % (all_caps
[0:4], all_caps
[4:8], all_caps
[8:12])
197 def data_to_color_text(line_number
, color
, data
, extra
=''):
198 (c1
, c2
, c3
, c4
) = unpack('BBBB', data
[0:4])
201 for c
in (c1
, c2
, c3
, c4
):
204 if char_c
in printable
[:-5]:
205 in_ascii
.append(char_c
)
210 return ' %2d: \033[%dm0x%02x%02x%02x%02x\033[0m %s %s' % (line_number
, color
, c1
, c2
, c3
, c4
, ''.join(in_ascii
), extra
)
212 return ' %2d: 0x%02x%02x%02x%02x %s %s' % (line_number
, c1
, c2
, c3
, c4
, ''.join(in_ascii
), extra
)
215 def padded_length(length
):
216 return int((length
+ 3) / 4) * 4
219 class Attribute(object):
221 def __init__(self
, atype
, string
, logger
):
224 self
.HEADER_PACK
= '=HH'
225 self
.HEADER_LEN
= calcsize(self
.HEADER_PACK
)
230 self
.net_byteorder
= False
236 def set_value(self
, value
):
239 def set_nested(self
, nested
):
242 def set_net_byteorder(self
, net_byteorder
):
243 self
.net_byteorder
= net_byteorder
245 def pad_bytes_needed(self
, length
):
247 Return the number of bytes that should be added to align on a 4-byte boundry
249 remainder
= length
% 4
256 def pad(self
, length
, raw
):
257 pad
= self
.pad_bytes_needed(length
)
267 raise Exception('Please define an encode() method in your child attribute class, or do not use AttributeGeneric')
269 length
= self
.HEADER_LEN
+ self
.LEN
270 attr_type_with_flags
= self
.atype
273 attr_type_with_flags
= attr_type_with_flags | NLA_F_NESTED
275 if self
.net_byteorder
:
276 attr_type_with_flags
= attr_type_with_flags | NLA_F_NET_BYTEORDER
278 raw
= pack(self
.HEADER_PACK
, length
, attr_type_with_flags
) + pack(self
.PACK
, self
.value
)
279 raw
= self
.pad(length
, raw
)
282 def decode_length_type(self
, data
):
284 The first two bytes of an attribute are the length, the next two bytes are the type
287 prev_atype
= self
.atype
288 (data1
, data2
) = unpack(self
.HEADER_PACK
, data
[:self
.HEADER_LEN
])
289 self
.length
= int(data1
)
290 self
.atype
= int(data2
)
291 self
.attr_end
= padded_length(self
.length
)
293 self
.nested
= True if self
.atype
& NLA_F_NESTED
else False
294 self
.net_byteorder
= True if self
.atype
& NLA_F_NET_BYTEORDER
else False
295 self
.atype
= self
.atype
& NLA_TYPE_MASK
297 # Should never happen
298 assert self
.atype
== prev_atype
, "This object changes attribute type from %d to %d, this is bad" % (prev_atype
, self
.atype
)
300 def dump_first_line(self
, dump_buffer
, line_number
, color
):
302 Add the "Length....Type..." line to the dump buffer
304 if self
.attr_end
== self
.length
:
307 padded_to
= ' padded to %d, ' % self
.attr_end
309 extra
= 'Length %s (%d)%sType %s%s%s (%d) %s' % \
310 (zfilled_hex(self
.length
, 4), self
.length
,
312 zfilled_hex(self
.atype
, 4),
313 " (NLA_F_NESTED set)" if self
.nested
else "",
314 " (NLA_F_NET_BYTEORDER set)" if self
.net_byteorder
else "",
318 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[0:4], extra
))
319 return line_number
+ 1
321 def dump_lines(self
, dump_buffer
, line_number
, color
):
322 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
324 for x
in xrange(1, self
.attr_end
/4):
327 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], ''))
332 def get_pretty_value(self
, obj
=None):
333 if obj
and callable(obj
):
334 return obj(self
.value
)
338 class AttributeFourByteList(Attribute
):
340 def __init__(self
, atype
, string
, family
, logger
):
341 Attribute
.__init
__(self
, atype
, string
, logger
)
343 def decode(self
, parent_msg
, data
):
344 self
.decode_length_type(data
)
345 wordcount
= (self
.attr_end
- 4)/4
346 self
.PACK
= '=%dL' % wordcount
347 self
.LEN
= calcsize(self
.PACK
)
350 self
.value
= unpack(self
.PACK
, self
.data
[4:])
352 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
355 def dump_lines(self
, dump_buffer
, line_number
, color
):
356 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
358 for val
in self
.value
:
359 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4*idx
:4*(idx
+1)], val
))
365 class AttributeFourByteValue(Attribute
):
367 def __init__(self
, atype
, string
, family
, logger
):
368 Attribute
.__init
__(self
, atype
, string
, logger
)
370 self
.LEN
= calcsize(self
.PACK
)
372 def decode(self
, parent_msg
, data
):
373 self
.decode_length_type(data
)
374 assert self
.attr_end
== 8, "Attribute length for %s must be 8, it is %d" % (self
, self
.attr_end
)
377 self
.value
= int(unpack(self
.PACK
, self
.data
[4:])[0])
379 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
382 def dump_lines(self
, dump_buffer
, line_number
, color
):
383 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
384 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
385 return line_number
+ 1
388 class AttributeTwoByteValue(Attribute
):
390 def __init__(self
, atype
, string
, family
, logger
):
391 Attribute
.__init
__(self
, atype
, string
, logger
)
393 self
.LEN
= calcsize(self
.PACK
)
395 def decode(self
, parent_msg
, data
):
396 self
.decode_length_type(data
)
397 assert self
.attr_end
== 8, "Attribute length for %s must be 8, it is %d" % (self
, self
.attr_end
)
400 self
.value
= int(unpack(self
.PACK
, self
.data
[4:8])[0])
402 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:6])))
406 length
= self
.HEADER_LEN
+ self
.LEN
407 raw
= pack(self
.HEADER_PACK
, length
-2, self
.atype
) + pack(self
.PACK
, self
.value
)
408 raw
= self
.pad(length
, raw
)
411 def dump_lines(self
, dump_buffer
, line_number
, color
):
412 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
413 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
414 return line_number
+ 1
417 class AttributeString(Attribute
):
419 def __init__(self
, atype
, string
, family
, logger
):
420 Attribute
.__init
__(self
, atype
, string
, logger
)
425 # some interface names come from JSON as unicode strings
426 # and cannot be packed as is so we must convert them to strings
427 if isinstance(self
.value
, unicode):
428 self
.value
= str(self
.value
)
429 self
.PACK
= '%ds' % len(self
.value
)
430 self
.LEN
= calcsize(self
.PACK
)
432 length
= self
.HEADER_LEN
+ self
.LEN
433 raw
= pack(self
.HEADER_PACK
, length
, self
.atype
) + pack(self
.PACK
, self
.value
)
434 raw
= self
.pad(length
, raw
)
437 def decode(self
, parent_msg
, data
):
438 self
.decode_length_type(data
)
439 self
.PACK
= '%ds' % (self
.length
- 4)
440 self
.LEN
= calcsize(self
.PACK
)
443 self
.value
= remove_trailing_null(unpack(self
.PACK
, self
.data
[4:self
.length
])[0])
445 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:self
.length
])))
449 class AttributeStringInterfaceName(AttributeString
):
451 def __init__(self
, atype
, string
, family
, logger
):
452 AttributeString
.__init
__(self
, atype
, string
, family
, logger
)
454 def set_value(self
, value
):
455 if value
and len(value
) > IF_NAME_SIZE
:
456 raise Exception('interface name exceeds max length of %d' % IF_NAME_SIZE
)
460 class AttributeIPAddress(Attribute
):
462 def __init__(self
, atype
, string
, family
, logger
):
463 Attribute
.__init
__(self
, atype
, string
, logger
)
464 self
.value_int
= None
465 self
.value_int_str
= None
468 if self
.family
== AF_INET
:
471 elif self
.family
== AF_INET6
:
474 elif self
.family
== AF_BRIDGE
:
478 raise Exception("%s is not a supported address family" % self
.family
)
480 self
.LEN
= calcsize(self
.PACK
)
482 def set_value(self
, value
):
486 self
.value
= IPAddress(value
)
488 def decode(self
, parent_msg
, data
):
489 self
.decode_length_type(data
)
492 if self
.family
== AF_INET
:
493 self
.value
= IPv4Address(unpack(self
.PACK
, self
.data
[4:])[0])
495 elif self
.family
== AF_INET6
:
496 (data1
, data2
) = unpack(self
.PACK
, self
.data
[4:])
497 self
.value
= IPv6Address(data1
<< 64 | data2
)
499 elif self
.family
== AF_BRIDGE
:
500 self
.value
= IPv4Address(unpack(self
.PACK
, self
.data
[4:])[0])
502 self
.value_int
= int(self
.value
)
503 self
.value_int_str
= str(self
.value_int
)
507 self
.value_int
= None
508 self
.value_int_str
= None
509 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
513 length
= self
.HEADER_LEN
+ self
.LEN
515 if self
.family
not in [AF_INET
, AF_INET6
, AF_BRIDGE
]:
516 raise Exception("%s is not a supported address family" % self
.family
)
518 raw
= pack(self
.HEADER_PACK
, length
, self
.atype
) + self
.value
.packed
519 raw
= self
.pad(length
, raw
)
522 def dump_lines(self
, dump_buffer
, line_number
, color
):
523 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
525 if self
.family
== AF_INET
:
526 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
529 elif self
.family
== AF_INET6
:
531 for x
in xrange(1, self
.attr_end
/4):
534 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], self
.value
))
537 elif self
.family
== AF_BRIDGE
:
538 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
544 class AttributeMACAddress(Attribute
):
546 def __init__(self
, atype
, string
, family
, logger
):
547 Attribute
.__init
__(self
, atype
, string
, logger
)
549 self
.LEN
= calcsize(self
.PACK
)
551 def decode(self
, parent_msg
, data
):
552 self
.decode_length_type(data
)
554 # IFLA_ADDRESS and IFLA_BROADCAST attributes for all interfaces has been a
555 # 6-byte MAC address. But the GRE interface uses a 4-byte IP address and
556 # GREv6 uses a 16-byte IPv6 address for this attribute.
558 # GRE interface uses a 4-byte IP address for this attribute
560 self
.value
= IPv4Address(unpack('>L', self
.data
[4:])[0])
561 self
.value_int
= int(self
.value
)
562 self
.value_int_str
= str(self
.value_int
)
564 elif self
.length
== 10:
565 (data1
, data2
) = unpack(self
.PACK
, self
.data
[4:])
566 self
.value
= mac_int_to_str(data1
<< 16 | data2
)
567 # GREv6 interface uses a 16-byte IP address for this attribute
568 elif self
.length
== 20:
569 self
.value
= IPv6Address(unpack('>L', self
.data
[16:])[0])
570 self
.value_int
= int(self
.value
)
571 self
.value_int_str
= str(self
.value_int
)
573 raise Exception("Length of MACAddress attribute not supported: %d" % self
.length
)
576 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
580 length
= self
.HEADER_LEN
+ self
.LEN
581 mac_raw
= int(self
.value
.replace('.', '').replace(':', ''), 16)
582 raw
= pack(self
.HEADER_PACK
, length
-2, self
.atype
) + pack(self
.PACK
, mac_raw
>> 16, mac_raw
& 0x0000FFFF)
583 raw
= self
.pad(length
, raw
)
586 def dump_lines(self
, dump_buffer
, line_number
, color
):
587 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
588 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
590 if len(self
.data
) >= 12:
591 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[8:12]))
596 class AttributeMplsLabel(Attribute
):
598 def __init__(self
, atype
, string
, family
, logger
):
599 Attribute
.__init
__(self
, atype
, string
, logger
)
600 self
.value_int
= None
601 self
.value_int_str
= None
605 def decode(self
, parent_msg
, data
):
606 self
.decode_length_type(data
)
609 (label_high
, label_low_tc_s
, self
.ttl
) = unpack(self
.PACK
, self
.data
[4:])
610 self
.s_bit
= label_low_tc_s
& 0x1
611 self
.traffic_class
= ((label_low_tc_s
& 0xf) >> 1)
612 self
.label
= (label_high
<< 4) |
(label_low_tc_s
>> 4)
613 self
.value
= self
.label
614 self
.value_int
= self
.value
615 self
.value_int_str
= str(self
.value_int
)
619 self
.value_int
= None
620 self
.value_int_str
= None
621 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
624 def dump_lines(self
, dump_buffer
, line_number
, color
):
625 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
626 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8],
627 'label %s, TC %s, bottom-of-stack %s, TTL %d' %
628 (self
.label
, self
.traffic_class
, self
.s_bit
, self
.ttl
)))
634 class AttributeGeneric(Attribute
):
636 def __init__(self
, atype
, string
, family
, logger
):
637 Attribute
.__init
__(self
, atype
, string
, logger
)
641 def decode(self
, parent_msg
, data
):
642 self
.decode_length_type(data
)
643 wordcount
= (self
.attr_end
- 4)/4
644 self
.PACK
= '=%dL' % wordcount
645 self
.LEN
= calcsize(self
.PACK
)
648 self
.value
= ''.join(map(str, unpack(self
.PACK
, self
.data
[4:])))
650 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:])))
654 class AttributeOneByteValue(AttributeGeneric
):
656 def __init__(self
, atype
, string
, family
, logger
):
657 AttributeGeneric
.__init
__(self
, atype
, string
, family
, logger
)
659 self
.LEN
= calcsize(self
.PACK
)
661 def decode(self
, parent_msg
, data
):
662 self
.decode_length_type(data
)
663 assert self
.attr_end
== 8, "Attribute length for %s must be 8, it is %d" % (self
, self
.attr_end
)
666 self
.value
= int(unpack(self
.PACK
, self
.data
[4:8])[0])
668 self
.log
.error("%s unpack of %s failed, data 0x%s" % (self
, self
.PACK
, hexlify(self
.data
[4:5])))
672 length
= self
.HEADER_LEN
+ self
.LEN
673 raw
= pack(self
.HEADER_PACK
, length
-3, self
.atype
) + pack(self
.PACK
, self
.value
)
674 raw
= self
.pad(length
, raw
)
677 def dump_lines(self
, dump_buffer
, line_number
, color
):
678 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
679 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[4:8], self
.value
))
680 return line_number
+ 1
683 class AttributeIFLA_AF_SPEC(Attribute
):
685 value will be a dictionary such as:
687 Link.IFLA_BRIDGE_FLAGS: flags,
688 Link.IFLA_BRIDGE_VLAN_INFO: (vflags, vlanid)
691 def __init__(self
, atype
, string
, family
, logger
):
692 Attribute
.__init
__(self
, atype
, string
, logger
)
696 pack_layout
= [self
.HEADER_PACK
]
697 payload
= [0, self
.atype | NLA_F_NESTED
]
698 attr_length_index
= 0
700 # For now this assumes that all data will be packed in the native endian
701 # order (=). If a field is added that needs to be packed via network
702 # order (>) then some smarts will need to be added to split the pack_layout
703 # string at the >, split the payload and make the needed pack() calls.
705 # Until we cross that bridge though we will keep things nice and simple and
706 # pack everything via a single pack() call.
709 for (sub_attr_type
, sub_attr_value
) in self
.value
.iteritems():
711 if sub_attr_type
== Link
.IFLA_BRIDGE_FLAGS
:
712 sub_attr_to_add
.append((sub_attr_type
, sub_attr_value
))
714 elif sub_attr_type
== Link
.IFLA_BRIDGE_VLAN_INFO
:
715 for (vlan_flag
, vlan_id
) in sub_attr_value
:
716 sub_attr_to_add
.append((sub_attr_type
, (vlan_flag
, vlan_id
)))
719 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_AF_SPEC sub-attribute type %d' % sub_attr_type
)
722 for (sub_attr_type
, sub_attr_value
) in sub_attr_to_add
:
723 sub_attr_pack_layout
= ['=', 'HH']
724 sub_attr_payload
= [0, sub_attr_type
]
725 sub_attr_length_index
= 0
727 if sub_attr_type
== Link
.IFLA_BRIDGE_FLAGS
:
728 sub_attr_pack_layout
.append('H')
729 sub_attr_payload
.append(sub_attr_value
)
731 elif sub_attr_type
== Link
.IFLA_BRIDGE_VLAN_INFO
:
732 sub_attr_pack_layout
.append('HH')
733 sub_attr_payload
.append(sub_attr_value
[0])
734 sub_attr_payload
.append(sub_attr_value
[1])
736 sub_attr_length
= calcsize(''.join(sub_attr_pack_layout
))
737 sub_attr_payload
[sub_attr_length_index
] = sub_attr_length
740 for x
in xrange(self
.pad_bytes_needed(sub_attr_length
)):
741 sub_attr_pack_layout
.append('x')
743 # The [1:] is to remove the leading = so that when we do the ''.join() later
744 # we do not end up with an = in the middle of the pack layout string. There
745 # will be an = at the beginning via self.HEADER_PACK
746 sub_attr_pack_layout
= sub_attr_pack_layout
[1:]
748 # Now extend the ovarall attribute pack_layout/payload to include this sub-attribute
749 pack_layout
.extend(sub_attr_pack_layout
)
750 payload
.extend(sub_attr_payload
)
752 pack_layout
= ''.join(pack_layout
)
754 # Fill in the length field
755 length
= calcsize(pack_layout
)
756 payload
[attr_length_index
] = length
758 raw
= pack(pack_layout
, *payload
)
759 raw
= self
.pad(length
, raw
)
762 def decode(self
, parent_msg
, data
):
764 value is a dictionary such as:
766 Link.IFLA_BRIDGE_FLAGS: flags,
767 Link.IFLA_BRIDGE_VLAN_INFO: (vflags, vlanid)
771 The encoding of the IFLA_AF_SPEC attribute varies depending on the family
772 used for the request (RTM_GETLINK) message. For AF_UNSPEC the encoding
773 has another level of nesting for each address family with the type encoded
775 af_spec = nla_nest_start(skb, IFLA_AF_SPEC)
777 af = nla_nest_start(skb, af_ops->family)
778 af_ops->fill_link_af(skb, dev, ext_filter_mask)
782 This allows the parser to find the address family by looking at the first
785 Whereas AF_BRIDGE encoding is just:
786 af_spec = nla_nest_start(skb, IFLA_AF_SPEC)
787 br_fill_ifvlaninfo{_compressed}(skb, vg)
790 which means the parser can not use the attribute itself to know the family
791 to which the attribute belongs.
793 /include/uapi/linux/if_link.h
796 * Contains nested attributes for address family specific attributes.
797 * Each address family may create a attribute with the address family
798 * number as type and create its own attribute structure in it.
803 * [IFLA_INET_CONF] = ...,
806 * [IFLA_INET6_FLAGS] = ...,
807 * [IFLA_INET6_CONF] = ...,
813 self
.decode_length_type(data
)
819 (sub_attr_length
, sub_attr_type
) = unpack('=HH', data
[:4])
820 sub_attr_end
= padded_length(sub_attr_length
)
822 if not sub_attr_length
:
823 self
.log
.error('parsed a zero length sub-attr')
826 sub_attr_data
= data
[4:sub_attr_end
]
828 if self
.family
== AF_BRIDGE
:
829 if sub_attr_type
== Link
.IFLA_BRIDGE_FLAGS
:
830 self
.value
[Link
.IFLA_BRIDGE_FLAGS
] = unpack("=H", sub_attr_data
[0:2])[0]
832 elif sub_attr_type
== Link
.IFLA_BRIDGE_VLAN_INFO
:
833 if Link
.IFLA_BRIDGE_VLAN_INFO
not in self
.value
:
834 self
.value
[Link
.IFLA_BRIDGE_VLAN_INFO
] = []
835 self
.value
[Link
.IFLA_BRIDGE_VLAN_INFO
].append(tuple(unpack("=HH", sub_attr_data
[0:4])))
838 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_AF_SPEC sub-attribute '
839 'type %s (%d), length %d, padded to %d' %
840 (parent_msg
.get_ifla_bridge_af_spec_to_string(sub_attr_type
),
841 sub_attr_type
, sub_attr_length
, sub_attr_end
))
843 elif self
.family
== AF_UNSPEC
:
845 if sub_attr_type
== AF_INET6
:
849 (inet6_attr_length
, inet6_attr_type
) = unpack('=HH', sub_attr_data
[:4])
850 inet6_attr_end
= padded_length(inet6_attr_length
)
853 if inet6_attr_type
== Link
.IFLA_INET6_ADDR_GEN_MODE
:
854 inet6_attr
[inet6_attr_type
] = unpack('=B', sub_attr_data
[4])[0]
855 # nlmanager doesn't support multiple kernel version
856 # all the other attributes like IFLA_INET6_CONF are
857 # based on DEVCONF_MAX from _UAPI_IPV6_H.
858 # we can opti the code and break this loop once we
859 # found the attribute that we are interested in.
860 # It's not really worth going through all the other
861 # attributes to log that we don't support them yet
866 'Add support for decoding AF_INET6 IFLA_AF_SPEC '
867 'sub-attribute type %s (%d), length %d, padded to %d'
869 parent_msg
.get_ifla_inet6_af_spec_to_string(inet6_attr_type
),
870 inet6_attr_type
, inet6_attr_length
, inet6_attr_end
874 sub_attr_data
= sub_attr_data
[inet6_attr_end
:]
875 self
.value
[AF_INET6
] = inet6_attr
877 self
.value
[sub_attr_type
] = {}
879 # Uncomment the following block to implement the AF_INET attributes
880 # see Link.get_ifla_inet_af_spec_to_string (dict)
881 #elif sub_attr_type == AF_INET:
884 # while sub_attr_data:
885 # (inet_attr_length, inet_attr_type) = unpack('=HH', sub_attr_data[:4])
886 # inet_attr_end = padded_length(inet_attr_length)
889 # # SYSLOG_EXTRA_DEBUG,
890 # 'Add support for decoding AF_INET IFLA_AF_SPEC '
891 # 'sub-attribute type %s (%d), length %d, padded to %d'
893 # parent_msg.get_ifla_inet_af_spec_to_string(inet_attr_type),
894 # inet_attr_type, inet_attr_length, inet_attr_end
898 # sub_attr_data = sub_attr_data[inet_attr_end:]
900 # self.value[AF_INET] = inet_attr
902 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_AF_SPEC sub-attribute '
903 'family %d, length %d, padded to %d'
904 % (self
.family
, sub_attr_length
, sub_attr_end
))
906 data
= data
[sub_attr_end
:]
908 def dump_lines(self
, dump_buffer
, line_number
, color
):
909 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
912 next_sub_attr_line
= 0
915 for x
in xrange(1, self
.attr_end
/4):
919 if line_number
== next_sub_attr_line
:
923 sub_attr_line
= False
925 (sub_attr_length
, sub_attr_type
) = unpack('=HH', self
.data
[start
:start
+4])
926 sub_attr_end
= padded_length(sub_attr_length
)
928 next_sub_attr_line
= line_number
+ (sub_attr_end
/4)
930 if sub_attr_end
== sub_attr_length
:
933 padded_to
= ' padded to %d,' % sub_attr_end
935 if self
.family
== AF_BRIDGE
:
936 extra
= 'Nested Attribute - Length %s (%d)%s Type %s (%d) %s' % \
937 (zfilled_hex(sub_attr_length
, 4), sub_attr_length
,
939 zfilled_hex(sub_attr_type
, 4), sub_attr_type
,
940 Link
.ifla_bridge_af_spec_to_string
.get(sub_attr_type
))
941 elif self
.family
== AF_UNSPEC
:
942 if sub_attr_type
== AF_INET6
:
944 elif sub_attr_type
== AF_INET
:
947 family
= 'Unsupported family %d' % sub_attr_type
949 extra
= 'Nested Attribute Structure for %s - Length %s (%d)%s Type %s (%d)' % (
950 family
, zfilled_hex(sub_attr_length
, 4), sub_attr_length
, padded_to
,
951 zfilled_hex(sub_attr_type
, 4), sub_attr_type
,
956 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], extra
))
961 def get_pretty_value(self
, obj
=None):
963 if obj
and callable(obj
):
964 return obj(self
.value
)
966 # We do this so we can print a more human readable dictionary
967 # with the names of the nested keys instead of their numbers
970 if self
.family
== AF_BRIDGE
:
971 for (sub_key
, sub_value
) in self
.value
.iteritems():
972 sub_key_pretty
= "(%2d) %s" % (sub_key
, Link
.ifla_bridge_af_spec_to_string
.get(sub_key
))
973 value_pretty
[sub_key_pretty
] = sub_value
974 elif self
.family
== AF_UNSPEC
:
975 for (family
, family_attr
) in self
.value
.iteritems():
976 family_value_pretty
= {}
978 if family
== AF_INET6
:
979 family_af_spec_to_string
= Link
.ifla_inet6_af_spec_to_string
980 elif family
== AF_INET
:
981 family_af_spec_to_string
= Link
.ifla_inet_af_spec_to_string
983 continue # log error?
985 for (sub_key
, sub_value
) in family_attr
.iteritems():
986 sub_key_pretty
= "(%2d) %s" % (sub_key
, family_af_spec_to_string
.get(sub_key
))
987 family_value_pretty
[sub_key_pretty
] = sub_value
988 value_pretty
= family_value_pretty
994 class AttributeRTA_MULTIPATH(Attribute
):
996 /* RTA_MULTIPATH --- array of struct rtnexthop.
998 * "struct rtnexthop" describes all necessary nexthop information,
999 * i.e. parameters of path to a destination via this nexthop.
1001 * At the moment it is impossible to set different prefsrc, mtu, window
1002 * and rtt for different paths from multipath.
1006 unsigned short rtnh_len;
1007 unsigned char rtnh_flags;
1008 unsigned char rtnh_hops;
1013 def __init__(self
, atype
, string
, family
, logger
):
1014 Attribute
.__init
__(self
, atype
, string
, logger
)
1015 self
.family
= family
1018 self
.RTNH_PACK
= '=HBBL' # rtnh_len, flags, hops, ifindex
1019 self
.RTNH_LEN
= calcsize(self
.RTNH_PACK
)
1025 # Calculate the length
1026 if self
.family
== AF_INET
:
1027 ip_len
= self
.IPV4_LEN
1028 elif self
.family
== AF_INET6
:
1029 ip_len
= self
.IPV6_LEN
1032 length
= self
.HEADER_LEN
+ ((self
.RTNH_LEN
+ self
.HEADER_LEN
+ ip_len
) * len(self
.value
))
1033 raw
= pack(self
.HEADER_PACK
, length
, self
.atype
)
1037 rtnh_len
= self
.RTNH_LEN
+ self
.HEADER_LEN
+ ip_len
1039 for (nexthop
, rtnh_ifindex
) in self
.value
:
1042 raw
+= pack(self
.RTNH_PACK
, rtnh_len
, rtnh_flags
, rtnh_hops
, rtnh_ifindex
)
1045 raw
+= pack(self
.HEADER_PACK
, self
.HEADER_LEN
+ ip_len
, Route
.RTA_GATEWAY
)
1047 if self
.family
== AF_INET
:
1048 raw
+= pack('>L', nexthop
)
1049 elif self
.family
== AF_INET6
:
1050 raw
+= pack('>QQ', nexthop
>> 64, nexthop
& 0x0000000000000000FFFFFFFFFFFFFFFF)
1052 raw
= self
.pad(length
, raw
)
1055 def decode(self
, parent_msg
, data
):
1056 self
.decode_length_type(data
)
1059 data
= self
.data
[4:]
1062 (rtnh_len
, rtnh_flags
, rtnh_hops
, rtnh_ifindex
) = unpack(self
.RTNH_PACK
, data
[:self
.RTNH_LEN
])
1063 data
= data
[self
.RTNH_LEN
:]
1065 (attr_type
, attr_length
) = unpack(self
.HEADER_PACK
, self
.data
[:self
.HEADER_LEN
])
1066 data
= data
[self
.HEADER_LEN
:]
1068 if self
.family
== AF_INET
:
1069 if len(data
) < self
.IPV4_LEN
:
1071 nexthop
= IPv4Address(unpack('>L', data
[:self
.IPV4_LEN
])[0])
1072 self
.value
.append((nexthop
, rtnh_ifindex
, rtnh_flags
, rtnh_hops
))
1074 elif self
.family
== AF_INET6
:
1075 if len(data
) < self
.IPV6_LEN
:
1077 (data1
, data2
) = unpack('>QQ', data
[:self
.IPV6_LEN
])
1078 nexthop
= IPv6Address(data1
<< 64 | data2
)
1079 self
.value
.append((nexthop
, rtnh_ifindex
, rtnh_flags
, rtnh_hops
))
1081 data
= data
[(rtnh_len
-self
.RTNH_LEN
-self
.HEADER_LEN
):]
1083 self
.value
= tuple(self
.value
)
1086 class AttributeIFLA_LINKINFO(Attribute
):
1088 value is a dictionary such as:
1091 Link.IFLA_INFO_KIND : 'vlan',
1092 Link.IFLA_INFO_DATA : {
1093 Link.IFLA_VLAN_ID : vlanid,
1097 def __init__(self
, atype
, string
, family
, logger
):
1098 Attribute
.__init
__(self
, atype
, string
, logger
)
1101 pack_layout
= [self
.HEADER_PACK
]
1102 payload
= [0, self
.atype | NLA_F_NESTED
]
1103 attr_length_index
= 0
1105 kind
= self
.value
.get(Link
.IFLA_INFO_KIND
)
1106 slave_kind
= self
.value
.get(Link
.IFLA_INFO_SLAVE_KIND
)
1108 if not slave_kind
and kind
not in ('vlan', 'macvlan', 'vxlan', 'bond', 'bridge'):
1109 raise Exception('Unsupported IFLA_INFO_KIND %s' % kind
)
1110 elif not kind
and slave_kind
!= 'bridge':
1111 # only support brport for now.
1112 raise Exception('Unsupported IFLA_INFO_SLAVE_KIND %s' % slave_kind
)
1114 # For now this assumes that all data will be packed in the native endian
1115 # order (=). If a field is added that needs to be packed via network
1116 # order (>) then some smarts will need to be added to split the pack_layout
1117 # string at the >, split the payload and make the needed pack() calls.
1119 # Until we cross that bridge though we will keep things nice and simple and
1120 # pack everything via a single pack() call.
1121 for (sub_attr_type
, sub_attr_value
) in self
.value
.iteritems():
1122 sub_attr_pack_layout
= ['=', 'HH']
1123 sub_attr_payload
= [0, sub_attr_type
]
1124 sub_attr_length_index
= 0
1126 if sub_attr_type
== Link
.IFLA_INFO_KIND
:
1127 sub_attr_pack_layout
.append('%ds' % len(sub_attr_value
))
1128 sub_attr_payload
.append(sub_attr_value
)
1130 elif sub_attr_type
== Link
.IFLA_INFO_DATA
:
1132 sub_attr_payload
= [0, sub_attr_type | NLA_F_NESTED
]
1134 for (info_data_type
, info_data_value
) in sub_attr_value
.iteritems():
1137 if info_data_type
== Link
.IFLA_VLAN_ID
:
1138 sub_attr_pack_layout
.append('HH')
1139 sub_attr_payload
.append(6) # length
1140 sub_attr_payload
.append(info_data_type
)
1143 sub_attr_pack_layout
.append('H')
1144 sub_attr_payload
.append(info_data_value
)
1147 sub_attr_pack_layout
.extend('xx')
1149 elif info_data_type
== Link
.IFLA_VLAN_PROTOCOL
:
1150 sub_attr_pack_layout
.append('HH')
1151 sub_attr_payload
.append(6) # length
1152 sub_attr_payload
.append(info_data_type
)
1155 vlan_protocol
= Link
.ifla_vlan_protocol_dict
.get(info_data_value
)
1156 if not vlan_protocol
:
1157 raise NotImplementedError('vlan protocol %s not implemented' % info_data_value
)
1159 sub_attr_pack_layout
.append('H')
1160 sub_attr_payload
.append(htons(vlan_protocol
))
1163 sub_attr_pack_layout
.extend('xx')
1165 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA vlan sub-attribute type %d' % info_data_type
)
1167 elif kind
== 'macvlan':
1168 if info_data_type
== Link
.IFLA_MACVLAN_MODE
:
1169 sub_attr_pack_layout
.append('HH')
1170 sub_attr_payload
.append(8) # length
1171 sub_attr_payload
.append(info_data_type
)
1174 sub_attr_pack_layout
.append('L')
1175 sub_attr_payload
.append(info_data_value
)
1178 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA macvlan sub-attribute type %d' % info_data_type
)
1180 elif kind
== 'vxlan':
1181 if info_data_type
in (Link
.IFLA_VXLAN_ID
,
1182 Link
.IFLA_VXLAN_LINK
,
1183 Link
.IFLA_VXLAN_AGEING
,
1184 Link
.IFLA_VXLAN_LIMIT
,
1185 Link
.IFLA_VXLAN_PORT_RANGE
):
1186 sub_attr_pack_layout
.append('HH')
1187 sub_attr_payload
.append(8) # length
1188 sub_attr_payload
.append(info_data_type
)
1190 sub_attr_pack_layout
.append('L')
1191 sub_attr_payload
.append(info_data_value
)
1193 elif info_data_type
in (Link
.IFLA_VXLAN_GROUP
,
1194 Link
.IFLA_VXLAN_LOCAL
):
1195 sub_attr_pack_layout
.append('HH')
1196 sub_attr_payload
.append(8) # length
1197 sub_attr_payload
.append(info_data_type
)
1199 sub_attr_pack_layout
.append('L')
1201 reorder
= unpack('<L', IPv4Address(info_data_value
).packed
)[0]
1202 sub_attr_payload
.append(IPv4Address(reorder
))
1204 elif info_data_type
in (Link
.IFLA_VXLAN_PORT
,):
1205 sub_attr_pack_layout
.append('HH')
1206 sub_attr_payload
.append(6)
1207 sub_attr_payload
.append(info_data_type
)
1209 sub_attr_pack_layout
.append('H')
1212 swaped
= pack(">H", info_data_value
)
1213 sub_attr_payload
.append(unpack("<H", swaped
)[0])
1215 sub_attr_pack_layout
.extend('xx')
1217 elif info_data_type
in (Link
.IFLA_VXLAN_TTL
,
1218 Link
.IFLA_VXLAN_TOS
,
1219 Link
.IFLA_VXLAN_LEARNING
,
1220 Link
.IFLA_VXLAN_PROXY
,
1221 Link
.IFLA_VXLAN_RSC
,
1222 Link
.IFLA_VXLAN_L2MISS
,
1223 Link
.IFLA_VXLAN_L3MISS
,
1224 Link
.IFLA_VXLAN_UDP_CSUM
,
1225 Link
.IFLA_VXLAN_UDP_ZERO_CSUM6_TX
,
1226 Link
.IFLA_VXLAN_UDP_ZERO_CSUM6_RX
,
1227 Link
.IFLA_VXLAN_REMCSUM_TX
,
1228 Link
.IFLA_VXLAN_REMCSUM_RX
,
1229 Link
.IFLA_VXLAN_REPLICATION_TYPE
):
1230 sub_attr_pack_layout
.append('HH')
1231 sub_attr_payload
.append(6)
1232 sub_attr_payload
.append(info_data_type
)
1234 sub_attr_pack_layout
.append('B')
1235 sub_attr_payload
.append(info_data_value
)
1236 sub_attr_pack_layout
.extend('xxx')
1239 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA vxlan sub-attribute type %d' % info_data_type
)
1241 elif kind
== 'bond':
1242 if info_data_type
in (Link
.IFLA_BOND_AD_ACTOR_SYSTEM
, ):
1243 sub_attr_pack_layout
.append('HH')
1244 sub_attr_payload
.append(10) # length
1245 sub_attr_payload
.append(info_data_type
)
1247 sub_attr_pack_layout
.append('6B')
1248 for mbyte
in info_data_value
.replace('.', ' ').replace(':', ' ').split():
1249 sub_attr_payload
.append(int(mbyte
, 16))
1250 sub_attr_pack_layout
.extend('xx')
1252 elif info_data_type
== Link
.IFLA_BOND_AD_ACTOR_SYS_PRIO
:
1253 sub_attr_pack_layout
.append('HH')
1254 sub_attr_payload
.append(6) # length
1255 sub_attr_payload
.append(info_data_type
)
1258 sub_attr_pack_layout
.append('H')
1259 sub_attr_payload
.append(int(info_data_value
))
1262 sub_attr_pack_layout
.extend('xx')
1264 elif info_data_type
== Link
.IFLA_BOND_NUM_PEER_NOTIF
:
1265 sub_attr_pack_layout
.append('HH')
1266 sub_attr_payload
.append(5) # length
1267 sub_attr_payload
.append(info_data_type
)
1270 sub_attr_pack_layout
.append('B')
1271 sub_attr_payload
.append(int(info_data_value
))
1274 sub_attr_pack_layout
.extend('xxx')
1277 elif info_data_type
in (Link
.IFLA_BOND_AD_LACP_RATE
,
1278 Link
.IFLA_BOND_AD_LACP_BYPASS
,
1279 Link
.IFLA_BOND_USE_CARRIER
):
1280 # converts yes/no/on/off/0/1 strings to boolean value
1281 bool_value
= self
.get_bool_value(info_data_value
)
1283 sub_attr_pack_layout
.append('HH')
1284 sub_attr_payload
.append(5) # length
1285 sub_attr_payload
.append(info_data_type
)
1288 sub_attr_pack_layout
.append('B')
1289 sub_attr_payload
.append(bool_value
)
1292 sub_attr_pack_layout
.extend('xxx')
1294 elif info_data_type
== Link
.IFLA_BOND_XMIT_HASH_POLICY
:
1295 index
= self
.get_index(Link
.ifla_bond_xmit_hash_policy_tbl
,
1296 'bond xmit hash policy',
1299 sub_attr_pack_layout
.append('HH')
1300 sub_attr_payload
.append(5) # length
1301 sub_attr_payload
.append(info_data_type
)
1304 sub_attr_pack_layout
.append('B')
1305 sub_attr_payload
.append(index
)
1308 sub_attr_pack_layout
.extend('xxx')
1310 elif info_data_type
== Link
.IFLA_BOND_MODE
:
1311 index
= self
.get_index(Link
.ifla_bond_mode_tbl
,
1315 sub_attr_pack_layout
.append('HH')
1316 sub_attr_payload
.append(5) # length
1317 sub_attr_payload
.append(info_data_type
)
1320 sub_attr_pack_layout
.append('B')
1321 sub_attr_payload
.append(index
)
1324 sub_attr_pack_layout
.extend('xxx')
1326 elif info_data_type
in (Link
.IFLA_BOND_MIIMON
,
1327 Link
.IFLA_BOND_UPDELAY
,
1328 Link
.IFLA_BOND_DOWNDELAY
,
1329 Link
.IFLA_BOND_MIN_LINKS
):
1330 sub_attr_pack_layout
.append('HH')
1331 sub_attr_payload
.append(8) # length
1332 sub_attr_payload
.append(info_data_type
)
1334 sub_attr_pack_layout
.append('L')
1335 sub_attr_payload
.append(int(info_data_value
))
1338 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA bond sub-attribute type %d' % info_data_type
)
1340 elif kind
== 'bridge':
1341 if info_data_type
== Link
.IFLA_BR_VLAN_PROTOCOL
:
1342 sub_attr_pack_layout
.append('HH')
1343 sub_attr_payload
.append(6) # length
1344 sub_attr_payload
.append(info_data_type
)
1347 vlan_protocol
= Link
.ifla_vlan_protocol_dict
.get(info_data_value
)
1348 if not vlan_protocol
:
1349 raise NotImplementedError('vlan protocol %s not implemented' % info_data_value
)
1351 sub_attr_pack_layout
.append('H')
1352 sub_attr_payload
.append(htons(vlan_protocol
))
1355 sub_attr_pack_layout
.extend('xx')
1358 elif info_data_type
in (Link
.IFLA_BR_VLAN_FILTERING
,
1359 Link
.IFLA_BR_TOPOLOGY_CHANGE
,
1360 Link
.IFLA_BR_TOPOLOGY_CHANGE_DETECTED
,
1361 Link
.IFLA_BR_MCAST_ROUTER
,
1362 Link
.IFLA_BR_MCAST_SNOOPING
,
1363 Link
.IFLA_BR_MCAST_QUERY_USE_IFADDR
,
1364 Link
.IFLA_BR_MCAST_QUERIER
,
1365 Link
.IFLA_BR_NF_CALL_IPTABLES
,
1366 Link
.IFLA_BR_NF_CALL_IP6TABLES
,
1367 Link
.IFLA_BR_NF_CALL_ARPTABLES
,
1368 Link
.IFLA_BR_VLAN_STATS_ENABLED
,
1369 Link
.IFLA_BR_MCAST_STATS_ENABLED
,
1370 Link
.IFLA_BR_MCAST_IGMP_VERSION
,
1371 Link
.IFLA_BR_MCAST_MLD_VERSION
):
1372 sub_attr_pack_layout
.append('HH')
1373 sub_attr_payload
.append(5) # length
1374 sub_attr_payload
.append(info_data_type
)
1377 sub_attr_pack_layout
.append('B')
1378 sub_attr_payload
.append(int(info_data_value
))
1381 sub_attr_pack_layout
.extend('xxx')
1384 elif info_data_type
in (Link
.IFLA_BR_PRIORITY
,
1385 Link
.IFLA_BR_GROUP_FWD_MASK
,
1386 Link
.IFLA_BR_ROOT_PORT
,
1387 Link
.IFLA_BR_VLAN_DEFAULT_PVID
):
1388 sub_attr_pack_layout
.append('HH')
1389 sub_attr_payload
.append(6) # length
1390 sub_attr_payload
.append(info_data_type
)
1393 sub_attr_pack_layout
.append('H')
1394 sub_attr_payload
.append(int(info_data_value
))
1397 sub_attr_pack_layout
.extend('xx')
1400 elif info_data_type
in (Link
.IFLA_BR_FORWARD_DELAY
,
1401 Link
.IFLA_BR_HELLO_TIME
,
1402 Link
.IFLA_BR_MAX_AGE
,
1403 Link
.IFLA_BR_AGEING_TIME
,
1404 Link
.IFLA_BR_STP_STATE
,
1405 Link
.IFLA_BR_ROOT_PATH_COST
,
1406 Link
.IFLA_BR_MCAST_QUERIER
,
1407 Link
.IFLA_BR_MCAST_HASH_ELASTICITY
,
1408 Link
.IFLA_BR_MCAST_HASH_MAX
,
1409 Link
.IFLA_BR_MCAST_LAST_MEMBER_CNT
,
1410 Link
.IFLA_BR_MCAST_STARTUP_QUERY_CNT
):
1411 sub_attr_pack_layout
.append('HH')
1412 sub_attr_payload
.append(8) # length
1413 sub_attr_payload
.append(info_data_type
)
1415 sub_attr_pack_layout
.append('L')
1416 sub_attr_payload
.append(int(info_data_value
))
1419 elif info_data_type
in (Link
.IFLA_BR_MCAST_LAST_MEMBER_INTVL
,
1420 Link
.IFLA_BR_MCAST_MEMBERSHIP_INTVL
,
1421 Link
.IFLA_BR_MCAST_QUERIER_INTVL
,
1422 Link
.IFLA_BR_MCAST_QUERY_INTVL
,
1423 Link
.IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
,
1424 Link
.IFLA_BR_MCAST_STARTUP_QUERY_INTVL
):
1425 sub_attr_pack_layout
.append('HH')
1426 sub_attr_payload
.append(12) # length
1427 sub_attr_payload
.append(info_data_type
)
1429 sub_attr_pack_layout
.append('Q')
1430 sub_attr_payload
.append(int(info_data_value
))
1433 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_DATA bridge sub-attribute type %d' % info_data_type
)
1435 elif sub_attr_type
== Link
.IFLA_INFO_SLAVE_DATA
:
1437 sub_attr_payload
= [0, sub_attr_type | NLA_F_NESTED
]
1439 for (info_slave_data_type
, info_slave_data_value
) in sub_attr_value
.iteritems():
1441 if slave_kind
== 'bridge':
1444 if info_slave_data_type
in (Link
.IFLA_BRPORT_STATE
,
1445 Link
.IFLA_BRPORT_MODE
,
1446 Link
.IFLA_BRPORT_GUARD
,
1447 Link
.IFLA_BRPORT_PROTECT
,
1448 Link
.IFLA_BRPORT_FAST_LEAVE
,
1449 Link
.IFLA_BRPORT_LEARNING
,
1450 Link
.IFLA_BRPORT_UNICAST_FLOOD
,
1451 Link
.IFLA_BRPORT_PROXYARP
,
1452 Link
.IFLA_BRPORT_LEARNING_SYNC
,
1453 Link
.IFLA_BRPORT_PROXYARP_WIFI
,
1454 Link
.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
,
1455 Link
.IFLA_BRPORT_CONFIG_PENDING
,
1456 Link
.IFLA_BRPORT_MULTICAST_ROUTER
,
1457 Link
.IFLA_BRPORT_MCAST_FLOOD
,
1458 Link
.IFLA_BRPORT_MCAST_TO_UCAST
,
1459 Link
.IFLA_BRPORT_VLAN_TUNNEL
,
1460 Link
.IFLA_BRPORT_BCAST_FLOOD
,
1461 Link
.IFLA_BRPORT_PEER_LINK
,
1462 Link
.IFLA_BRPORT_DUAL_LINK
,
1463 Link
.IFLA_BRPORT_ARP_SUPPRESS
,
1464 Link
.IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
):
1465 sub_attr_pack_layout
.append('HH')
1466 sub_attr_payload
.append(5) # length
1467 sub_attr_payload
.append(info_slave_data_type
)
1470 sub_attr_pack_layout
.append('B')
1471 sub_attr_payload
.append(int(info_slave_data_value
))
1474 sub_attr_pack_layout
.extend('xxx')
1477 elif info_slave_data_type
in (Link
.IFLA_BRPORT_PRIORITY
,
1478 Link
.IFLA_BRPORT_DESIGNATED_PORT
,
1479 Link
.IFLA_BRPORT_DESIGNATED_COST
,
1480 Link
.IFLA_BRPORT_ID
,
1481 Link
.IFLA_BRPORT_NO
,
1482 Link
.IFLA_BRPORT_GROUP_FWD_MASK
,
1483 Link
.IFLA_BRPORT_GROUP_FWD_MASKHI
):
1484 sub_attr_pack_layout
.append('HH')
1485 sub_attr_payload
.append(6) # length
1486 sub_attr_payload
.append(info_slave_data_type
)
1489 sub_attr_pack_layout
.append('H')
1490 sub_attr_payload
.append(int(info_slave_data_value
))
1493 sub_attr_pack_layout
.extend('xx')
1496 elif info_slave_data_type
== Link
.IFLA_BRPORT_COST
:
1497 sub_attr_pack_layout
.append('HH')
1498 sub_attr_payload
.append(8) # length
1499 sub_attr_payload
.append(info_slave_data_type
)
1501 sub_attr_pack_layout
.append('L')
1502 sub_attr_payload
.append(int(info_slave_data_value
))
1505 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_INFO_SLAVE_DATA bond sub-attribute type %d' % info_slave_data_type
)
1508 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_LINKINFO kind %s' % slave_kind
)
1511 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_LINKINFO sub-attribute type %d' % sub_attr_type
)
1514 sub_attr_length
= calcsize(''.join(sub_attr_pack_layout
))
1515 sub_attr_payload
[sub_attr_length_index
] = sub_attr_length
1518 for x
in xrange(self
.pad_bytes_needed(sub_attr_length
)):
1519 sub_attr_pack_layout
.append('x')
1521 # The [1:] is to remove the leading = so that when we do the ''.join() later
1522 # we do not end up with an = in the middle of the pack layout string. There
1523 # will be an = at the beginning via self.HEADER_PACK
1524 sub_attr_pack_layout
= sub_attr_pack_layout
[1:]
1526 # Now extend the ovarall attribute pack_layout/payload to include this sub-attribute
1527 pack_layout
.extend(sub_attr_pack_layout
)
1528 payload
.extend(sub_attr_payload
)
1530 pack_layout
= ''.join(pack_layout
)
1532 # Fill in the length field
1533 length
= calcsize(pack_layout
)
1534 payload
[attr_length_index
] = length
1536 raw
= pack(pack_layout
, *payload
)
1537 raw
= self
.pad(length
, raw
)
1540 def get_bool_value(self
, value
, default
=None):
1542 return value_to_bool_dict
[value
]
1544 self
.log
.debug('%s: unsupported boolean value' % value
)
1547 def get_index(self
, tbl
, attr
, value
, default
=None):
1551 self
.log
.debug('unsupported %s value %s (%s)' % (attr
, value
, tbl
.keys()))
1554 def decode(self
, parent_msg
, data
):
1556 value is a dictionary such as:
1559 Link.IFLA_INFO_KIND : 'vlan',
1560 Link.IFLA_INFO_DATA : {
1561 Link.IFLA_VLAN_ID : vlanid,
1565 self
.decode_length_type(data
)
1568 data
= self
.data
[4:]
1570 # IFLA_MACVLAN_MODE and IFLA_VLAN_ID both have a value of 1 and both are
1571 # valid IFLA_INFO_DATA entries :( The sender must TX IFLA_INFO_KIND
1572 # first in order for us to know if "1" is IFLA_MACVLAN_MODE vs IFLA_VLAN_ID.
1575 (sub_attr_length
, sub_attr_type
) = unpack('=HH', data
[:4])
1576 sub_attr_end
= padded_length(sub_attr_length
)
1578 if not sub_attr_length
:
1579 self
.log
.error('parsed a zero length sub-attr')
1582 if sub_attr_type
in (Link
.IFLA_INFO_KIND
, Link
.IFLA_INFO_SLAVE_KIND
):
1583 self
.value
[sub_attr_type
] = remove_trailing_null(unpack('%ds' % (sub_attr_length
- 4), data
[4:sub_attr_length
])[0])
1585 elif sub_attr_type
== Link
.IFLA_INFO_SLAVE_DATA
:
1586 sub_attr_data
= data
[4:sub_attr_end
]
1588 ifla_info_slave_data
= dict()
1589 ifla_info_slave_kind
= self
.value
.get(Link
.IFLA_INFO_SLAVE_KIND
)
1591 if not ifla_info_slave_kind
:
1592 self
.log
.warning('IFLA_INFO_SLAVE_KIND is not known...we cannot parse IFLA_INFO_SLAVE_DATA')
1594 while sub_attr_data
:
1595 (info_data_length
, info_data_type
) = unpack('=HH', sub_attr_data
[:4])
1596 info_data_end
= padded_length(info_data_length
)
1598 if ifla_info_slave_kind
== 'bridge':
1600 if info_data_type
in (Link
.IFLA_BRPORT_STATE
,
1601 Link
.IFLA_BRPORT_MODE
,
1602 Link
.IFLA_BRPORT_GUARD
,
1603 Link
.IFLA_BRPORT_PROTECT
,
1604 Link
.IFLA_BRPORT_FAST_LEAVE
,
1605 Link
.IFLA_BRPORT_LEARNING
,
1606 Link
.IFLA_BRPORT_UNICAST_FLOOD
,
1607 Link
.IFLA_BRPORT_PROXYARP
,
1608 Link
.IFLA_BRPORT_LEARNING_SYNC
,
1609 Link
.IFLA_BRPORT_PROXYARP_WIFI
,
1610 Link
.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
,
1611 Link
.IFLA_BRPORT_CONFIG_PENDING
,
1612 Link
.IFLA_BRPORT_MULTICAST_ROUTER
,
1613 Link
.IFLA_BRPORT_MCAST_FLOOD
,
1614 Link
.IFLA_BRPORT_MCAST_TO_UCAST
,
1615 Link
.IFLA_BRPORT_VLAN_TUNNEL
,
1616 Link
.IFLA_BRPORT_PEER_LINK
,
1617 Link
.IFLA_BRPORT_DUAL_LINK
,
1618 Link
.IFLA_BRPORT_ARP_SUPPRESS
,
1619 Link
.IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
):
1620 ifla_info_slave_data
[info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1623 elif info_data_type
in (Link
.IFLA_BRPORT_PRIORITY
,
1624 Link
.IFLA_BRPORT_DESIGNATED_PORT
,
1625 Link
.IFLA_BRPORT_DESIGNATED_COST
,
1626 Link
.IFLA_BRPORT_ID
,
1627 Link
.IFLA_BRPORT_NO
,
1628 Link
.IFLA_BRPORT_GROUP_FWD_MASK
,
1629 Link
.IFLA_BRPORT_GROUP_FWD_MASKHI
):
1630 ifla_info_slave_data
[info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1633 elif info_data_type
== Link
.IFLA_BRPORT_COST
:
1634 ifla_info_slave_data
[info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1636 elif ifla_info_slave_kind
== 'bond':
1639 if info_data_type
in (
1640 Link
.IFLA_BOND_SLAVE_STATE
,
1641 Link
.IFLA_BOND_SLAVE_MII_STATUS
,
1642 Link
.IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE
,
1643 Link
.IFLA_BOND_SLAVE_AD_RX_BYPASS
,
1645 ifla_info_slave_data
[info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1648 elif info_data_type
in (
1649 Link
.IFLA_BOND_SLAVE_QUEUE_ID
,
1650 Link
.IFLA_BOND_SLAVE_AD_AGGREGATOR_ID
1652 ifla_info_slave_data
[info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1655 elif info_data_type
== (
1656 Link
.IFLA_BOND_SLAVE_PERM_HWADDR
,
1657 Link
.IFLA_BOND_SLAVE_LINK_FAILURE_COUNT
1659 ifla_info_slave_data
[info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1661 except Exception as e
:
1662 self
.log
.debug('%s: attribute %s: %s'
1663 % (self
.value
[Link
.IFLA_INFO_SLAVE_KIND
],
1666 sub_attr_data
= sub_attr_data
[info_data_end
:]
1668 self
.value
[Link
.IFLA_INFO_SLAVE_DATA
] = ifla_info_slave_data
1670 elif sub_attr_type
== Link
.IFLA_INFO_DATA
:
1671 sub_attr_data
= data
[4:sub_attr_end
]
1672 self
.value
[Link
.IFLA_INFO_DATA
] = {}
1674 ifla_info_kind
= self
.value
.get(Link
.IFLA_INFO_KIND
)
1675 if not ifla_info_kind
:
1676 self
.log
.warning('IFLA_INFO_KIND is not known...we cannot parse IFLA_INFO_DATA')
1678 while sub_attr_data
:
1679 (info_data_length
, info_data_type
) = unpack('=HH', sub_attr_data
[:4])
1680 info_data_end
= padded_length(info_data_length
)
1682 if ifla_info_kind
== 'vlan':
1683 if info_data_type
== Link
.IFLA_VLAN_ID
:
1684 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1686 elif info_data_type
== Link
.IFLA_VLAN_PROTOCOL
:
1687 hex_value
= '0x%s' % sub_attr_data
[4:6].encode('hex')
1688 vlan_protocol
= Link
.ifla_vlan_protocol_dict
.get(int(hex_value
, base
=16))
1691 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = vlan_protocol
1693 self
.log
.warning('IFLA_VLAN_PROTOCOL: cannot decode vlan protocol %s' % hex_value
)
1696 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND vlan type %s (%d), length %d, padded to %d' %
1697 (parent_msg
.get_ifla_vlan_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1699 elif ifla_info_kind
== 'macvlan':
1700 if info_data_type
== Link
.IFLA_MACVLAN_MODE
:
1701 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1703 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND macvlan type %s (%d), length %d, padded to %d' %
1704 (parent_msg
.get_ifla_macvlan_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1706 elif ifla_info_kind
== 'vxlan':
1709 if info_data_type
in (Link
.IFLA_VXLAN_GROUP
,
1710 Link
.IFLA_VXLAN_LOCAL
):
1711 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = IPv4Address(unpack('>L', sub_attr_data
[4:8])[0])
1714 elif info_data_type
in (Link
.IFLA_VXLAN_ID
,
1715 Link
.IFLA_VXLAN_LINK
,
1716 Link
.IFLA_VXLAN_AGEING
,
1717 Link
.IFLA_VXLAN_LIMIT
,
1718 Link
.IFLA_VXLAN_PORT_RANGE
):
1719 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1722 elif info_data_type
in (Link
.IFLA_VXLAN_PORT
, ):
1723 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('!H', sub_attr_data
[4:6])[0]
1724 # The form '!' is available for those poor souls who claim they can't
1725 # remember whether network byte order is big-endian or little-endian.
1728 elif info_data_type
in (Link
.IFLA_VXLAN_TTL
,
1729 Link
.IFLA_VXLAN_TOS
,
1730 Link
.IFLA_VXLAN_LEARNING
,
1731 Link
.IFLA_VXLAN_PROXY
,
1732 Link
.IFLA_VXLAN_RSC
,
1733 Link
.IFLA_VXLAN_L2MISS
,
1734 Link
.IFLA_VXLAN_L3MISS
,
1735 Link
.IFLA_VXLAN_UDP_CSUM
,
1736 Link
.IFLA_VXLAN_UDP_ZERO_CSUM6_TX
,
1737 Link
.IFLA_VXLAN_UDP_ZERO_CSUM6_RX
,
1738 Link
.IFLA_VXLAN_REMCSUM_TX
,
1739 Link
.IFLA_VXLAN_REMCSUM_RX
,
1740 Link
.IFLA_VXLAN_REPLICATION_TYPE
):
1741 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1744 # sub_attr_end = padded_length(sub_attr_length)
1745 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND vxlan type %s (%d), length %d, padded to %d' %
1746 (parent_msg
.get_ifla_vxlan_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1748 elif ifla_info_kind
== 'bond':
1750 if info_data_type
in (Link
.IFLA_BOND_AD_INFO
, ):
1751 ad_attr_data
= sub_attr_data
[4:info_data_end
]
1752 self
.value
[Link
.IFLA_INFO_DATA
][Link
.IFLA_BOND_AD_INFO
] = {}
1755 (ad_data_length
, ad_data_type
) = unpack('=HH', ad_attr_data
[:4])
1756 ad_data_end
= padded_length(ad_data_length
)
1758 if ad_data_type
in (Link
.IFLA_BOND_AD_INFO_PARTNER_MAC
,):
1759 (data1
, data2
) = unpack('>LHxx', ad_attr_data
[4:12])
1760 self
.value
[Link
.IFLA_INFO_DATA
][Link
.IFLA_BOND_AD_INFO
][ad_data_type
] = mac_int_to_str(data1
<< 16 | data2
)
1762 ad_attr_data
= ad_attr_data
[ad_data_end
:]
1765 elif info_data_type
in (Link
.IFLA_BOND_MODE
,
1766 Link
.IFLA_BOND_USE_CARRIER
,
1767 Link
.IFLA_BOND_AD_LACP_RATE
,
1768 Link
.IFLA_BOND_AD_LACP_BYPASS
,
1769 Link
.IFLA_BOND_XMIT_HASH_POLICY
,
1770 Link
.IFLA_BOND_NUM_PEER_NOTIF
):
1771 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1774 elif info_data_type
== Link
.IFLA_BOND_AD_ACTOR_SYS_PRIO
:
1775 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1778 elif info_data_type
in (Link
.IFLA_BOND_MIIMON
,
1779 Link
.IFLA_BOND_UPDELAY
,
1780 Link
.IFLA_BOND_DOWNDELAY
,
1781 Link
.IFLA_BOND_MIN_LINKS
):
1782 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1785 elif info_data_type
in (Link
.IFLA_BOND_AD_ACTOR_SYSTEM
, ):
1786 (data1
, data2
) = unpack('>LHxx', sub_attr_data
[4:12])
1787 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = mac_int_to_str(data1
<< 16 | data2
)
1790 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND bond type %s (%d), length %d, padded to %d' %
1791 (parent_msg
.get_ifla_bond_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1793 elif ifla_info_kind
== 'bridge':
1795 if info_data_type
in (Link
.IFLA_BR_AGEING_TIME
,
1796 Link
.IFLA_BR_FORWARD_DELAY
,
1797 Link
.IFLA_BR_HELLO_TIME
,
1798 Link
.IFLA_BR_MAX_AGE
,
1799 Link
.IFLA_BR_STP_STATE
,
1800 Link
.IFLA_BR_ROOT_PATH_COST
,
1801 Link
.IFLA_BR_MCAST_HASH_ELASTICITY
,
1802 Link
.IFLA_BR_MCAST_HASH_MAX
,
1803 Link
.IFLA_BR_MCAST_LAST_MEMBER_CNT
,
1804 Link
.IFLA_BR_MCAST_STARTUP_QUERY_CNT
):
1805 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1808 elif info_data_type
in (Link
.IFLA_BR_PRIORITY
,
1809 Link
.IFLA_BR_GROUP_FWD_MASK
,
1810 Link
.IFLA_BR_ROOT_PORT
,
1811 Link
.IFLA_BR_VLAN_DEFAULT_PVID
):
1812 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=H', sub_attr_data
[4:6])[0]
1814 elif info_data_type
== Link
.IFLA_BR_VLAN_PROTOCOL
:
1815 hex_value
= '0x%s' % sub_attr_data
[4:6].encode('hex')
1816 vlan_protocol
= Link
.ifla_vlan_protocol_dict
.get(int(hex_value
, base
=16))
1819 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = vlan_protocol
1821 self
.log
.warning('IFLA_VLAN_PROTOCOL: cannot decode vlan protocol %s' % hex_value
)
1824 elif info_data_type
in (Link
.IFLA_BR_MCAST_MEMBERSHIP_INTVL
,
1825 Link
.IFLA_BR_MCAST_QUERIER_INTVL
,
1826 Link
.IFLA_BR_MCAST_LAST_MEMBER_INTVL
,
1827 Link
.IFLA_BR_MCAST_MEMBERSHIP_INTVL
,
1828 Link
.IFLA_BR_MCAST_QUERIER_INTVL
,
1829 Link
.IFLA_BR_MCAST_QUERY_INTVL
,
1830 Link
.IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
,
1831 Link
.IFLA_BR_MCAST_STARTUP_QUERY_INTVL
):
1832 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=Q', sub_attr_data
[4:12])[0]
1835 elif info_data_type
in (Link
.IFLA_BR_VLAN_FILTERING
,
1836 Link
.IFLA_BR_TOPOLOGY_CHANGE
,
1837 Link
.IFLA_BR_TOPOLOGY_CHANGE_DETECTED
,
1838 Link
.IFLA_BR_MCAST_ROUTER
,
1839 Link
.IFLA_BR_MCAST_SNOOPING
,
1840 Link
.IFLA_BR_MCAST_QUERY_USE_IFADDR
,
1841 Link
.IFLA_BR_MCAST_QUERIER
,
1842 Link
.IFLA_BR_NF_CALL_IPTABLES
,
1843 Link
.IFLA_BR_NF_CALL_IP6TABLES
,
1844 Link
.IFLA_BR_NF_CALL_ARPTABLES
,
1845 Link
.IFLA_BR_VLAN_STATS_ENABLED
,
1846 Link
.IFLA_BR_MCAST_STATS_ENABLED
,
1847 Link
.IFLA_BR_MCAST_IGMP_VERSION
,
1848 Link
.IFLA_BR_MCAST_MLD_VERSION
):
1849 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=B', sub_attr_data
[4])[0]
1851 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_INFO_KIND bridge type %s (%d), length %d, padded to %d' %
1852 (parent_msg
.get_ifla_br_string(info_data_type
), info_data_type
, info_data_length
, info_data_end
))
1854 elif ifla_info_kind
== 'vrf':
1856 if info_data_type
in (Link
.IFLA_VRF_TABLE
,):
1857 self
.value
[Link
.IFLA_INFO_DATA
][info_data_type
] = unpack('=L', sub_attr_data
[4:8])[0]
1861 self
.log
.log(SYSLOG_EXTRA_DEBUG
, "Add support for decoding IFLA_INFO_KIND %s (%d), length %d, padded to %d" %
1862 (ifla_info_kind
, info_data_type
, info_data_length
, info_data_end
))
1864 except Exception as e
:
1865 self
.log
.debug('%s: attribute %s: %s'
1866 % (self
.value
[Link
.IFLA_INFO_KIND
],
1869 sub_attr_data
= sub_attr_data
[info_data_end
:]
1872 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_LINKINFO sub-attribute type %s (%d), length %d, padded to %d' %
1873 (parent_msg
.get_ifla_info_string(sub_attr_type
), sub_attr_type
, sub_attr_length
, sub_attr_end
))
1875 data
= data
[sub_attr_end
:]
1877 # self.log.info('IFLA_LINKINFO values %s' % pformat(self.value))
1879 def dump_lines(self
, dump_buffer
, line_number
, color
):
1880 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
1883 next_sub_attr_line
= 0
1884 sub_attr_line
= True
1886 for x
in xrange(1, self
.attr_end
/4):
1890 if line_number
== next_sub_attr_line
:
1891 sub_attr_line
= True
1894 sub_attr_line
= False
1896 (sub_attr_length
, sub_attr_type
) = unpack('=HH', self
.data
[start
:start
+4])
1897 sub_attr_end
= padded_length(sub_attr_length
)
1899 next_sub_attr_line
= line_number
+ (sub_attr_end
/4)
1901 if sub_attr_end
== sub_attr_length
:
1904 padded_to
= ' padded to %d, ' % sub_attr_end
1906 extra
= 'Nested Attribute - Length %s (%d)%s Type %s (%d) %s' % \
1907 (zfilled_hex(sub_attr_length
, 4), sub_attr_length
,
1909 zfilled_hex(sub_attr_type
, 4), sub_attr_type
,
1910 Link
.ifla_info_to_string
.get(sub_attr_type
))
1914 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], extra
))
1919 def get_pretty_value(self
, obj
=None):
1921 if obj
and callable(obj
):
1922 return obj(self
.value
)
1924 value_pretty
= self
.value
1925 ifla_info_kind
= self
.value
.get(Link
.IFLA_INFO_KIND
)
1926 ifla_info_slave_kind
= self
.value
.get(Link
.IFLA_INFO_SLAVE_KIND
)
1930 # We do this so we can print a more human readable dictionary
1931 # with the names of the nested keys instead of their numbers
1933 # Most of these are placeholders...we need to add support
1934 # for more human readable dictionaries for bond, bridge, etc
1935 kind_dict
[Link
.IFLA_INFO_DATA
] = {
1936 'bond': Link
.ifla_bond_to_string
,
1937 'vlan': Link
.ifla_vlan_to_string
,
1938 'vxlan': Link
.ifla_vxlan_to_string
,
1939 'bridge': Link
.ifla_br_to_string
,
1940 'macvlan': Link
.ifla_macvlan_to_string
1941 }.get(ifla_info_kind
, {})
1943 kind_dict
[Link
.IFLA_INFO_SLAVE_DATA
] = {
1944 'bridge': Link
.ifla_brport_to_string
,
1945 'bond': Link
.ifla_bond_slave_to_string
1946 }.get(ifla_info_slave_kind
, {})
1948 if ifla_info_kind
or ifla_info_slave_kind
:
1951 for (sub_key
, sub_value
) in self
.value
.iteritems():
1952 sub_key_pretty
= "(%2d) %s" % (sub_key
, Link
.ifla_info_to_string
.get(sub_key
, 'UNKNOWN'))
1953 sub_value_pretty
= sub_value
1955 if sub_key
in (Link
.IFLA_INFO_DATA
, Link
.IFLA_INFO_SLAVE_DATA
):
1956 kind_to_string_dict
= kind_dict
.get(sub_key
, {})
1957 sub_value_pretty
= {}
1959 for (sub_sub_key
, sub_sub_value
) in sub_value
.iteritems():
1960 sub_sub_key_pretty
= "(%2d) %s" % (sub_sub_key
, kind_to_string_dict
.get(sub_sub_key
, 'UNKNOWN'))
1961 sub_value_pretty
[sub_sub_key_pretty
] = sub_sub_value
1963 value_pretty
[sub_key_pretty
] = sub_value_pretty
1968 class AttributeIFLA_PROTINFO(Attribute
):
1970 IFLA_PROTINFO nested attributes.
1972 def __init__(self
, atype
, string
, family
, logger
):
1973 Attribute
.__init
__(self
, atype
, string
, logger
)
1974 self
.family
= family
1977 pack_layout
= [self
.HEADER_PACK
]
1978 payload
= [0, self
.atype | NLA_F_NESTED
]
1979 attr_length_index
= 0
1981 if self
.family
not in (AF_BRIDGE
,):
1982 raise Exception('Unsupported IFLA_PROTINFO family %d' % self
.family
)
1984 # For now this assumes that all data will be packed in the native endian
1985 # order (=). If a field is added that needs to be packed via network
1986 # order (>) then some smarts will need to be added to split the pack_layout
1987 # string at the >, split the payload and make the needed pack() calls.
1989 # Until we cross that bridge though we will keep things nice and simple and
1990 # pack everything via a single pack() call.
1991 for (sub_attr_type
, sub_attr_value
) in self
.value
.iteritems():
1992 sub_attr_pack_layout
= ['=', 'HH']
1993 sub_attr_payload
= [0, sub_attr_type
]
1994 sub_attr_length_index
= 0
1996 if self
.family
== AF_BRIDGE
:
1998 if sub_attr_type
in (Link
.IFLA_BRPORT_STATE
,
1999 Link
.IFLA_BRPORT_MODE
,
2000 Link
.IFLA_BRPORT_GUARD
,
2001 Link
.IFLA_BRPORT_PROTECT
,
2002 Link
.IFLA_BRPORT_FAST_LEAVE
,
2003 Link
.IFLA_BRPORT_LEARNING
,
2004 Link
.IFLA_BRPORT_UNICAST_FLOOD
,
2005 Link
.IFLA_BRPORT_PROXYARP
,
2006 Link
.IFLA_BRPORT_LEARNING_SYNC
,
2007 Link
.IFLA_BRPORT_PROXYARP_WIFI
,
2008 Link
.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
,
2009 Link
.IFLA_BRPORT_CONFIG_PENDING
,
2010 Link
.IFLA_BRPORT_FLUSH
,
2011 Link
.IFLA_BRPORT_MULTICAST_ROUTER
,
2012 Link
.IFLA_BRPORT_PEER_LINK
,
2013 Link
.IFLA_BRPORT_DUAL_LINK
,
2014 Link
.IFLA_BRPORT_ARP_SUPPRESS
,
2015 Link
.IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
):
2016 sub_attr_pack_layout
.append('B')
2017 sub_attr_payload
.append(sub_attr_value
)
2018 sub_attr_pack_layout
.extend('xxx')
2021 elif sub_attr_type
in (Link
.IFLA_BRPORT_PRIORITY
,
2022 Link
.IFLA_BRPORT_DESIGNATED_PORT
,
2023 Link
.IFLA_BRPORT_DESIGNATED_COST
,
2024 Link
.IFLA_BRPORT_ID
,
2025 Link
.IFLA_BRPORT_NO
):
2026 sub_attr_pack_layout
.append('H')
2027 sub_attr_payload
.append(sub_attr_value
)
2028 sub_attr_pack_layout
.extend('xx')
2031 elif sub_attr_type
in (Link
.IFLA_BRPORT_COST
,):
2032 sub_attr_pack_layout
.append('L')
2033 sub_attr_payload
.append(sub_attr_value
)
2036 elif sub_attr_type
in (Link
.IFLA_BRPORT_MESSAGE_AGE_TIMER
,
2037 Link
.IFLA_BRPORT_FORWARD_DELAY_TIMER
,
2038 Link
.IFLA_BRPORT_HOLD_TIMER
):
2039 sub_attr_pack_layout
.append('Q')
2040 sub_attr_payload
.append(sub_attr_value
)
2043 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for encoding IFLA_PROTINFO sub-attribute type %d' % sub_attr_type
)
2045 sub_attr_length
= calcsize(''.join(sub_attr_pack_layout
))
2046 sub_attr_payload
[sub_attr_length_index
] = sub_attr_length
2049 for x
in xrange(self
.pad_bytes_needed(sub_attr_length
)):
2050 sub_attr_pack_layout
.append('x')
2052 # The [1:] is to remove the leading = so that when we do the ''.join() later
2053 # we do not end up with an = in the middle of the pack layout string. There
2054 # will be an = at the beginning via self.HEADER_PACK
2055 sub_attr_pack_layout
= sub_attr_pack_layout
[1:]
2057 # Now extend the ovarall attribute pack_layout/payload to include this sub-attribute
2058 pack_layout
.extend(sub_attr_pack_layout
)
2059 payload
.extend(sub_attr_payload
)
2061 pack_layout
= ''.join(pack_layout
)
2063 # Fill in the length field
2064 length
= calcsize(pack_layout
)
2065 payload
[attr_length_index
] = length
2067 raw
= pack(pack_layout
, *payload
)
2068 raw
= self
.pad(length
, raw
)
2071 def decode(self
, parent_msg
, data
):
2073 value is a dictionary such as:
2075 Link.IFLA_BRPORT_STATE : 3,
2076 Link.IFLA_BRPORT_PRIORITY : 8
2077 Link.IFLA_BRPORT_COST : 2
2081 self
.decode_length_type(data
)
2084 data
= self
.data
[4:]
2087 (sub_attr_length
, sub_attr_type
) = unpack('=HH', data
[:4])
2088 sub_attr_end
= padded_length(sub_attr_length
)
2090 if not sub_attr_length
:
2091 self
.log
.error('parsed a zero length sub-attr')
2094 if self
.family
== AF_BRIDGE
:
2097 if sub_attr_type
in (Link
.IFLA_BRPORT_STATE
,
2098 Link
.IFLA_BRPORT_MODE
,
2099 Link
.IFLA_BRPORT_GUARD
,
2100 Link
.IFLA_BRPORT_PROTECT
,
2101 Link
.IFLA_BRPORT_FAST_LEAVE
,
2102 Link
.IFLA_BRPORT_LEARNING
,
2103 Link
.IFLA_BRPORT_UNICAST_FLOOD
,
2104 Link
.IFLA_BRPORT_PROXYARP
,
2105 Link
.IFLA_BRPORT_LEARNING_SYNC
,
2106 Link
.IFLA_BRPORT_PROXYARP_WIFI
,
2107 Link
.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
,
2108 Link
.IFLA_BRPORT_CONFIG_PENDING
,
2109 Link
.IFLA_BRPORT_FLUSH
,
2110 Link
.IFLA_BRPORT_MULTICAST_ROUTER
,
2111 Link
.IFLA_BRPORT_PEER_LINK
,
2112 Link
.IFLA_BRPORT_DUAL_LINK
,
2113 Link
.IFLA_BRPORT_ARP_SUPPRESS
,
2114 Link
.IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
):
2115 self
.value
[sub_attr_type
] = unpack('=B', data
[4])[0]
2118 elif sub_attr_type
in (Link
.IFLA_BRPORT_PRIORITY
,
2119 Link
.IFLA_BRPORT_DESIGNATED_PORT
,
2120 Link
.IFLA_BRPORT_DESIGNATED_COST
,
2121 Link
.IFLA_BRPORT_ID
,
2122 Link
.IFLA_BRPORT_NO
):
2123 self
.value
[sub_attr_type
] = unpack('=H', data
[4:6])[0]
2126 elif sub_attr_type
in (Link
.IFLA_BRPORT_COST
,):
2127 self
.value
[sub_attr_type
] = unpack('=L', data
[4:8])[0]
2130 elif sub_attr_type
in (Link
.IFLA_BRPORT_MESSAGE_AGE_TIMER
,
2131 Link
.IFLA_BRPORT_FORWARD_DELAY_TIMER
,
2132 Link
.IFLA_BRPORT_HOLD_TIMER
):
2133 self
.value
[sub_attr_type
] = unpack('=Q', data
[4:12])[0]
2136 self
.log
.log(SYSLOG_EXTRA_DEBUG
, 'Add support for decoding IFLA_PROTINFO sub-attribute type %s (%d), length %d, padded to %d' %
2137 (parent_msg
.get_ifla_brport_string(sub_attr_type
), sub_attr_type
, sub_attr_length
, sub_attr_end
))
2139 data
= data
[sub_attr_end
:]
2141 def dump_lines(self
, dump_buffer
, line_number
, color
):
2142 line_number
= self
.dump_first_line(dump_buffer
, line_number
, color
)
2145 next_sub_attr_line
= 0
2146 sub_attr_line
= True
2148 for x
in xrange(1, self
.attr_end
/4):
2152 if line_number
== next_sub_attr_line
:
2153 sub_attr_line
= True
2156 sub_attr_line
= False
2158 (sub_attr_length
, sub_attr_type
) = unpack('=HH', self
.data
[start
:start
+4])
2159 sub_attr_end
= padded_length(sub_attr_length
)
2161 next_sub_attr_line
= line_number
+ (sub_attr_end
/4)
2163 if sub_attr_end
== sub_attr_length
:
2166 padded_to
= ' padded to %d, ' % sub_attr_end
2168 extra
= 'Nested Attribute - Length %s (%d)%s Type %s (%d) %s' % \
2169 (zfilled_hex(sub_attr_length
, 4), sub_attr_length
,
2171 zfilled_hex(sub_attr_type
, 4), sub_attr_type
,
2172 Link
.ifla_brport_to_string
.get(sub_attr_type
))
2176 dump_buffer
.append(data_to_color_text(line_number
, color
, self
.data
[start
:end
], extra
))
2181 def get_pretty_value(self
, obj
=None):
2183 if obj
and callable(obj
):
2184 return obj(self
.value
)
2188 for (sub_key
, sub_value
) in self
.value
.iteritems():
2189 sub_key_pretty
= "(%2d) %s" % (sub_key
, Link
.ifla_brport_to_string
.get(sub_key
, 'UNKNOWN'))
2190 sub_value_pretty
= sub_value
2191 value_pretty
[sub_key_pretty
] = sub_value_pretty
2197 class NetlinkPacket(object):
2202 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
2203 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2205 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2207 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2209 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2210 | Process ID (PID) |
2211 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2214 header_PACK
= 'IHHII'
2215 header_LEN
= calcsize(header_PACK
)
2217 # Netlink packet types
2218 # /usr/include/linux/rtnetlink.h
2220 NLMSG_NOOP
: 'NLMSG_NOOP',
2221 NLMSG_ERROR
: 'NLMSG_ERROR',
2222 NLMSG_DONE
: 'NLMSG_DONE',
2223 NLMSG_OVERRUN
: 'NLMSG_OVERRUN',
2224 RTM_NEWLINK
: 'RTM_NEWLINK',
2225 RTM_DELLINK
: 'RTM_DELLINK',
2226 RTM_GETLINK
: 'RTM_GETLINK',
2227 RTM_SETLINK
: 'RTM_SETLINK',
2228 RTM_NEWADDR
: 'RTM_NEWADDR',
2229 RTM_DELADDR
: 'RTM_DELADDR',
2230 RTM_GETADDR
: 'RTM_GETADDR',
2231 RTM_NEWNEIGH
: 'RTM_NEWNEIGH',
2232 RTM_DELNEIGH
: 'RTM_DELNEIGH',
2233 RTM_GETNEIGH
: 'RTM_GETNEIGH',
2234 RTM_NEWROUTE
: 'RTM_NEWROUTE',
2235 RTM_DELROUTE
: 'RTM_DELROUTE',
2236 RTM_GETROUTE
: 'RTM_GETROUTE',
2237 RTM_NEWQDISC
: 'RTM_NEWQDISC',
2238 RTM_DELQDISC
: 'RTM_DELQDISC',
2239 RTM_GETQDISC
: 'RTM_GETQDISC',
2240 RTM_NEWNETCONF
: 'RTM_NEWNETCONF',
2241 RTM_GETNETCONF
: 'RTM_GETNETCONF'
2244 af_family_to_string
= {
2249 def __init__(self
, msgtype
, debug
, owner_logger
=None, use_color
=True):
2250 self
.msgtype
= msgtype
2251 self
.attributes
= {}
2252 self
.dump_buffer
= ['']
2253 self
.line_number
= 1
2256 self
.use_color
= use_color
2260 self
.log
= owner_logger
2265 return self
.get_type_string()
2267 def get_string(self
, to_string
, index
):
2269 Used to do lookups in all of the various FOO_to_string dictionaries
2270 but returns 'UNKNOWN' if the key is bogus
2272 if index
in to_string
:
2273 return to_string
[index
]
2276 def get_type_string(self
, msgtype
=None):
2278 msgtype
= self
.msgtype
2279 return self
.get_string(self
.type_to_string
, msgtype
)
2281 def get_flags_string(self
):
2284 for (flag
, flag_string
) in self
.flag_to_string
.iteritems():
2285 if self
.flags
& flag
:
2286 foo
.append(flag_string
)
2288 return ', '.join(foo
)
2290 def decode_packet(self
, length
, flags
, seq
, pid
, data
):
2291 self
.length
= length
2295 self
.header_data
= data
[0:self
.header_LEN
]
2296 self
.msg_data
= data
[self
.header_LEN
:length
]
2298 self
.decode_netlink_header()
2299 self
.decode_service_header()
2301 # NLMSG_ERROR is special case, it does not have attributes to decode
2302 if self
.msgtype
!= NLMSG_ERROR
:
2303 self
.decode_attributes()
2305 def get_netlink_header_flags_string(self
, msg_type
, flags
):
2308 if flags
& NLM_F_REQUEST
:
2309 foo
.append('NLM_F_REQUEST')
2311 if flags
& NLM_F_MULTI
:
2312 foo
.append('NLM_F_MULTI')
2314 if flags
& NLM_F_ACK
:
2315 foo
.append('NLM_F_ACK')
2317 if flags
& NLM_F_ECHO
:
2318 foo
.append('NLM_F_ECHO')
2320 # Modifiers to GET query
2321 if msg_type
in (RTM_GETLINK
, RTM_GETADDR
, RTM_GETNEIGH
, RTM_GETROUTE
, RTM_GETQDISC
, RTM_GETNETCONF
):
2322 if flags
& NLM_F_DUMP
:
2323 foo
.append('NLM_F_DUMP')
2325 if flags
& NLM_F_MATCH
:
2326 foo
.append('NLM_F_MATCH')
2328 if flags
& NLM_F_ROOT
:
2329 foo
.append('NLM_F_ROOT')
2331 if flags
& NLM_F_ATOMIC
:
2332 foo
.append('NLM_F_ATOMIC')
2334 # Modifiers to NEW query
2335 elif msg_type
in (RTM_NEWLINK
, RTM_NEWADDR
, RTM_NEWNEIGH
, RTM_NEWROUTE
, RTM_NEWQDISC
):
2336 if flags
& NLM_F_REPLACE
:
2337 foo
.append('NLM_F_REPLACE')
2339 if flags
& NLM_F_EXCL
:
2340 foo
.append('NLM_F_EXCL')
2342 if flags
& NLM_F_CREATE
:
2343 foo
.append('NLM_F_CREATE')
2345 if flags
& NLM_F_APPEND
:
2346 foo
.append('NLM_F_APPEND')
2348 return ', '.join(foo
)
2350 # When we first RXed the netlink message we had to decode the header to
2351 # determine what type of netlink message we were dealing with. So the
2352 # header has actually already been decoded...what we do here is
2353 # populate the dump_buffer lines with the header content.
2354 def decode_netlink_header(self
):
2359 header_data
= self
.header_data
2361 # Print the netlink header in red
2362 netlink_header_length
= 16
2363 color
= red
if self
.use_color
else None
2364 color_start
= "\033[%dm" % color
if color
else ""
2365 color_end
= "\033[0m" if color
else ""
2366 self
.dump_buffer
.append(" %sNetlink Header%s" % (color_start
, color_end
))
2368 for x
in range(0, netlink_header_length
/4):
2372 if self
.line_number
== 1:
2373 data
= unpack('=L', header_data
[start
:end
])[0]
2374 extra
= "Length %s (%d)" % (zfilled_hex(data
, 8), data
)
2376 elif self
.line_number
== 2:
2377 (data1
, data2
) = unpack('HH', header_data
[start
:end
])
2378 extra
= "Type %s (%d - %s), Flags %s (%s)" % \
2379 (zfilled_hex(data1
, 4), data1
, self
.get_type_string(data1
),
2380 zfilled_hex(data2
, 4), self
.get_netlink_header_flags_string(data1
, data2
))
2382 elif self
.line_number
== 3:
2383 data
= unpack('=L', header_data
[start
:end
])[0]
2384 extra
= "Sequence Number %s (%d)" % (zfilled_hex(data
, 8), data
)
2386 elif self
.line_number
== 4:
2387 data
= unpack('=L', header_data
[start
:end
])[0]
2388 extra
= "Process ID %s (%d)" % (zfilled_hex(data
, 8), data
)
2390 extra
= "Unexpected line number %d" % self
.line_number
2392 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, header_data
[start
:end
], extra
))
2393 self
.line_number
+= 1
2395 def decode_attributes(self
):
2397 Decode the attributes and populate the dump_buffer
2401 self
.dump_buffer
.append(" Attributes")
2402 color
= green
if self
.use_color
else None
2404 data
= self
.msg_data
[self
.LEN
:]
2407 (length
, attr_type
) = unpack('=HH', data
[:4])
2409 # If this is zero we will stay in this loop for forever
2411 self
.log
.error('Length is zero')
2414 if len(data
) < length
:
2415 self
.log
.error("Buffer underrun %d < %d" % (len(data
), length
))
2418 attr
= self
.add_attribute(attr_type
, None)
2420 # Find the end of 'data' for this attribute and decode our section
2421 # of 'data'. attributes are padded for alignment thus the attr_end.
2423 # How the attribute is decoded/unpacked is specific per AttributeXXXX class.
2424 attr_end
= padded_length(length
)
2425 attr
.decode(self
, data
[0:attr_end
])
2428 self
.line_number
= attr
.dump_lines(self
.dump_buffer
, self
.line_number
, color
)
2430 # Alternate back and forth between green and blue
2437 data
= data
[attr_end
:]
2439 def add_attribute(self
, attr_type
, value
):
2440 nested
= True if attr_type
& NLA_F_NESTED
else False
2441 net_byteorder
= True if attr_type
& NLA_F_NET_BYTEORDER
else False
2442 attr_type
= attr_type
& NLA_TYPE_MASK
2444 # Given an attr_type (say RTA_DST) find the type of AttributeXXXX class
2445 # that we will use to store this attribute...AttributeIPAddress in the
2447 if attr_type
in self
.attribute_to_class
:
2448 (attr_string
, attr_class
) = self
.attribute_to_class
[attr_type
]
2451 attribute_to_class is a dictionary where the key is the attr_type, it doesn't
2452 take the family into account. For now we'll handle this as a special case for
2453 MPLS but long term we may need to make key a tuple of the attr_type and family.
2455 if self
.msgtype
not in (RTM_NEWNETCONF
, RTM_GETNETCONF
) and attr_type
== Route
.RTA_DST
and self
.family
== AF_MPLS
:
2456 attr_string
= 'RTA_DST'
2457 attr_class
= AttributeMplsLabel
2460 attr_string
= "UNKNOWN_ATTRIBUTE_%d" % attr_type
2461 attr_class
= AttributeGeneric
2462 self
.log
.debug("Attribute %d is not defined in %s.attribute_to_class, assuming AttributeGeneric" %
2463 (attr_type
, self
.__class
__.__name
__))
2465 attr
= attr_class(attr_type
, attr_string
, self
.family
, self
.log
)
2467 attr
.set_value(value
)
2468 attr
.set_nested(nested
)
2469 attr
.set_net_byteorder(net_byteorder
)
2471 # self.attributes is a dictionary keyed by the attribute type where
2472 # the value is an instance of the corresponding AttributeXXXX class.
2473 self
.attributes
[attr_type
] = attr
2477 def get_attribute_value(self
, attr_type
, default
=None):
2478 if attr_type
not in self
.attributes
:
2481 return self
.attributes
[attr_type
].value
2483 def get_attr_string(self
, attr_type
):
2485 Example: If attr_type is Address.IFA_CACHEINFO return the string 'IFA_CACHEINFO'
2487 if attr_type
in self
.attribute_to_class
:
2488 (attr_string
, attr_class
) = self
.attribute_to_class
[attr_type
]
2490 return str(attr_type
)
2492 def build_message(self
, seq
, pid
):
2497 for attr
in self
.attributes
.itervalues():
2498 attrs
+= attr
.encode()
2500 self
.length
= self
.header_LEN
+ len(self
.body
) + len(attrs
)
2501 self
.header_data
= pack(self
.header_PACK
, self
.length
, self
.msgtype
, self
.flags
, self
.seq
, self
.pid
)
2502 self
.msg_data
= self
.body
+ attrs
2503 self
.message
= self
.header_data
+ self
.msg_data
2506 self
.decode_netlink_header()
2507 self
.decode_service_header()
2508 self
.decode_attributes()
2509 self
.dump("TXed %s, length %d, seq %d, pid %d, flags 0x%x (%s)" %
2510 (self
, self
.length
, self
.seq
, self
.pid
, self
.flags
,
2511 self
.get_netlink_header_flags_string(self
.msgtype
, self
.flags
)))
2513 def pretty_display_dict(self
, dic
, level
):
2514 for k
,v
in dic
.iteritems():
2515 if isinstance(v
, dict):
2516 self
.log
.debug(' '*level
+ str(k
) + ':')
2517 self
.pretty_display_dict(v
, level
+5)
2519 self
.log
.debug(' '*level
+ str(k
) + ': ' + str(v
))
2521 # Print the netlink message in hex. This is only used for debugging.
2522 def dump(self
, desc
=None):
2526 desc
= "RXed %s, length %d, seq %d, pid %d, flags 0x%x" % (self
, self
.length
, self
.seq
, self
.pid
, self
.flags
)
2528 for (attr_type
, attr_obj
) in self
.attributes
.iteritems():
2529 key_string
= "(%2d) %s" % (attr_type
, self
.get_attr_string(attr_type
))
2530 attr_string
[key_string
] = attr_obj
.get_pretty_value()
2533 self
.log
.debug("%s\n%s\n\nAttributes Summary\n%s\n" %
2534 (desc
, '\n'.join(self
.dump_buffer
), pformat(attr_string
)))
2536 # Assume if we are not allowing color output we also don't want embedded
2537 # newline characters in the output. Output each line individually.
2538 self
.log
.debug(desc
)
2539 for line
in self
.dump_buffer
:
2540 self
.log
.debug(line
)
2542 self
.log
.debug("Attributes Summary")
2543 self
.pretty_display_dict(attr_string
, 1)
2546 class Address(NetlinkPacket
):
2550 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
2551 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2552 | Family | Length | Flags | Scope |
2553 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2555 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2558 # Address attributes
2559 # /usr/include/linux/if_addr.h
2564 IFA_BROADCAST
= 0x04
2566 IFA_CACHEINFO
= 0x06
2567 IFA_MULTICAST
= 0x07
2570 attribute_to_class
= {
2571 IFA_UNSPEC
: ('IFA_UNSPEC', AttributeGeneric
),
2572 IFA_ADDRESS
: ('IFA_ADDRESS', AttributeIPAddress
),
2573 IFA_LOCAL
: ('IFA_LOCAL', AttributeIPAddress
),
2574 IFA_LABEL
: ('IFA_LABEL', AttributeString
),
2575 IFA_BROADCAST
: ('IFA_BROADCAST', AttributeIPAddress
),
2576 IFA_ANYCAST
: ('IFA_ANYCAST', AttributeIPAddress
),
2577 IFA_CACHEINFO
: ('IFA_CACHEINFO', AttributeGeneric
),
2578 IFA_MULTICAST
: ('IFA_MULTICAST', AttributeIPAddress
),
2579 IFA_FLAGS
: ('IFA_FLAGS', AttributeGeneric
)
2583 # /usr/include/linux/if_addr.h
2584 IFA_F_SECONDARY
= 0x01
2586 IFA_F_OPTIMISTIC
= 0x04
2587 IFA_F_DADFAILED
= 0x08
2588 IFA_F_HOMEADDRESS
= 0x10
2589 IFA_F_DEPRECATED
= 0x20
2590 IFA_F_TENTATIVE
= 0x40
2591 IFA_F_PERMANENT
= 0x80
2594 IFA_F_SECONDARY
: 'IFA_F_SECONDARY',
2595 IFA_F_NODAD
: 'IFA_F_NODAD',
2596 IFA_F_OPTIMISTIC
: 'IFA_F_OPTIMISTIC',
2597 IFA_F_DADFAILED
: 'IFA_F_DADFAILED',
2598 IFA_F_HOMEADDRESS
: 'IFA_F_HOMEADDRESS',
2599 IFA_F_DEPRECATED
: 'IFA_F_DEPRECATED',
2600 IFA_F_TENTATIVE
: 'IFA_F_TENTATIVE',
2601 IFA_F_PERMANENT
: 'IFA_F_PERMANENT'
2604 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
2605 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
2607 self
.LEN
= calcsize(self
.PACK
)
2609 def decode_service_header(self
):
2611 # Nothing to do if the message did not contain a service header
2612 if self
.length
== self
.header_LEN
:
2615 (self
.family
, self
.prefixlen
, self
.flags
, self
.scope
,
2617 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
2620 color
= yellow
if self
.use_color
else None
2621 color_start
= "\033[%dm" % color
if color
else ""
2622 color_end
= "\033[0m" if color
else ""
2623 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
2625 for x
in range(0, self
.LEN
/4):
2626 if self
.line_number
== 5:
2627 extra
= "Family %s (%s:%d), Length %s (%d), Flags %s, Scope %s (%d)" % \
2628 (zfilled_hex(self
.family
, 2), get_family_str(self
.family
), self
.family
,
2629 zfilled_hex(self
.prefixlen
, 2), self
.prefixlen
,
2630 zfilled_hex(self
.flags
, 2),
2631 zfilled_hex(self
.scope
, 2), self
.scope
)
2632 elif self
.line_number
== 6:
2633 extra
= "Interface Index %s (%d)" % (zfilled_hex(self
.ifindex
, 8), self
.ifindex
)
2635 extra
= "Unexpected line number %d" % self
.line_number
2639 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
2640 self
.line_number
+= 1
2643 class Error(NetlinkPacket
):
2646 # /include/netlink/errno.h
2657 NLE_OPNOTSUPP
= 0x0A
2658 NLE_AF_NOSUPPORT
= 0x0B
2659 NLE_OBJ_NOTFOUND
= 0x0C
2661 NLE_MISSING_ATTR
= 0x0E
2662 NLE_AF_MISMATCH
= 0x0F
2663 NLE_SEQ_MISMATCH
= 0x10
2664 NLE_MSG_OVERFLOW
= 0x11
2665 NLE_MSG_TRUNC
= 0x12
2667 NLE_SRCRT_NOSUPPORT
= 0x14
2668 NLE_MSG_TOOSHORT
= 0x15
2669 NLE_MSGTYPE_NOSUPPORT
= 0x16
2670 NLE_OBJ_MISMATCH
= 0x17
2673 NLE_PROTO_MISMATCH
= 0x1A
2676 NLE_PKTLOC_FILE
= 0x1D
2677 NLE_PARSE_ERR
= 0x1E
2679 NLE_IMMUTABLE
= 0x20
2680 NLE_DUMP_INTR
= 0x21
2683 NLE_SUCCESS
: 'NLE_SUCCESS',
2684 NLE_FAILURE
: 'NLE_FAILURE',
2685 NLE_INTR
: 'NLE_INTR',
2686 NLE_BAD_SOCK
: 'NLE_BAD_SOCK',
2687 NLE_AGAIN
: 'NLE_AGAIN',
2688 NLE_NOMEM
: 'NLE_NOMEM',
2689 NLE_EXIST
: 'NLE_EXIST',
2690 NLE_INVAL
: 'NLE_INVAL',
2691 NLE_RANGE
: 'NLE_RANGE',
2692 NLE_MSGSIZE
: 'NLE_MSGSIZE',
2693 NLE_OPNOTSUPP
: 'NLE_OPNOTSUPP',
2694 NLE_AF_NOSUPPORT
: 'NLE_AF_NOSUPPORT',
2695 NLE_OBJ_NOTFOUND
: 'NLE_OBJ_NOTFOUND',
2696 NLE_NOATTR
: 'NLE_NOATTR',
2697 NLE_MISSING_ATTR
: 'NLE_MISSING_ATTR',
2698 NLE_AF_MISMATCH
: 'NLE_AF_MISMATCH',
2699 NLE_SEQ_MISMATCH
: 'NLE_SEQ_MISMATCH',
2700 NLE_MSG_OVERFLOW
: 'NLE_MSG_OVERFLOW',
2701 NLE_MSG_TRUNC
: 'NLE_MSG_TRUNC',
2702 NLE_NOADDR
: 'NLE_NOADDR',
2703 NLE_SRCRT_NOSUPPORT
: 'NLE_SRCRT_NOSUPPORT',
2704 NLE_MSG_TOOSHORT
: 'NLE_MSG_TOOSHORT',
2705 NLE_MSGTYPE_NOSUPPORT
: 'NLE_MSGTYPE_NOSUPPORT',
2706 NLE_OBJ_MISMATCH
: 'NLE_OBJ_MISMATCH',
2707 NLE_NOCACHE
: 'NLE_NOCACHE',
2708 NLE_BUSY
: 'NLE_BUSY',
2709 NLE_PROTO_MISMATCH
: 'NLE_PROTO_MISMATCH',
2710 NLE_NOACCESS
: 'NLE_NOACCESS',
2711 NLE_PERM
: 'NLE_PERM',
2712 NLE_PKTLOC_FILE
: 'NLE_PKTLOC_FILE',
2713 NLE_PARSE_ERR
: 'NLE_PARSE_ERR',
2714 NLE_NODEV
: 'NLE_NODEV',
2715 NLE_IMMUTABLE
: 'NLE_IMMUTABLE',
2716 NLE_DUMP_INTR
: 'NLE_DUMP_INTR'
2719 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
2720 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
2721 self
.PACK
= '=iLHHLL'
2722 self
.LEN
= calcsize(self
.PACK
)
2724 def decode_service_header(self
):
2726 # Nothing to do if the message did not contain a service header
2727 if self
.length
== self
.header_LEN
:
2730 (self
.negative_errno
, self
.bad_msg_len
, self
.bad_msg_type
,
2731 self
.bad_msg_flag
, self
.bad_msg_seq
, self
.bad_msg_pid
) =\
2732 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
2735 color
= yellow
if self
.use_color
else None
2736 color_start
= "\033[%dm" % color
if color
else ""
2737 color_end
= "\033[0m" if color
else ""
2738 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
2740 for x
in range(0, self
.LEN
/4):
2742 if self
.line_number
== 5:
2743 extra
= "Error Number %s is %s" % (self
.negative_errno
, self
.error_to_string
.get(abs(self
.negative_errno
)))
2744 # zfilled_hex(self.negative_errno, 2)
2746 elif self
.line_number
== 6:
2747 extra
= "Length %s (%d)" % (zfilled_hex(self
.bad_msg_len
, 8), self
.bad_msg_len
)
2749 elif self
.line_number
== 7:
2750 extra
= "Type %s (%d - %s), Flags %s (%s)" % \
2751 (zfilled_hex(self
.bad_msg_type
, 4), self
.bad_msg_type
, self
.get_type_string(self
.bad_msg_type
),
2752 zfilled_hex(self
.bad_msg_flag
, 4), self
.get_netlink_header_flags_string(self
.bad_msg_type
, self
.bad_msg_flag
))
2754 elif self
.line_number
== 8:
2755 extra
= "Sequence Number %s (%d)" % (zfilled_hex(self
.bad_msg_seq
, 8), self
.bad_msg_seq
)
2757 elif self
.line_number
== 9:
2758 extra
= "Process ID %s (%d)" % (zfilled_hex(self
.bad_msg_pid
, 8), self
.bad_msg_pid
)
2761 extra
= "Unexpected line number %d" % self
.line_number
2765 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
2766 self
.line_number
+= 1
2769 class Link(NetlinkPacket
):
2774 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
2775 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2776 | Family | Reserved | Device Type |
2777 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2779 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2781 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2783 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2787 # /usr/include/linux/if_link.h
2807 IFLA_NET_NS_PID
= 19
2810 IFLA_VFINFO_LIST
= 22
2818 IFLA_PROMISCUITY
= 30
2819 IFLA_NUM_TX_QUEUES
= 31
2820 IFLA_NUM_RX_QUEUES
= 32
2822 IFLA_PHYS_PORT_ID
= 34
2823 IFLA_CARRIER_CHANGES
= 35
2824 IFLA_PHYS_SWITCH_ID
= 36
2825 IFLA_LINK_NETNSID
= 37
2826 IFLA_PHYS_PORT_NAME
= 38
2827 IFLA_PROTO_DOWN
= 39
2828 IFLA_GSO_MAX_SEGS
= 40
2829 IFLA_GSO_MAX_SIZE
= 41
2831 attribute_to_class
= {
2832 IFLA_UNSPEC
: ('IFLA_UNSPEC', AttributeGeneric
),
2833 IFLA_ADDRESS
: ('IFLA_ADDRESS', AttributeMACAddress
),
2834 IFLA_BROADCAST
: ('IFLA_BROADCAST', AttributeMACAddress
),
2835 IFLA_IFNAME
: ('IFLA_IFNAME', AttributeStringInterfaceName
),
2836 IFLA_MTU
: ('IFLA_MTU', AttributeFourByteValue
),
2837 IFLA_LINK
: ('IFLA_LINK', AttributeFourByteValue
),
2838 IFLA_QDISC
: ('IFLA_QDISC', AttributeString
),
2839 IFLA_STATS
: ('IFLA_STATS', AttributeGeneric
),
2840 IFLA_COST
: ('IFLA_COST', AttributeGeneric
),
2841 IFLA_PRIORITY
: ('IFLA_PRIORITY', AttributeGeneric
),
2842 IFLA_MASTER
: ('IFLA_MASTER', AttributeFourByteValue
),
2843 IFLA_WIRELESS
: ('IFLA_WIRELESS', AttributeGeneric
),
2844 IFLA_PROTINFO
: ('IFLA_PROTINFO', AttributeIFLA_PROTINFO
),
2845 IFLA_TXQLEN
: ('IFLA_TXQLEN', AttributeFourByteValue
),
2846 IFLA_MAP
: ('IFLA_MAP', AttributeGeneric
),
2847 IFLA_WEIGHT
: ('IFLA_WEIGHT', AttributeGeneric
),
2848 IFLA_OPERSTATE
: ('IFLA_OPERSTATE', AttributeOneByteValue
),
2849 IFLA_LINKMODE
: ('IFLA_LINKMODE', AttributeOneByteValue
),
2850 IFLA_LINKINFO
: ('IFLA_LINKINFO', AttributeIFLA_LINKINFO
),
2851 IFLA_NET_NS_PID
: ('IFLA_NET_NS_PID', AttributeGeneric
),
2852 IFLA_IFALIAS
: ('IFLA_IFALIAS', AttributeGeneric
),
2853 IFLA_NUM_VF
: ('IFLA_NUM_VF', AttributeGeneric
),
2854 IFLA_VFINFO_LIST
: ('IFLA_VFINFO_LIST', AttributeGeneric
),
2855 IFLA_STATS64
: ('IFLA_STATS64', AttributeGeneric
),
2856 IFLA_VF_PORTS
: ('IFLA_VF_PORTS', AttributeGeneric
),
2857 IFLA_PORT_SELF
: ('IFLA_PORT_SELF', AttributeGeneric
),
2858 IFLA_AF_SPEC
: ('IFLA_AF_SPEC', AttributeIFLA_AF_SPEC
),
2859 IFLA_GROUP
: ('IFLA_GROUP', AttributeFourByteValue
),
2860 IFLA_NET_NS_FD
: ('IFLA_NET_NS_FD', AttributeGeneric
),
2861 IFLA_EXT_MASK
: ('IFLA_EXT_MASK', AttributeFourByteValue
),
2862 IFLA_PROMISCUITY
: ('IFLA_PROMISCUITY', AttributeGeneric
),
2863 IFLA_NUM_TX_QUEUES
: ('IFLA_NUM_TX_QUEUES', AttributeGeneric
),
2864 IFLA_NUM_RX_QUEUES
: ('IFLA_NUM_RX_QUEUES', AttributeGeneric
),
2865 IFLA_CARRIER
: ('IFLA_CARRIER', AttributeGeneric
),
2866 IFLA_PHYS_PORT_ID
: ('IFLA_PHYS_PORT_ID', AttributeGeneric
),
2867 IFLA_CARRIER_CHANGES
: ('IFLA_CARRIER_CHANGES', AttributeGeneric
),
2868 IFLA_PHYS_SWITCH_ID
: ('IFLA_PHYS_SWITCH_ID', AttributeGeneric
),
2869 IFLA_LINK_NETNSID
: ('IFLA_LINK_NETNSID', AttributeGeneric
),
2870 IFLA_PHYS_PORT_NAME
: ('IFLA_PHYS_PORT_NAME', AttributeGeneric
),
2871 IFLA_PROTO_DOWN
: ('IFLA_PROTO_DOWN', AttributeOneByteValue
),
2872 IFLA_GSO_MAX_SEGS
: ('IFLA_GSO_MAX_SEGS', AttributeFourByteValue
),
2873 IFLA_GSO_MAX_SIZE
: ('IFLA_GSO_MAX_SIZE', AttributeFourByteValue
)
2877 # /usr/include/linux/if.h
2878 IFF_UP
= 0x0001 # Interface is administratively up.
2879 IFF_BROADCAST
= 0x0002 # Valid broadcast address set.
2880 IFF_DEBUG
= 0x0004 # Internal debugging flag.
2881 IFF_LOOPBACK
= 0x0008 # Interface is a loopback interface.
2882 IFF_POINTOPOINT
= 0x0010 # Interface is a point-to-point link.
2883 IFF_NOTRAILERS
= 0x0020 # Avoid use of trailers.
2884 IFF_RUNNING
= 0x0040 # Interface is operationally up.
2885 IFF_NOARP
= 0x0080 # No ARP protocol needed for this interface.
2886 IFF_PROMISC
= 0x0100 # Interface is in promiscuous mode.
2887 IFF_ALLMULTI
= 0x0200 # Receive all multicast packets.
2888 IFF_MASTER
= 0x0400 # Master of a load balancing bundle.
2889 IFF_SLAVE
= 0x0800 # Slave of a load balancing bundle.
2890 IFF_MULTICAST
= 0x1000 # Supports multicast.
2891 IFF_PORTSEL
= 0x2000 # Is able to select media type via ifmap.
2892 IFF_AUTOMEDIA
= 0x4000 # Auto media selection active.
2893 IFF_DYNAMIC
= 0x8000 # Interface was dynamically created.
2894 IFF_LOWER_UP
= 0x10000 # driver signals L1 up
2895 IFF_DORMANT
= 0x20000 # driver signals dormant
2896 IFF_ECHO
= 0x40000 # echo sent packet
2897 IFF_PROTO_DOWN
= 0x1000000 # protocol is down on the interface
2901 IFF_BROADCAST
: 'IFF_BROADCAST',
2902 IFF_DEBUG
: 'IFF_DEBUG',
2903 IFF_LOOPBACK
: 'IFF_LOOPBACK',
2904 IFF_POINTOPOINT
: 'IFF_POINTOPOINT',
2905 IFF_NOTRAILERS
: 'IFF_NOTRAILERS',
2906 IFF_RUNNING
: 'IFF_RUNNING',
2907 IFF_NOARP
: 'IFF_NOARP',
2908 IFF_PROMISC
: 'IFF_PROMISC',
2909 IFF_ALLMULTI
: 'IFF_ALLMULTI',
2910 IFF_MASTER
: 'IFF_MASTER',
2911 IFF_SLAVE
: 'IFF_SLAVE',
2912 IFF_MULTICAST
: 'IFF_MULTICAST',
2913 IFF_PORTSEL
: 'IFF_PORTSEL',
2914 IFF_AUTOMEDIA
: 'IFF_AUTOMEDIA',
2915 IFF_DYNAMIC
: 'IFF_DYNAMIC',
2916 IFF_LOWER_UP
: 'IFF_LOWER_UP',
2917 IFF_DORMANT
: 'IFF_DORMANT',
2918 IFF_ECHO
: 'IFF_ECHO',
2919 IFF_PROTO_DOWN
: 'IFF_PROTO_DOWN'
2922 # RFC 2863 operational status
2924 IF_OPER_NOTPRESENT
= 1
2926 IF_OPER_LOWERLAYERDOWN
= 3
2932 IF_OPER_UNKNOWN
: 'IF_OPER_UNKNOWN',
2933 IF_OPER_NOTPRESENT
: 'IF_OPER_NOTPRESENT',
2934 IF_OPER_DOWN
: 'IF_OPER_DOWN',
2935 IF_OPER_LOWERLAYERDOWN
: 'IF_OPER_LOWERLAYERDOWN',
2936 IF_OPER_TESTING
: 'IF_OPER_TESTING',
2937 IF_OPER_DORMANT
: 'IF_OPER_DORMANT',
2938 IF_OPER_UP
: 'IF_OPER_UP'
2942 # /usr/include/linux/if_arp.h
2943 # ARP protocol HARDWARE identifiers
2944 ARPHRD_NETROM
= 0 # from KA9Q: NET/ROM pseudo
2945 ARPHRD_ETHER
= 1 # Ethernet 10Mbps
2946 ARPHRD_EETHER
= 2 # Experimental Ethernet
2947 ARPHRD_AX25
= 3 # AX.25 Level 2
2948 ARPHRD_PRONET
= 4 # PROnet token ring
2949 ARPHRD_CHAOS
= 5 # Chaosnet
2950 ARPHRD_IEEE802
= 6 # IEEE 802.2 Ethernet/TR/TB
2951 ARPHRD_ARCNET
= 7 # ARCnet
2952 ARPHRD_APPLETLK
= 8 # APPLEtalk
2953 ARPHRD_DLCI
= 15 # Frame Relay DLCI
2954 ARPHRD_ATM
= 19 # ATM
2955 ARPHRD_METRICOM
= 23 # Metricom STRIP (new IANA id)
2956 ARPHRD_IEEE1394
= 24 # IEEE 1394 IPv4 - RFC 2734
2957 ARPHRD_EUI64
= 27 # EUI-64
2958 ARPHRD_INFINIBAND
= 32 # InfiniBand
2959 # Dummy types for non ARP hardware
2964 ARPHRD_RSRVD
= 260 # Notional KISS type
2967 ARPHRD_X25
= 271 # CCITT X.25
2968 ARPHRD_HWX25
= 272 # Boards with X.25 in firmware
2969 ARPHRD_CAN
= 280 # Controller Area Network
2971 ARPHRD_CISCO
= 513 # Cisco HDLC
2972 ARPHRD_HDLC
= ARPHRD_CISCO
2973 ARPHRD_LAPB
= 516 # LAPB
2974 ARPHRD_DDCMP
= 517 # Digital's DDCMP protocol
2975 ARPHRD_RAWHDLC
= 518 # Raw HDLC
2976 ARPHRD_TUNNEL
= 768 # IPIP tunnel
2977 ARPHRD_TUNNEL6
= 769 # IP6IP6 tunnel
2978 ARPHRD_FRAD
= 770 # Frame Relay Access Device
2979 ARPHRD_SKIP
= 771 # SKIP vif
2980 ARPHRD_LOOPBACK
= 772 # Loopback device
2981 ARPHRD_LOCALTLK
= 773 # Localtalk device
2982 ARPHRD_FDDI
= 774 # Fiber Distributed Data Interface
2983 ARPHRD_BIF
= 775 # AP1000 BIF
2984 ARPHRD_SIT
= 776 # sit0 device - IPv6-in-IPv4
2985 ARPHRD_IPDDP
= 777 # IP over DDP tunneller
2986 ARPHRD_IPGRE
= 778 # GRE over IP
2987 ARPHRD_PIMREG
= 779 # PIMSM register interface
2988 ARPHRD_HIPPI
= 780 # High Performance Parallel Interface
2989 ARPHRD_ASH
= 781 # Nexus 64Mbps Ash
2990 ARPHRD_ECONET
= 782 # Acorn Econet
2991 ARPHRD_IRDA
= 783 # Linux-IrDA
2992 ARPHRD_FCPP
= 784 # Point to point fibrechannel
2993 ARPHRD_FCAL
= 785 # Fibrechannel arbitrated loop
2994 ARPHRD_FCPL
= 786 # Fibrechannel public loop
2995 ARPHRD_FCFABRIC
= 787 # Fibrechannel fabric
2996 # 787->799 reserved for fibrechannel media types
2997 ARPHRD_IEEE802_TR
= 800 # Magic type ident for TR
2998 ARPHRD_IEEE80211
= 801 # IEEE 802.11
2999 ARPHRD_IEEE80211_PRISM
= 802 # IEEE 802.11 + Prism2 header
3000 ARPHRD_IEEE80211_RADIOTAP
= 803 # IEEE 802.11 + radiotap header
3001 ARPHRD_IEEE802154
= 804
3002 ARPHRD_PHONET
= 820 # PhoNet media type
3003 ARPHRD_PHONET_PIPE
= 821 # PhoNet pipe header
3004 ARPHRD_CAIF
= 822 # CAIF media type
3005 ARPHRD_VOID
= 0xFFFF # Void type, nothing is known
3006 ARPHRD_NONE
= 0xFFFE # zero header length
3008 link_type_to_string
= {
3009 ARPHRD_NETROM
: 'ARPHRD_NETROM',
3010 ARPHRD_ETHER
: 'ARPHRD_ETHER',
3011 ARPHRD_EETHER
: 'ARPHRD_EETHER',
3012 ARPHRD_AX25
: 'ARPHRD_AX25',
3013 ARPHRD_PRONET
: 'ARPHRD_PRONET',
3014 ARPHRD_CHAOS
: 'ARPHRD_CHAOS',
3015 ARPHRD_IEEE802
: 'ARPHRD_IEEE802',
3016 ARPHRD_ARCNET
: 'ARPHRD_ARCNET',
3017 ARPHRD_APPLETLK
: 'ARPHRD_APPLETLK',
3018 ARPHRD_DLCI
: 'ARPHRD_DLCI',
3019 ARPHRD_ATM
: 'ARPHRD_ATM',
3020 ARPHRD_METRICOM
: 'ARPHRD_METRICOM',
3021 ARPHRD_IEEE1394
: 'ARPHRD_IEEE1394',
3022 ARPHRD_EUI64
: 'ARPHRD_EUI64',
3023 ARPHRD_INFINIBAND
: 'ARPHRD_INFINIBAND',
3024 ARPHRD_SLIP
: 'ARPHRD_SLIP',
3025 ARPHRD_CSLIP
: 'ARPHRD_CSLIP',
3026 ARPHRD_SLIP6
: 'ARPHRD_SLIP6',
3027 ARPHRD_CSLIP6
: 'ARPHRD_CSLIP6',
3028 ARPHRD_RSRVD
: 'ARPHRD_RSRVD',
3029 ARPHRD_ADAPT
: 'ARPHRD_ADAPT',
3030 ARPHRD_ROSE
: 'ARPHRD_ROSE',
3031 ARPHRD_X25
: 'ARPHRD_X25',
3032 ARPHRD_HWX25
: 'ARPHRD_HWX25',
3033 ARPHRD_CAN
: 'ARPHRD_CAN',
3034 ARPHRD_PPP
: 'ARPHRD_PPP',
3035 ARPHRD_CISCO
: 'ARPHRD_CISCO',
3036 ARPHRD_HDLC
: 'ARPHRD_HDLC',
3037 ARPHRD_LAPB
: 'ARPHRD_LAPB',
3038 ARPHRD_DDCMP
: 'ARPHRD_DDCMP',
3039 ARPHRD_RAWHDLC
: 'ARPHRD_RAWHDLC',
3040 ARPHRD_TUNNEL
: 'ARPHRD_TUNNEL',
3041 ARPHRD_TUNNEL6
: 'ARPHRD_TUNNEL6',
3042 ARPHRD_FRAD
: 'ARPHRD_FRAD',
3043 ARPHRD_SKIP
: 'ARPHRD_SKIP',
3044 ARPHRD_LOOPBACK
: 'ARPHRD_LOOPBACK',
3045 ARPHRD_LOCALTLK
: 'ARPHRD_LOCALTLK',
3046 ARPHRD_FDDI
: 'ARPHRD_FDDI',
3047 ARPHRD_BIF
: 'ARPHRD_BIF',
3048 ARPHRD_SIT
: 'ARPHRD_SIT',
3049 ARPHRD_IPDDP
: 'ARPHRD_IPDDP',
3050 ARPHRD_IPGRE
: 'ARPHRD_IPGRE',
3051 ARPHRD_PIMREG
: 'ARPHRD_PIMREG',
3052 ARPHRD_HIPPI
: 'ARPHRD_HIPPI',
3053 ARPHRD_ASH
: 'ARPHRD_ASH',
3054 ARPHRD_ECONET
: 'ARPHRD_ECONET',
3055 ARPHRD_IRDA
: 'ARPHRD_IRDA',
3056 ARPHRD_FCPP
: 'ARPHRD_FCPP',
3057 ARPHRD_FCAL
: 'ARPHRD_FCAL',
3058 ARPHRD_FCPL
: 'ARPHRD_FCPL',
3059 ARPHRD_FCFABRIC
: 'ARPHRD_FCFABRIC',
3060 ARPHRD_IEEE802_TR
: 'ARPHRD_IEEE802_TR',
3061 ARPHRD_IEEE80211
: 'ARPHRD_IEEE80211',
3062 ARPHRD_IEEE80211_PRISM
: 'ARPHRD_IEEE80211_PRISM',
3063 ARPHRD_IEEE80211_RADIOTAP
: 'ARPHRD_IEEE80211_RADIOTAP',
3064 ARPHRD_IEEE802154
: 'ARPHRD_IEEE802154',
3065 ARPHRD_PHONET
: 'ARPHRD_PHONET',
3066 ARPHRD_PHONET_PIPE
: 'ARPHRD_PHONET_PIPE',
3067 ARPHRD_CAIF
: 'ARPHRD_CAIF',
3068 ARPHRD_VOID
: 'ARPHRD_VOID',
3069 ARPHRD_NONE
: 'ARPHRD_NONE'
3072 # =========================================
3073 # IFLA_LINKINFO attributes
3074 # =========================================
3075 IFLA_INFO_UNSPEC
= 0
3078 IFLA_INFO_XSTATS
= 3
3079 IFLA_INFO_SLAVE_KIND
= 4
3080 IFLA_INFO_SLAVE_DATA
= 5
3083 ifla_info_to_string
= {
3084 IFLA_INFO_UNSPEC
: 'IFLA_INFO_UNSPEC',
3085 IFLA_INFO_KIND
: 'IFLA_INFO_KIND',
3086 IFLA_INFO_DATA
: 'IFLA_INFO_DATA',
3087 IFLA_INFO_XSTATS
: 'IFLA_INFO_XSTATS',
3088 IFLA_INFO_SLAVE_KIND
: 'IFLA_INFO_SLAVE_KIND',
3089 IFLA_INFO_SLAVE_DATA
: 'IFLA_INFO_SLAVE_DATA',
3090 IFLA_INFO_MAX
: 'IFLA_INFO_MAX'
3093 # =========================================
3094 # IFLA_INFO_DATA attributes for vlan
3095 # =========================================
3096 IFLA_VLAN_UNSPEC
= 0
3099 IFLA_VLAN_EGRESS_QOS
= 3
3100 IFLA_VLAN_INGRESS_QOS
= 4
3101 IFLA_VLAN_PROTOCOL
= 5
3103 ifla_vlan_to_string
= {
3104 IFLA_VLAN_UNSPEC
: 'IFLA_VLAN_UNSPEC',
3105 IFLA_VLAN_ID
: 'IFLA_VLAN_ID',
3106 IFLA_VLAN_FLAGS
: 'IFLA_VLAN_FLAGS',
3107 IFLA_VLAN_EGRESS_QOS
: 'IFLA_VLAN_EGRESS_QOS',
3108 IFLA_VLAN_INGRESS_QOS
: 'IFLA_VLAN_INGRESS_QOS',
3109 IFLA_VLAN_PROTOCOL
: 'IFLA_VLAN_PROTOCOL'
3112 ifla_vlan_protocol_dict
= {
3125 # =========================================
3126 # IFLA_INFO_DATA attributes for macvlan
3127 # =========================================
3128 IFLA_MACVLAN_UNSPEC
= 0
3129 IFLA_MACVLAN_MODE
= 1
3131 ifla_macvlan_to_string
= {
3132 IFLA_MACVLAN_UNSPEC
: 'IFLA_MACVLAN_UNSPEC',
3133 IFLA_MACVLAN_MODE
: 'IFLA_MACVLAN_MODE'
3137 MACVLAN_MODE_PRIVATE
= 1
3138 MACVLAN_MODE_VEPA
= 2
3139 MACVLAN_MODE_BRIDGE
= 3
3140 MACVLAN_MODE_PASSTHRU
= 4
3142 macvlan_mode_to_string
= {
3143 MACVLAN_MODE_PRIVATE
: 'MACVLAN_MODE_PRIVATE',
3144 MACVLAN_MODE_VEPA
: 'MACVLAN_MODE_VEPA',
3145 MACVLAN_MODE_BRIDGE
: 'MACVLAN_MODE_BRIDGE',
3146 MACVLAN_MODE_PASSTHRU
: 'MACVLAN_MODE_PASSTHRU'
3149 # =========================================
3150 # IFLA_INFO_DATA attributes for vxlan
3151 # =========================================
3152 IFLA_VXLAN_UNSPEC
= 0
3154 IFLA_VXLAN_GROUP
= 2
3156 IFLA_VXLAN_LOCAL
= 4
3159 IFLA_VXLAN_LEARNING
= 7
3160 IFLA_VXLAN_AGEING
= 8
3161 IFLA_VXLAN_LIMIT
= 9
3162 IFLA_VXLAN_PORT_RANGE
= 10
3163 IFLA_VXLAN_PROXY
= 11
3165 IFLA_VXLAN_L2MISS
= 13
3166 IFLA_VXLAN_L3MISS
= 14
3167 IFLA_VXLAN_PORT
= 15
3168 IFLA_VXLAN_GROUP6
= 16
3169 IFLA_VXLAN_LOCAL6
= 17
3170 IFLA_VXLAN_UDP_CSUM
= 18
3171 IFLA_VXLAN_UDP_ZERO_CSUM6_TX
= 19
3172 IFLA_VXLAN_UDP_ZERO_CSUM6_RX
= 20
3173 IFLA_VXLAN_REMCSUM_TX
= 21
3174 IFLA_VXLAN_REMCSUM_RX
= 22
3176 IFLA_VXLAN_REMCSUM_NOPARTIAL
= 24
3177 IFLA_VXLAN_COLLECT_METADATA
= 25
3178 IFLA_VXLAN_REPLICATION_NODE
= 253
3179 IFLA_VXLAN_REPLICATION_TYPE
= 254
3181 ifla_vxlan_to_string
= {
3182 IFLA_VXLAN_UNSPEC
: 'IFLA_VXLAN_UNSPEC',
3183 IFLA_VXLAN_ID
: 'IFLA_VXLAN_ID',
3184 IFLA_VXLAN_GROUP
: 'IFLA_VXLAN_GROUP',
3185 IFLA_VXLAN_LINK
: 'IFLA_VXLAN_LINK',
3186 IFLA_VXLAN_LOCAL
: 'IFLA_VXLAN_LOCAL',
3187 IFLA_VXLAN_TTL
: 'IFLA_VXLAN_TTL',
3188 IFLA_VXLAN_TOS
: 'IFLA_VXLAN_TOS',
3189 IFLA_VXLAN_LEARNING
: 'IFLA_VXLAN_LEARNING',
3190 IFLA_VXLAN_AGEING
: 'IFLA_VXLAN_AGEING',
3191 IFLA_VXLAN_LIMIT
: 'IFLA_VXLAN_LIMIT',
3192 IFLA_VXLAN_PORT_RANGE
: 'IFLA_VXLAN_PORT_RANGE',
3193 IFLA_VXLAN_PROXY
: 'IFLA_VXLAN_PROXY',
3194 IFLA_VXLAN_RSC
: 'IFLA_VXLAN_RSC',
3195 IFLA_VXLAN_L2MISS
: 'IFLA_VXLAN_L2MISS',
3196 IFLA_VXLAN_L3MISS
: 'IFLA_VXLAN_L3MISS',
3197 IFLA_VXLAN_PORT
: 'IFLA_VXLAN_PORT',
3198 IFLA_VXLAN_GROUP6
: 'IFLA_VXLAN_GROUP6',
3199 IFLA_VXLAN_LOCAL6
: 'IFLA_VXLAN_LOCAL6',
3200 IFLA_VXLAN_UDP_CSUM
: 'IFLA_VXLAN_UDP_CSUM',
3201 IFLA_VXLAN_UDP_ZERO_CSUM6_TX
: 'IFLA_VXLAN_UDP_ZERO_CSUM6_TX',
3202 IFLA_VXLAN_UDP_ZERO_CSUM6_RX
: 'IFLA_VXLAN_UDP_ZERO_CSUM6_RX',
3203 IFLA_VXLAN_REMCSUM_TX
: 'IFLA_VXLAN_REMCSUM_TX',
3204 IFLA_VXLAN_REMCSUM_RX
: 'IFLA_VXLAN_REMCSUM_RX',
3205 IFLA_VXLAN_GBP
: 'IFLA_VXLAN_GBP',
3206 IFLA_VXLAN_REMCSUM_NOPARTIAL
: 'IFLA_VXLAN_REMCSUM_NOPARTIAL',
3207 IFLA_VXLAN_COLLECT_METADATA
: 'IFLA_VXLAN_COLLECT_METADATA',
3208 IFLA_VXLAN_REPLICATION_NODE
: 'IFLA_VXLAN_REPLICATION_NODE',
3209 IFLA_VXLAN_REPLICATION_TYPE
: 'IFLA_VXLAN_REPLICATION_TYPE'
3212 # =========================================
3213 # IFLA_INFO_DATA attributes for bonds
3214 # =========================================
3215 IFLA_BOND_UNSPEC
= 0
3217 IFLA_BOND_ACTIVE_SLAVE
= 2
3218 IFLA_BOND_MIIMON
= 3
3219 IFLA_BOND_UPDELAY
= 4
3220 IFLA_BOND_DOWNDELAY
= 5
3221 IFLA_BOND_USE_CARRIER
= 6
3222 IFLA_BOND_ARP_INTERVAL
= 7
3223 IFLA_BOND_ARP_IP_TARGET
= 8
3224 IFLA_BOND_ARP_VALIDATE
= 9
3225 IFLA_BOND_ARP_ALL_TARGETS
= 10
3226 IFLA_BOND_PRIMARY
= 11
3227 IFLA_BOND_PRIMARY_RESELECT
= 12
3228 IFLA_BOND_FAIL_OVER_MAC
= 13
3229 IFLA_BOND_XMIT_HASH_POLICY
= 14
3230 IFLA_BOND_RESEND_IGMP
= 15
3231 IFLA_BOND_NUM_PEER_NOTIF
= 16
3232 IFLA_BOND_ALL_SLAVES_ACTIVE
= 17
3233 IFLA_BOND_MIN_LINKS
= 18
3234 IFLA_BOND_LP_INTERVAL
= 19
3235 IFLA_BOND_PACKETS_PER_SLAVE
= 20
3236 IFLA_BOND_AD_LACP_RATE
= 21
3237 IFLA_BOND_AD_SELECT
= 22
3238 IFLA_BOND_AD_INFO
= 23
3239 IFLA_BOND_AD_ACTOR_SYS_PRIO
= 24
3240 IFLA_BOND_AD_USER_PORT_KEY
= 25
3241 IFLA_BOND_AD_ACTOR_SYSTEM
= 26
3242 IFLA_BOND_AD_LACP_BYPASS
= 100
3244 ifla_bond_to_string
= {
3245 IFLA_BOND_UNSPEC
: 'IFLA_BOND_UNSPEC',
3246 IFLA_BOND_MODE
: 'IFLA_BOND_MODE',
3247 IFLA_BOND_ACTIVE_SLAVE
: 'IFLA_BOND_ACTIVE_SLAVE',
3248 IFLA_BOND_MIIMON
: 'IFLA_BOND_MIIMON',
3249 IFLA_BOND_UPDELAY
: 'IFLA_BOND_UPDELAY',
3250 IFLA_BOND_DOWNDELAY
: 'IFLA_BOND_DOWNDELAY',
3251 IFLA_BOND_USE_CARRIER
: 'IFLA_BOND_USE_CARRIER',
3252 IFLA_BOND_ARP_INTERVAL
: 'IFLA_BOND_ARP_INTERVAL',
3253 IFLA_BOND_ARP_IP_TARGET
: 'IFLA_BOND_ARP_IP_TARGET',
3254 IFLA_BOND_ARP_VALIDATE
: 'IFLA_BOND_ARP_VALIDATE',
3255 IFLA_BOND_ARP_ALL_TARGETS
: 'IFLA_BOND_ARP_ALL_TARGETS',
3256 IFLA_BOND_PRIMARY
: 'IFLA_BOND_PRIMARY',
3257 IFLA_BOND_PRIMARY_RESELECT
: 'IFLA_BOND_PRIMARY_RESELECT',
3258 IFLA_BOND_FAIL_OVER_MAC
: 'IFLA_BOND_FAIL_OVER_MAC',
3259 IFLA_BOND_XMIT_HASH_POLICY
: 'IFLA_BOND_XMIT_HASH_POLICY',
3260 IFLA_BOND_RESEND_IGMP
: 'IFLA_BOND_RESEND_IGMP',
3261 IFLA_BOND_NUM_PEER_NOTIF
: 'IFLA_BOND_NUM_PEER_NOTIF',
3262 IFLA_BOND_ALL_SLAVES_ACTIVE
: 'IFLA_BOND_ALL_SLAVES_ACTIVE',
3263 IFLA_BOND_MIN_LINKS
: 'IFLA_BOND_MIN_LINKS',
3264 IFLA_BOND_LP_INTERVAL
: 'IFLA_BOND_LP_INTERVAL',
3265 IFLA_BOND_PACKETS_PER_SLAVE
: 'IFLA_BOND_PACKETS_PER_SLAVE',
3266 IFLA_BOND_AD_LACP_RATE
: 'IFLA_BOND_AD_LACP_RATE',
3267 IFLA_BOND_AD_SELECT
: 'IFLA_BOND_AD_SELECT',
3268 IFLA_BOND_AD_INFO
: 'IFLA_BOND_AD_INFO',
3269 IFLA_BOND_AD_ACTOR_SYS_PRIO
: 'IFLA_BOND_AD_ACTOR_SYS_PRIO',
3270 IFLA_BOND_AD_USER_PORT_KEY
: 'IFLA_BOND_AD_USER_PORT_KEY',
3271 IFLA_BOND_AD_ACTOR_SYSTEM
: 'IFLA_BOND_AD_ACTOR_SYSTEM',
3272 IFLA_BOND_AD_LACP_BYPASS
: 'IFLA_BOND_AD_LACP_BYPASS'
3275 IFLA_BOND_AD_INFO_UNSPEC
= 0
3276 IFLA_BOND_AD_INFO_AGGREGATOR
= 1
3277 IFLA_BOND_AD_INFO_NUM_PORTS
= 2
3278 IFLA_BOND_AD_INFO_ACTOR_KEY
= 3
3279 IFLA_BOND_AD_INFO_PARTNER_KEY
= 4
3280 IFLA_BOND_AD_INFO_PARTNER_MAC
= 5
3282 ifla_bond_ad_to_string
= {
3283 IFLA_BOND_AD_INFO_UNSPEC
: 'IFLA_BOND_AD_INFO_UNSPEC',
3284 IFLA_BOND_AD_INFO_AGGREGATOR
: 'IFLA_BOND_AD_INFO_AGGREGATOR',
3285 IFLA_BOND_AD_INFO_NUM_PORTS
: 'IFLA_BOND_AD_INFO_NUM_PORTS',
3286 IFLA_BOND_AD_INFO_ACTOR_KEY
: 'IFLA_BOND_AD_INFO_ACTOR_KEY',
3287 IFLA_BOND_AD_INFO_PARTNER_KEY
: 'IFLA_BOND_AD_INFO_PARTNER_KEY',
3288 IFLA_BOND_AD_INFO_PARTNER_MAC
: 'IFLA_BOND_AD_INFO_PARTNER_MAC'
3291 ifla_bond_mode_tbl
= {
3315 ifla_bond_mode_pretty_tbl
= {
3325 ifla_bond_xmit_hash_policy_tbl
= {
3343 ifla_bond_xmit_hash_policy_pretty_tbl
= {
3351 # =========================================
3352 # IFLA_INFO_SLAVE_DATA attributes for bonds
3353 # =========================================
3354 IFLA_BOND_SLAVE_UNSPEC
= 0
3355 IFLA_BOND_SLAVE_STATE
= 1
3356 IFLA_BOND_SLAVE_MII_STATUS
= 2
3357 IFLA_BOND_SLAVE_LINK_FAILURE_COUNT
= 3
3358 IFLA_BOND_SLAVE_PERM_HWADDR
= 4
3359 IFLA_BOND_SLAVE_QUEUE_ID
= 5
3360 IFLA_BOND_SLAVE_AD_AGGREGATOR_ID
= 6
3361 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE
= 7
3362 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
= 8
3363 IFLA_BOND_SLAVE_CL_START
= 50
3364 IFLA_BOND_SLAVE_AD_RX_BYPASS
= IFLA_BOND_SLAVE_CL_START
3366 ifla_bond_slave_to_string
= {
3367 IFLA_BOND_SLAVE_UNSPEC
: 'IFLA_BOND_SLAVE_UNSPEC',
3368 IFLA_BOND_SLAVE_STATE
: 'IFLA_BOND_SLAVE_STATE',
3369 IFLA_BOND_SLAVE_MII_STATUS
: 'IFLA_BOND_SLAVE_MII_STATUS',
3370 IFLA_BOND_SLAVE_LINK_FAILURE_COUNT
: 'IFLA_BOND_SLAVE_LINK_FAILURE_COUNT',
3371 IFLA_BOND_SLAVE_PERM_HWADDR
: 'IFLA_BOND_SLAVE_PERM_HWADDR',
3372 IFLA_BOND_SLAVE_QUEUE_ID
: 'IFLA_BOND_SLAVE_QUEUE_ID',
3373 IFLA_BOND_SLAVE_AD_AGGREGATOR_ID
: 'IFLA_BOND_SLAVE_AD_AGGREGATOR_ID',
3374 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE
: 'IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE',
3375 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
: 'IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE',
3376 IFLA_BOND_SLAVE_CL_START
: 'IFLA_BOND_SLAVE_CL_START',
3377 IFLA_BOND_SLAVE_AD_RX_BYPASS
: 'IFLA_BOND_SLAVE_AD_RX_BYPASS'
3380 # =========================================
3381 # IFLA_PROTINFO attributes for bridge ports
3382 # =========================================
3383 IFLA_BRPORT_UNSPEC
= 0
3384 IFLA_BRPORT_STATE
= 1
3385 IFLA_BRPORT_PRIORITY
= 2
3386 IFLA_BRPORT_COST
= 3
3387 IFLA_BRPORT_MODE
= 4
3388 IFLA_BRPORT_GUARD
= 5
3389 IFLA_BRPORT_PROTECT
= 6
3390 IFLA_BRPORT_FAST_LEAVE
= 7
3391 IFLA_BRPORT_LEARNING
= 8
3392 IFLA_BRPORT_UNICAST_FLOOD
= 9
3393 IFLA_BRPORT_PROXYARP
= 10
3394 IFLA_BRPORT_LEARNING_SYNC
= 11
3395 IFLA_BRPORT_PROXYARP_WIFI
= 12
3396 IFLA_BRPORT_ROOT_ID
= 13
3397 IFLA_BRPORT_BRIDGE_ID
= 14
3398 IFLA_BRPORT_DESIGNATED_PORT
= 15
3399 IFLA_BRPORT_DESIGNATED_COST
= 16
3402 IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
= 19
3403 IFLA_BRPORT_CONFIG_PENDING
= 20
3404 IFLA_BRPORT_MESSAGE_AGE_TIMER
= 21
3405 IFLA_BRPORT_FORWARD_DELAY_TIMER
= 22
3406 IFLA_BRPORT_HOLD_TIMER
= 23
3407 IFLA_BRPORT_FLUSH
= 24
3408 IFLA_BRPORT_MULTICAST_ROUTER
= 25
3409 IFLA_BRPORT_PAD
= 26
3410 IFLA_BRPORT_MCAST_FLOOD
= 27
3411 IFLA_BRPORT_MCAST_TO_UCAST
= 28
3412 IFLA_BRPORT_VLAN_TUNNEL
= 29
3413 IFLA_BRPORT_BCAST_FLOOD
= 30
3414 IFLA_BRPORT_GROUP_FWD_MASK
= 31
3415 IFLA_BRPORT_ARP_SUPPRESS
= 32
3416 IFLA_BRPORT_PEER_LINK
= 150
3417 IFLA_BRPORT_DUAL_LINK
= 151
3418 IFLA_BRPORT_GROUP_FWD_MASKHI
= 153
3419 IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
= 154
3421 ifla_brport_to_string
= {
3422 IFLA_BRPORT_UNSPEC
: 'IFLA_BRPORT_UNSPEC',
3423 IFLA_BRPORT_STATE
: 'IFLA_BRPORT_STATE',
3424 IFLA_BRPORT_PRIORITY
: 'IFLA_BRPORT_PRIORITY',
3425 IFLA_BRPORT_COST
: 'IFLA_BRPORT_COST',
3426 IFLA_BRPORT_MODE
: 'IFLA_BRPORT_MODE',
3427 IFLA_BRPORT_GUARD
: 'IFLA_BRPORT_GUARD',
3428 IFLA_BRPORT_PROTECT
: 'IFLA_BRPORT_PROTECT',
3429 IFLA_BRPORT_FAST_LEAVE
: 'IFLA_BRPORT_FAST_LEAVE',
3430 IFLA_BRPORT_LEARNING
: 'IFLA_BRPORT_LEARNING',
3431 IFLA_BRPORT_UNICAST_FLOOD
: 'IFLA_BRPORT_UNICAST_FLOOD',
3432 IFLA_BRPORT_PROXYARP
: 'IFLA_BRPORT_PROXYARP',
3433 IFLA_BRPORT_LEARNING_SYNC
: 'IFLA_BRPORT_LEARNING_SYNC',
3434 IFLA_BRPORT_PROXYARP_WIFI
: 'IFLA_BRPORT_PROXYARP_WIFI',
3435 IFLA_BRPORT_ROOT_ID
: 'IFLA_BRPORT_ROOT_ID',
3436 IFLA_BRPORT_BRIDGE_ID
: 'IFLA_BRPORT_BRIDGE_ID',
3437 IFLA_BRPORT_DESIGNATED_PORT
: 'IFLA_BRPORT_DESIGNATED_PORT',
3438 IFLA_BRPORT_DESIGNATED_COST
: 'IFLA_BRPORT_DESIGNATED_COST',
3439 IFLA_BRPORT_ID
: 'IFLA_BRPORT_ID',
3440 IFLA_BRPORT_NO
: 'IFLA_BRPORT_NO',
3441 IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
: 'IFLA_BRPORT_TOPOLOGY_CHANGE_ACK',
3442 IFLA_BRPORT_CONFIG_PENDING
: 'IFLA_BRPORT_CONFIG_PENDING',
3443 IFLA_BRPORT_MESSAGE_AGE_TIMER
: 'IFLA_BRPORT_MESSAGE_AGE_TIMER',
3444 IFLA_BRPORT_FORWARD_DELAY_TIMER
: 'IFLA_BRPORT_FORWARD_DELAY_TIMER',
3445 IFLA_BRPORT_HOLD_TIMER
: 'IFLA_BRPORT_HOLD_TIMER',
3446 IFLA_BRPORT_FLUSH
: 'IFLA_BRPORT_FLUSH',
3447 IFLA_BRPORT_MULTICAST_ROUTER
: 'IFLA_BRPORT_MULTICAST_ROUTER',
3448 IFLA_BRPORT_PAD
: 'IFLA_BRPORT_PAD',
3449 IFLA_BRPORT_MCAST_FLOOD
: 'IFLA_BRPORT_MCAST_FLOOD',
3450 IFLA_BRPORT_MCAST_TO_UCAST
: 'IFLA_BRPORT_MCAST_TO_UCAST',
3451 IFLA_BRPORT_VLAN_TUNNEL
: 'IFLA_BRPORT_VLAN_TUNNEL',
3452 IFLA_BRPORT_BCAST_FLOOD
: 'IFLA_BRPORT_BCAST_FLOOD',
3453 IFLA_BRPORT_GROUP_FWD_MASK
: 'IFLA_BRPORT_GROUP_FWD_MASK',
3454 IFLA_BRPORT_PEER_LINK
: 'IFLA_BRPORT_PEER_LINK',
3455 IFLA_BRPORT_DUAL_LINK
: 'IFLA_BRPORT_DUAL_LINK',
3456 IFLA_BRPORT_ARP_SUPPRESS
: 'IFLA_BRPORT_ARP_SUPPRESS',
3457 IFLA_BRPORT_GROUP_FWD_MASKHI
: 'IFLA_BRPORT_GROUP_FWD_MASKHI',
3458 IFLA_BRPORT_DOWN_PEERLINK_REDIRECT
: 'IFLA_BRPORT_DOWN_PEERLINK_REDIRECT'
3461 # Subtype attributes for IFLA_AF_SPEC
3462 IFLA_INET6_UNSPEC
= 0
3463 IFLA_INET6_FLAGS
= 1 # link flags
3464 IFLA_INET6_CONF
= 2 # sysctl parameters
3465 IFLA_INET6_STATS
= 3 # statistics
3466 IFLA_INET6_MCAST
= 4 # MC things. What of them?
3467 IFLA_INET6_CACHEINFO
= 5 # time values and max reasm size
3468 IFLA_INET6_ICMP6STATS
= 6 # statistics (icmpv6)
3469 IFLA_INET6_TOKEN
= 7 # device token
3470 IFLA_INET6_ADDR_GEN_MODE
= 8 # implicit address generator mode
3471 __IFLA_INET6_MAX
= 9
3473 ifla_inet6_af_spec_to_string
= {
3474 IFLA_INET6_UNSPEC
: 'IFLA_INET6_UNSPEC',
3475 IFLA_INET6_FLAGS
: 'IFLA_INET6_FLAGS',
3476 IFLA_INET6_CONF
: 'IFLA_INET6_CONF',
3477 IFLA_INET6_STATS
: 'IFLA_INET6_STATS',
3478 IFLA_INET6_MCAST
: 'IFLA_INET6_MCAST',
3479 IFLA_INET6_CACHEINFO
: 'IFLA_INET6_CACHEINFO',
3480 IFLA_INET6_ICMP6STATS
: 'IFLA_INET6_ICMP6STATS',
3481 IFLA_INET6_TOKEN
: 'IFLA_INET6_TOKEN',
3482 IFLA_INET6_ADDR_GEN_MODE
: 'IFLA_INET6_ADDR_GEN_MODE',
3485 # Subtype attrbutes AF_INET
3486 IFLA_INET_UNSPEC
= 0
3490 ifla_inet_af_spec_to_string
= {
3491 IFLA_INET_UNSPEC
: 'IFLA_INET_UNSPEC',
3492 IFLA_INET_CONF
: 'IFLA_INET_CONF',
3495 # BRIDGE IFLA_AF_SPEC attributes
3496 IFLA_BRIDGE_FLAGS
= 0
3497 IFLA_BRIDGE_MODE
= 1
3498 IFLA_BRIDGE_VLAN_INFO
= 2
3500 ifla_bridge_af_spec_to_string
= {
3501 IFLA_BRIDGE_FLAGS
: 'IFLA_BRIDGE_FLAGS',
3502 IFLA_BRIDGE_MODE
: 'IFLA_BRIDGE_MODE',
3503 IFLA_BRIDGE_VLAN_INFO
: 'IFLA_BRIDGE_VLAN_INFO'
3506 # BRIDGE_VLAN_INFO flags
3507 BRIDGE_VLAN_INFO_MASTER
= 1 << 0 # Operate on Bridge device as well
3508 BRIDGE_VLAN_INFO_PVID
= 1 << 1 # VLAN is PVID, ingress untagged
3509 BRIDGE_VLAN_INFO_UNTAGGED
= 1 << 2 # VLAN egresses untagged
3510 BRIDGE_VLAN_INFO_RANGE_BEGIN
= 1 << 3 # VLAN is start of vlan range
3511 BRIDGE_VLAN_INFO_RANGE_END
= 1 << 4 # VLAN is end of vlan range
3512 BRIDGE_VLAN_INFO_BRENTRY
= 1 << 5 # Global bridge VLAN entry
3514 bridge_vlan_to_string
= {
3515 BRIDGE_VLAN_INFO_MASTER
: 'BRIDGE_VLAN_INFO_MASTER',
3516 BRIDGE_VLAN_INFO_PVID
: 'BRIDGE_VLAN_INFO_PVID',
3517 BRIDGE_VLAN_INFO_UNTAGGED
: 'BRIDGE_VLAN_INFO_UNTAGGED',
3518 BRIDGE_VLAN_INFO_RANGE_BEGIN
: 'BRIDGE_VLAN_INFO_RANGE_BEGIN',
3519 BRIDGE_VLAN_INFO_RANGE_END
: 'BRIDGE_VLAN_INFO_RANGE_END',
3520 BRIDGE_VLAN_INFO_BRENTRY
: 'BRIDGE_VLAN_INFO_BRENTRY'
3524 BRIDGE_FLAGS_MASTER
= 1
3525 BRIDGE_FLAGS_SELF
= 2
3527 bridge_flags_to_string
= {
3528 BRIDGE_FLAGS_MASTER
: 'BRIDGE_FLAGS_MASTER',
3529 BRIDGE_FLAGS_SELF
: 'BRIDGE_FLAGS_SELF'
3532 # filters for IFLA_EXT_MASK
3533 RTEXT_FILTER_VF
= 1 << 0
3534 RTEXT_FILTER_BRVLAN
= 1 << 1
3535 RTEXT_FILTER_BRVLAN_COMPRESSED
= 1 << 2
3536 RTEXT_FILTER_SKIP_STATS
= 1 << 3
3539 RTEXT_FILTER_VF
: 'RTEXT_FILTER_VF',
3540 RTEXT_FILTER_BRVLAN
: 'RTEXT_FILTER_BRVLAN',
3541 RTEXT_FILTER_BRVLAN_COMPRESSED
: 'RTEXT_FILTER_BRVLAN_COMPRESSED',
3542 RTEXT_FILTER_SKIP_STATS
: 'RTEXT_FILTER_SKIP_STATS'
3546 IFLA_BR_FORWARD_DELAY
= 1
3547 IFLA_BR_HELLO_TIME
= 2
3549 IFLA_BR_AGEING_TIME
= 4
3550 IFLA_BR_STP_STATE
= 5
3551 IFLA_BR_PRIORITY
= 6
3552 IFLA_BR_VLAN_FILTERING
= 7
3553 IFLA_BR_VLAN_PROTOCOL
= 8
3554 IFLA_BR_GROUP_FWD_MASK
= 9
3555 IFLA_BR_ROOT_ID
= 10
3556 IFLA_BR_BRIDGE_ID
= 11
3557 IFLA_BR_ROOT_PORT
= 12
3558 IFLA_BR_ROOT_PATH_COST
= 13
3559 IFLA_BR_TOPOLOGY_CHANGE
= 14
3560 IFLA_BR_TOPOLOGY_CHANGE_DETECTED
= 15
3561 IFLA_BR_HELLO_TIMER
= 16
3562 IFLA_BR_TCN_TIMER
= 17
3563 IFLA_BR_TOPOLOGY_CHANGE_TIMER
= 18
3564 IFLA_BR_GC_TIMER
= 19
3565 IFLA_BR_GROUP_ADDR
= 20
3566 IFLA_BR_FDB_FLUSH
= 21
3567 IFLA_BR_MCAST_ROUTER
= 22
3568 IFLA_BR_MCAST_SNOOPING
= 23
3569 IFLA_BR_MCAST_QUERY_USE_IFADDR
= 24
3570 IFLA_BR_MCAST_QUERIER
= 25
3571 IFLA_BR_MCAST_HASH_ELASTICITY
= 26
3572 IFLA_BR_MCAST_HASH_MAX
= 27
3573 IFLA_BR_MCAST_LAST_MEMBER_CNT
= 28
3574 IFLA_BR_MCAST_STARTUP_QUERY_CNT
= 29
3575 IFLA_BR_MCAST_LAST_MEMBER_INTVL
= 30
3576 IFLA_BR_MCAST_MEMBERSHIP_INTVL
= 31
3577 IFLA_BR_MCAST_QUERIER_INTVL
= 32
3578 IFLA_BR_MCAST_QUERY_INTVL
= 33
3579 IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
= 34
3580 IFLA_BR_MCAST_STARTUP_QUERY_INTVL
= 35
3581 IFLA_BR_NF_CALL_IPTABLES
= 36
3582 IFLA_BR_NF_CALL_IP6TABLES
= 37
3583 IFLA_BR_NF_CALL_ARPTABLES
= 38
3584 IFLA_BR_VLAN_DEFAULT_PVID
= 39
3586 IFLA_BR_VLAN_STATS_ENABLED
= 41
3587 IFLA_BR_MCAST_STATS_ENABLED
= 42
3588 IFLA_BR_MCAST_IGMP_VERSION
= 43
3589 IFLA_BR_MCAST_MLD_VERSION
= 44
3591 ifla_br_to_string
= {
3592 IFLA_BR_UNSPEC
: 'IFLA_BR_UNSPEC',
3593 IFLA_BR_FORWARD_DELAY
: 'IFLA_BR_FORWARD_DELAY',
3594 IFLA_BR_HELLO_TIME
: 'IFLA_BR_HELLO_TIME',
3595 IFLA_BR_MAX_AGE
: 'IFLA_BR_MAX_AGE',
3596 IFLA_BR_AGEING_TIME
: 'IFLA_BR_AGEING_TIME',
3597 IFLA_BR_STP_STATE
: 'IFLA_BR_STP_STATE',
3598 IFLA_BR_PRIORITY
: 'IFLA_BR_PRIORITY',
3599 IFLA_BR_VLAN_FILTERING
: 'IFLA_BR_VLAN_FILTERING',
3600 IFLA_BR_VLAN_PROTOCOL
: 'IFLA_BR_VLAN_PROTOCOL',
3601 IFLA_BR_GROUP_FWD_MASK
: 'IFLA_BR_GROUP_FWD_MASK',
3602 IFLA_BR_ROOT_ID
: 'IFLA_BR_ROOT_ID',
3603 IFLA_BR_BRIDGE_ID
: 'IFLA_BR_BRIDGE_ID',
3604 IFLA_BR_ROOT_PORT
: 'IFLA_BR_ROOT_PORT',
3605 IFLA_BR_ROOT_PATH_COST
: 'IFLA_BR_ROOT_PATH_COST',
3606 IFLA_BR_TOPOLOGY_CHANGE
: 'IFLA_BR_TOPOLOGY_CHANGE',
3607 IFLA_BR_TOPOLOGY_CHANGE_DETECTED
: 'IFLA_BR_TOPOLOGY_CHANGE_DETECTED',
3608 IFLA_BR_HELLO_TIMER
: 'IFLA_BR_HELLO_TIMER',
3609 IFLA_BR_TCN_TIMER
: 'IFLA_BR_TCN_TIMER',
3610 IFLA_BR_TOPOLOGY_CHANGE_TIMER
: 'IFLA_BR_TOPOLOGY_CHANGE_TIMER',
3611 IFLA_BR_GC_TIMER
: 'IFLA_BR_GC_TIMER',
3612 IFLA_BR_GROUP_ADDR
: 'IFLA_BR_GROUP_ADDR',
3613 IFLA_BR_FDB_FLUSH
: 'IFLA_BR_FDB_FLUSH',
3614 IFLA_BR_MCAST_ROUTER
: 'IFLA_BR_MCAST_ROUTER',
3615 IFLA_BR_MCAST_SNOOPING
: 'IFLA_BR_MCAST_SNOOPING',
3616 IFLA_BR_MCAST_QUERY_USE_IFADDR
: 'IFLA_BR_MCAST_QUERY_USE_IFADDR',
3617 IFLA_BR_MCAST_QUERIER
: 'IFLA_BR_MCAST_QUERIER',
3618 IFLA_BR_MCAST_HASH_ELASTICITY
: 'IFLA_BR_MCAST_HASH_ELASTICITY',
3619 IFLA_BR_MCAST_HASH_MAX
: 'IFLA_BR_MCAST_HASH_MAX',
3620 IFLA_BR_MCAST_LAST_MEMBER_CNT
: 'IFLA_BR_MCAST_LAST_MEMBER_CNT',
3621 IFLA_BR_MCAST_STARTUP_QUERY_CNT
: 'IFLA_BR_MCAST_STARTUP_QUERY_CNT',
3622 IFLA_BR_MCAST_LAST_MEMBER_INTVL
: 'IFLA_BR_MCAST_LAST_MEMBER_INTVL',
3623 IFLA_BR_MCAST_MEMBERSHIP_INTVL
: 'IFLA_BR_MCAST_MEMBERSHIP_INTVL',
3624 IFLA_BR_MCAST_QUERIER_INTVL
: 'IFLA_BR_MCAST_QUERIER_INTVL',
3625 IFLA_BR_MCAST_QUERY_INTVL
: 'IFLA_BR_MCAST_QUERY_INTVL',
3626 IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
: 'IFLA_BR_MCAST_QUERY_RESPONSE_INTVL',
3627 IFLA_BR_MCAST_STARTUP_QUERY_INTVL
: 'IFLA_BR_MCAST_STARTUP_QUERY_INTVL',
3628 IFLA_BR_NF_CALL_IPTABLES
: 'IFLA_BR_NF_CALL_IPTABLES',
3629 IFLA_BR_NF_CALL_IP6TABLES
: 'IFLA_BR_NF_CALL_IP6TABLES',
3630 IFLA_BR_NF_CALL_ARPTABLES
: 'IFLA_BR_NF_CALL_ARPTABLES',
3631 IFLA_BR_VLAN_DEFAULT_PVID
: 'IFLA_BR_VLAN_DEFAULT_PVID',
3632 IFLA_BR_PAD
: 'IFLA_BR_PAD',
3633 IFLA_BR_VLAN_STATS_ENABLED
: 'IFLA_BR_VLAN_STATS_ENABLED',
3634 IFLA_BR_MCAST_STATS_ENABLED
: 'IFLA_BR_MCAST_STATS_ENABLED',
3635 IFLA_BR_MCAST_IGMP_VERSION
: 'IFLA_BR_MCAST_IGMP_VERSION',
3636 IFLA_BR_MCAST_MLD_VERSION
: 'IFLA_BR_MCAST_MLD_VERSION'
3639 # =========================================
3640 # IFLA_INFO_DATA attributes for vrfs
3641 # =========================================
3645 ifla_vrf_to_string
= {
3646 IFLA_VRF_UNSPEC
: 'IFLA_VRF_UNSPEC',
3647 IFLA_VRF_TABLE
: 'IFLA_VRF_TABLE'
3650 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
3651 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
3652 self
.PACK
= 'BxHiII'
3653 self
.LEN
= calcsize(self
.PACK
)
3655 def get_link_type_string(self
, index
):
3656 return self
.get_string(self
.link_type_to_string
, index
)
3658 def get_ifla_inet6_af_spec_to_string(self
, index
):
3659 return self
.get_string(self
.ifla_inet6_af_spec_to_string
, index
)
3661 def get_ifla_inet_af_spec_to_string(self
, index
):
3662 return self
.get_string(self
.ifla_inet_af_spec_to_string
, index
)
3664 def get_ifla_bridge_af_spec_to_string(self
, index
):
3665 return self
.get_string(self
.ifla_bridge_af_spec_to_string
, index
)
3667 def get_ifla_info_string(self
, index
):
3668 return self
.get_string(self
.ifla_info_to_string
, index
)
3670 def get_ifla_vlan_string(self
, index
):
3671 return self
.get_string(self
.ifla_vlan_to_string
, index
)
3673 def get_ifla_vxlan_string(self
, index
):
3674 return self
.get_string(self
.ifla_vxlan_to_string
, index
)
3676 def get_ifla_macvlan_string(self
, index
):
3677 return self
.get_string(self
.ifla_macvlan_to_string
, index
)
3679 def get_macvlan_mode_string(self
, index
):
3680 return self
.get_string(self
.macvlan_mode_to_string
, index
)
3682 def get_ifla_bond_string(self
, index
):
3683 return self
.get_string(self
.ifla_bond_to_string
, index
)
3685 def get_ifla_bond_ad_string(self
, index
):
3686 return self
.get_string(self
.ifla_bond_ad_to_string
, index
)
3688 def get_ifla_brport_string(self
, index
):
3689 return self
.get_string(self
.ifla_brport_to_string
, index
)
3691 def get_ifla_br_string(self
, index
):
3692 return self
.get_string(self
.ifla_br_to_string
, index
)
3694 def get_bridge_vlan_string(self
, index
):
3695 return self
.get_string(self
.bridge_vlan_to_string
, index
)
3697 def get_bridge_flags_string(self
, index
):
3698 return self
.get_string(self
.bridge_flags_to_string
, index
)
3700 def decode_service_header(self
):
3702 # Nothing to do if the message did not contain a service header
3703 if self
.length
== self
.header_LEN
:
3706 (self
.family
, self
.device_type
,
3709 self
.change_mask
) = \
3710 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
3713 color
= yellow
if self
.use_color
else None
3714 color_start
= "\033[%dm" % color
if color
else ""
3715 color_end
= "\033[0m" if color
else ""
3716 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
3718 for x
in range(0, self
.LEN
/4):
3719 if self
.line_number
== 5:
3720 extra
= "Family %s (%s:%d), Device Type %s (%d - %s)" % \
3721 (zfilled_hex(self
.family
, 2), get_family_str(self
.family
), self
.family
,
3722 zfilled_hex(self
.device_type
, 4), self
.device_type
, self
.get_link_type_string(self
.device_type
))
3723 elif self
.line_number
== 6:
3724 extra
= "Interface Index %s (%d)" % (zfilled_hex(self
.ifindex
, 8), self
.ifindex
)
3725 elif self
.line_number
== 7:
3726 extra
= "Device Flags %s (%s)" % (zfilled_hex(self
.flags
, 8), self
.get_flags_string())
3727 elif self
.line_number
== 8:
3728 extra
= "Change Mask %s" % zfilled_hex(self
.change_mask
, 8)
3730 extra
= "Unexpected line number %d" % self
.line_number
3734 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
3735 self
.line_number
+= 1
3738 if self
.flags
& Link
.IFF_UP
:
3743 class Netconf(Link
):
3745 RTM_NEWNETCONF - Service Header
3753 RTM_GETNETCONF - Service Header
3756 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
3757 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3758 | Family | Reserved | Device Type |
3759 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3761 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3763 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3765 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3767 # Netconf attributes
3768 # /usr/include/linux/netconf.h
3770 NETCONFA_IFINDEX
= 1
3771 NETCONFA_FORWARDING
= 2
3772 NETCONFA_RP_FILTER
= 3
3773 NETCONFA_MC_FORWARDING
= 4
3774 NETCONFA_PROXY_NEIGH
= 5
3775 NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN
= 6
3779 NETCONFA_MAX
= (__NETCONFA_MAX
- 1)
3782 NETCONFA_IFINDEX_ALL
= -1
3783 NETCONFA_IFINDEX_DEFAULT
= -2
3785 NETCONF_ATTR_FAMILY
= 0x0001
3786 NETCONF_ATTR_IFINDEX
= 0x0002
3787 NETCONF_ATTR_RP_FILTER
= 0x0004
3788 NETCONF_ATTR_FWDING
= 0x0008
3789 NETCONF_ATTR_MC_FWDING
= 0x0010
3790 NETCONF_ATTR_PROXY_NEIGH
= 0x0020
3791 NETCONF_ATTR_IGNORE_RT_LINKDWN
= 0x0040
3793 attribute_to_class
= {
3794 NETCONFA_UNSPEC
: ('NETCONFA_UNSPEC', AttributeGeneric
),
3795 NETCONFA_IFINDEX
: ('NETCONFA_IFINDEX', AttributeFourByteValue
),
3796 NETCONFA_FORWARDING
: ('NETCONFA_FORWARDING', AttributeFourByteValue
),
3797 NETCONFA_RP_FILTER
: ('NETCONFA_RP_FILTER', AttributeFourByteValue
),
3798 NETCONFA_MC_FORWARDING
: ('NETCONFA_MC_FORWARDING', AttributeFourByteValue
),
3799 NETCONFA_PROXY_NEIGH
: ('NETCONFA_PROXY_NEIGH', AttributeFourByteValue
),
3800 NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN
: ('NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN', AttributeFourByteValue
),
3801 NETCONFA_INPUT
: ('NETCONFA_INPUT', AttributeFourByteValue
),
3804 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
3805 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
3806 if msgtype
== RTM_GETNETCONF
: # same as RTM_GETLINK
3807 self
.PACK
= 'BxHiII'
3808 self
.LEN
= calcsize(self
.PACK
)
3809 elif msgtype
== RTM_NEWNETCONF
:
3811 self
.LEN
= calcsize(self
.PACK
)
3813 def decode_service_header(self
):
3814 # Nothing to do if the message did not contain a service header
3815 if self
.length
== self
.header_LEN
:
3818 if self
.msgtype
== RTM_GETNETCONF
:
3819 super(Netconf
, self
).decode_service_header()
3821 elif self
.msgtype
== RTM_NEWNETCONF
:
3822 (self
.family
,) = unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
3825 color
= yellow
if self
.use_color
else None
3826 color_start
= "\033[%dm" % color
if color
else ""
3827 color_end
= "\033[0m" if color
else ""
3828 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
3829 self
.dump_buffer
.append(data_to_color_text(1, color
, bytearray(struct
.pack('!I', self
.family
)), "Family %s (%s:%d)" % (zfilled_hex(self
.family
, 2), get_family_str(self
.family
), self
.family
)))
3832 class Neighbor(NetlinkPacket
):
3837 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
3838 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3839 | Family | Reserved1 | Reserved2 |
3840 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3842 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3843 | State | Flags | Type |
3844 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3847 # Neighbor attributes
3848 # /usr/include/linux/neighbour.h
3849 NDA_UNSPEC
= 0x00 # Unknown type
3850 NDA_DST
= 0x01 # A neighbour cache network. layer destination address
3851 NDA_LLADDR
= 0x02 # A neighbor cache link layer address.
3852 NDA_CACHEINFO
= 0x03 # Cache statistics
3859 NDA_LINK_NETNSID
= 0x0A
3861 attribute_to_class
= {
3862 NDA_UNSPEC
: ('NDA_UNSPEC', AttributeGeneric
),
3863 NDA_DST
: ('NDA_DST', AttributeIPAddress
),
3864 NDA_LLADDR
: ('NDA_LLADDR', AttributeMACAddress
),
3865 NDA_CACHEINFO
: ('NDA_CACHEINFO', AttributeFourByteList
),
3866 NDA_PROBES
: ('NDA_PROBES', AttributeFourByteValue
),
3867 NDA_VLAN
: ('NDA_VLAN', AttributeTwoByteValue
),
3868 NDA_PORT
: ('NDA_PORT', AttributeGeneric
),
3869 NDA_VNI
: ('NDA_VNI', AttributeFourByteValue
),
3870 NDA_IFINDEX
: ('NDA_IFINDEX', AttributeFourByteValue
),
3871 NDA_MASTER
: ('NDA_MASTER', AttributeFourByteValue
),
3872 NDA_LINK_NETNSID
: ('NDA_LINK_NETNSID', AttributeGeneric
)
3876 # /usr/include/linux/neighbour.h
3880 NTF_PROXY
= 0x08 # A proxy ARP entry
3881 NTF_EXT_LEARNED
= 0x10 # neigh entry installed by an external APP
3882 NTF_ROUTER
= 0x80 # An IPv6 router
3885 NTF_USE
: 'NTF_USE',
3886 NTF_SELF
: 'NTF_SELF',
3887 NTF_MASTER
: 'NTF_MASTER',
3888 NTF_PROXY
: 'NTF_PROXY',
3889 NTF_EXT_LEARNED
: 'NTF_EXT_LEARNED',
3890 NTF_ROUTER
: 'NTF_ROUTER'
3894 # /usr/include/linux/neighbour.h
3896 NUD_INCOMPLETE
= 0x01 # Still attempting to resolve
3897 NUD_REACHABLE
= 0x02 # A confirmed working cache entry
3898 NUD_STALE
= 0x04 # an expired cache entry
3899 NUD_DELAY
= 0x08 # Neighbor no longer reachable. Traffic sent, waiting for confirmatio.
3900 NUD_PROBE
= 0x10 # A cache entry that is currently being re-solicited
3901 NUD_FAILED
= 0x20 # An invalid cache entry
3902 NUD_NOARP
= 0x40 # A device which does not do neighbor discovery(ARP)
3903 NUD_PERMANENT
= 0x80 # A static entry
3906 NUD_NONE
: 'NUD_NONE',
3907 NUD_INCOMPLETE
: 'NUD_INCOMPLETE',
3908 NUD_REACHABLE
: 'NUD_REACHABLE',
3909 NUD_STALE
: 'NUD_STALE',
3910 NUD_DELAY
: 'NUD_DELAY',
3911 NUD_PROBE
: 'NUD_PROBE',
3912 NUD_FAILED
: 'NUD_FAILED',
3913 NUD_NOARP
: 'NUD_NOARP',
3914 NUD_PERMANENT
: 'NUD_PERMANENT'
3917 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
3918 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
3919 self
.PACK
= 'BxxxiHBB'
3920 self
.LEN
= calcsize(self
.PACK
)
3922 def get_state_string(self
, index
):
3923 return self
.get_string(self
.state_to_string
, index
)
3925 def get_states_string(self
, states
):
3928 if states
& Neighbor
.NUD_INCOMPLETE
:
3929 for_string
.append('NUD_INCOMPLETE')
3931 if states
& Neighbor
.NUD_REACHABLE
:
3932 for_string
.append('NUD_REACHABLE')
3934 if states
& Neighbor
.NUD_STALE
:
3935 for_string
.append('NUD_STALE')
3937 if states
& Neighbor
.NUD_DELAY
:
3938 for_string
.append('NUD_DELAY')
3940 if states
& Neighbor
.NUD_PROBE
:
3941 for_string
.append('NUD_PROBE')
3943 if states
& Neighbor
.NUD_FAILED
:
3944 for_string
.append('NUD_FAILED')
3946 if states
& Neighbor
.NUD_NOARP
:
3947 for_string
.append('NUD_NOARP')
3949 if states
& Neighbor
.NUD_PERMANENT
:
3950 for_string
.append('NUD_PERMANENT')
3952 return ', '.join(for_string
)
3954 def get_flags_string(self
, flags
):
3957 if flags
& Neighbor
.NTF_USE
:
3958 for_string
.append('NTF_USE')
3960 if flags
& Neighbor
.NTF_SELF
:
3961 for_string
.append('NTF_SELF')
3963 if flags
& Neighbor
.NTF_MASTER
:
3964 for_string
.append('NTF_MASTER')
3966 if flags
& Neighbor
.NTF_PROXY
:
3967 for_string
.append('NTF_PROXY')
3969 if flags
& Neighbor
.NTF_ROUTER
:
3970 for_string
.append('NTF_ROUTER')
3972 return ', '.join(for_string
)
3974 def decode_service_header(self
):
3976 # Nothing to do if the message did not contain a service header
3977 if self
.length
== self
.header_LEN
:
3982 self
.state
, self
.flags
, self
.neighbor_type
) = \
3983 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
3986 color
= yellow
if self
.use_color
else None
3987 color_start
= "\033[%dm" % color
if color
else ""
3988 color_end
= "\033[0m" if color
else ""
3989 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
3991 for x
in range(0, self
.LEN
/4):
3992 if self
.line_number
== 5:
3993 extra
= "Family %s (%s:%d)" % (zfilled_hex(self
.family
, 2), get_family_str(self
.family
), self
.family
)
3994 elif self
.line_number
== 6:
3995 extra
= "Interface Index %s (%d)" % (zfilled_hex(self
.ifindex
, 8), self
.ifindex
)
3996 elif self
.line_number
== 7:
3997 extra
= "State %s (%d) %s, Flags %s (%s) %s, Type %s (%d)" % \
3998 (zfilled_hex(self
.state
, 4), self
.state
, self
.get_states_string(self
.state
),
3999 zfilled_hex(self
.flags
, 2), self
.flags
, self
.get_flags_string(self
.flags
),
4000 zfilled_hex(self
.neighbor_type
, 4), self
.neighbor_type
)
4002 extra
= "Unexpected line number %d" % self
.line_number
4006 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
4007 self
.line_number
+= 1
4010 class Route(NetlinkPacket
):
4015 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
4016 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4017 | Family | Dest length | Src length | TOS |
4018 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4019 | Table ID | Protocol | Scope | Type |
4020 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4022 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4026 # /usr/include/linux/rtnetlink.h
4027 RTA_UNSPEC
= 0x00 # Ignored.
4028 RTA_DST
= 0x01 # Protocol address for route destination address.
4029 RTA_SRC
= 0x02 # Protocol address for route source address.
4030 RTA_IIF
= 0x03 # Input interface index.
4031 RTA_OIF
= 0x04 # Output interface index.
4032 RTA_GATEWAY
= 0x05 # Protocol address for the gateway of the route
4033 RTA_PRIORITY
= 0x06 # Priority of broker.
4034 RTA_PREFSRC
= 0x07 # Preferred source address in cases where more than one source address could be used.
4035 RTA_METRICS
= 0x08 # Route metrics attributed to route and associated protocols(e.g., RTT, initial TCP window, etc.).
4036 RTA_MULTIPATH
= 0x09 # Multipath route next hop's attributes.
4037 RTA_PROTOINFO
= 0x0A # Firewall based policy routing attribute.
4038 RTA_FLOW
= 0x0B # Route realm.
4039 RTA_CACHEINFO
= 0x0C # Cached route information.
4044 RTA_MFC_STATS
= 0x11
4048 RTA_ENCAP_TYPE
= 0x15
4051 attribute_to_class
= {
4052 RTA_UNSPEC
: ('RTA_UNSPEC', AttributeGeneric
),
4053 RTA_DST
: ('RTA_DST', AttributeIPAddress
),
4054 RTA_SRC
: ('RTA_SRC', AttributeIPAddress
),
4055 RTA_IIF
: ('RTA_IIF', AttributeFourByteValue
),
4056 RTA_OIF
: ('RTA_OIF', AttributeFourByteValue
),
4057 RTA_GATEWAY
: ('RTA_GATEWAY', AttributeIPAddress
),
4058 RTA_PRIORITY
: ('RTA_PRIORITY', AttributeFourByteValue
),
4059 RTA_PREFSRC
: ('RTA_PREFSRC', AttributeIPAddress
),
4060 RTA_METRICS
: ('RTA_METRICS', AttributeGeneric
),
4061 RTA_MULTIPATH
: ('RTA_MULTIPATH', AttributeRTA_MULTIPATH
),
4062 RTA_PROTOINFO
: ('RTA_PROTOINFO', AttributeGeneric
),
4063 RTA_FLOW
: ('RTA_FLOW', AttributeGeneric
),
4064 RTA_CACHEINFO
: ('RTA_CACHEINFO', AttributeGeneric
),
4065 RTA_SESSION
: ('RTA_SESSION', AttributeGeneric
),
4066 RTA_MP_ALGO
: ('RTA_MP_ALGO', AttributeGeneric
),
4067 RTA_TABLE
: ('RTA_TABLE', AttributeFourByteValue
),
4068 RTA_MARK
: ('RTA_MARK', AttributeGeneric
),
4069 RTA_MFC_STATS
: ('RTA_MFC_STATS', AttributeGeneric
),
4070 RTA_VIA
: ('RTA_VIA', AttributeGeneric
),
4071 RTA_NEWDST
: ('RTA_NEWDST', AttributeGeneric
),
4072 RTA_PREF
: ('RTA_PREF', AttributeGeneric
),
4073 RTA_ENCAP_TYPE
: ('RTA_ENCAP_TYPE', AttributeGeneric
),
4074 RTA_ENCAP
: ('RTA_ENCAP', AttributeGeneric
)
4078 # /usr/include/linux/rtnetlink.h
4079 RT_TABLE_UNSPEC
= 0x00 # An unspecified routing table
4080 RT_TABLE_COMPAT
= 0xFC
4081 RT_TABLE_DEFAULT
= 0xFD # The default table
4082 RT_TABLE_MAIN
= 0xFE # The main table
4083 RT_TABLE_LOCAL
= 0xFF # The local table
4086 RT_TABLE_UNSPEC
: 'RT_TABLE_UNSPEC',
4087 RT_TABLE_COMPAT
: 'RT_TABLE_COMPAT',
4088 RT_TABLE_DEFAULT
: 'RT_TABLE_DEFAULT',
4089 RT_TABLE_MAIN
: 'RT_TABLE_MAIN',
4090 RT_TABLE_LOCAL
: 'RT_TABLE_LOCAL'
4094 # /usr/include/linux/rtnetlink.h
4095 RT_SCOPE_UNIVERSE
= 0x00 # Global route
4096 RT_SCOPE_SITE
= 0xC8 # Interior route in the local autonomous system
4097 RT_SCOPE_LINK
= 0xFD # Route on this link
4098 RT_SCOPE_HOST
= 0xFE # Route on the local host
4099 RT_SCOPE_NOWHERE
= 0xFF # Destination does not exist
4102 RT_SCOPE_UNIVERSE
: 'RT_SCOPE_UNIVERSE',
4103 RT_SCOPE_SITE
: 'RT_SCOPE_SITE',
4104 RT_SCOPE_LINK
: 'RT_SCOPE_LINK',
4105 RT_SCOPE_HOST
: 'RT_SCOPE_HOST',
4106 RT_SCOPE_NOWHERE
: 'RT_SCOPE_NOWHERE'
4109 # Route scope to string
4110 # iproute2/lib/rt_names.c
4111 rtnl_rtscope_tab
= {
4112 RT_SCOPE_UNIVERSE
: 'global',
4113 RT_SCOPE_NOWHERE
: 'nowhere',
4114 RT_SCOPE_HOST
: 'host',
4115 RT_SCOPE_LINK
: 'link',
4116 RT_SCOPE_SITE
: 'site'
4120 # /usr/include/linux/rtnetlink.h
4121 RT_PROT_UNSPEC
= 0x00 # Identifies what/who added the route
4122 RT_PROT_REDIRECT
= 0x01 # By an ICMP redirect
4123 RT_PROT_KERNEL
= 0x02 # By the kernel
4124 RT_PROT_BOOT
= 0x03 # During bootup
4125 RT_PROT_STATIC
= 0x04 # By the administrator
4126 RT_PROT_GATED
= 0x08 # GateD
4127 RT_PROT_RA
= 0x09 # RDISC/ND router advertissements
4128 RT_PROT_MRT
= 0x0A # Merit MRT
4129 RT_PROT_ZEBRA
= 0x0B # ZEBRA
4130 RT_PROT_BIRD
= 0x0C # BIRD
4131 RT_PROT_DNROUTED
= 0x0D # DECnet routing daemon
4132 RT_PROT_XORP
= 0x0E # XORP
4133 RT_PROT_NTK
= 0x0F # Netsukuku
4134 RT_PROT_DHCP
= 0x10 # DHCP client
4135 RT_PROT_EXABGP
= 0x11 # Exa Networks ExaBGP
4138 RT_PROT_UNSPEC
: 'RT_PROT_UNSPEC',
4139 RT_PROT_REDIRECT
: 'RT_PROT_REDIRECT',
4140 RT_PROT_KERNEL
: 'RT_PROT_KERNEL',
4141 RT_PROT_BOOT
: 'RT_PROT_BOOT',
4142 RT_PROT_STATIC
: 'RT_PROT_STATIC',
4143 RT_PROT_GATED
: 'RT_PROT_GATED',
4144 RT_PROT_RA
: 'RT_PROT_RA',
4145 RT_PROT_MRT
: 'RT_PROT_MRT',
4146 RT_PROT_ZEBRA
: 'RT_PROT_ZEBRA',
4147 RT_PROT_BIRD
: 'RT_PROT_BIRD',
4148 RT_PROT_DNROUTED
: 'RT_PROT_DNROUTED',
4149 RT_PROT_XORP
: 'RT_PROT_XORP',
4150 RT_PROT_NTK
: 'RT_PROT_NTK',
4151 RT_PROT_DHCP
: 'RT_PROT_DHCP',
4152 RT_PROT_EXABGP
: 'RT_PROT_EXABGP'
4156 # /usr/include/linux/rtnetlink.h
4157 RTN_UNSPEC
= 0x00 # Unknown broker.
4158 RTN_UNICAST
= 0x01 # A gateway or direct broker.
4159 RTN_LOCAL
= 0x02 # A local interface broker.
4160 RTN_BROADCAST
= 0x03 # A local broadcast route(sent as a broadcast).
4161 RTN_ANYCAST
= 0x04 # An anycast broker.
4162 RTN_MULTICAST
= 0x05 # A multicast broker.
4163 RTN_BLACKHOLE
= 0x06 # A silent packet dropping broker.
4164 RTN_UNREACHABLE
= 0x07 # An unreachable destination. Packets dropped and
4165 # host unreachable ICMPs are sent to the originator.
4166 RTN_PROHIBIT
= 0x08 # A packet rejection broker. Packets are dropped and
4167 # communication prohibited ICMPs are sent to the originator.
4168 RTN_THROW
= 0x09 # When used with policy routing, continue routing lookup
4169 # in another table. Under normal routing, packets are
4170 # dropped and net unreachable ICMPs are sent to the originator.
4171 RTN_NAT
= 0x0A # A network address translation rule.
4172 RTN_XRESOLVE
= 0x0B # Refer to an external resolver(not implemented).
4174 rt_type_to_string
= {
4175 RTN_UNSPEC
: 'RTN_UNSPEC',
4176 RTN_UNICAST
: 'RTN_UNICAST',
4177 RTN_LOCAL
: 'RTN_LOCAL',
4178 RTN_BROADCAST
: 'RTN_BROADCAST',
4179 RTN_ANYCAST
: 'RTN_ANYCAST',
4180 RTN_MULTICAST
: 'RTN_MULTICAST',
4181 RTN_BLACKHOLE
: 'RTN_BLACKHOLE',
4182 RTN_UNREACHABLE
: 'RTN_UNREACHABLE',
4183 RTN_PROHIBIT
: 'RTN_PROHIBIT',
4184 RTN_THROW
: 'RTN_THROW',
4185 RTN_NAT
: 'RTN_NAT',
4186 RTN_XRESOLVE
: 'RTN_XRESOLVE'
4190 # /usr/include/linux/rtnetlink.h
4191 RTM_F_NOTIFY
= 0x100 # If the route changes, notify the user
4192 RTM_F_CLONED
= 0x200 # Route is cloned from another route
4193 RTM_F_EQUALIZE
= 0x400 # Allow randomization of next hop path in multi-path routing(currently not implemented)
4194 RTM_F_PREFIX
= 0x800 # Prefix Address
4197 RTM_F_NOTIFY
: 'RTM_F_NOTIFY',
4198 RTM_F_CLONED
: 'RTM_F_CLONED',
4199 RTM_F_EQUALIZE
: 'RTM_F_EQUALIZE',
4200 RTM_F_PREFIX
: 'RTM_F_PREFIX'
4203 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
4204 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
4205 self
.PACK
= '=8BI' # or is it 8Bi ?
4206 self
.LEN
= calcsize(self
.PACK
)
4208 def get_prefix_string(self
):
4209 dst
= self
.get_attribute_value(self
.RTA_DST
)
4212 return "%s/%d" % (dst
, self
.src_len
)
4214 if self
.family
== AF_INET
:
4216 elif self
.family
== AF_INET6
:
4219 def get_protocol_string(self
, index
=None):
4221 index
= self
.protocol
4222 return self
.get_string(self
.prot_to_string
, index
)
4224 def get_rt_type_string(self
, index
=None):
4226 index
= self
.route_type
4227 return self
.get_string(self
.rt_type_to_string
, index
)
4229 def get_scope_string(self
, index
=None):
4232 return self
.get_string(self
.scope_to_string
, index
)
4234 def get_table_id_string(self
, index
=None):
4236 index
= self
.table_id
4237 return self
.get_string(self
.table_to_string
, index
)
4239 def _get_ifname_from_index(self
, ifindex
, ifname_by_index
):
4241 ifname
= ifname_by_index
.get(ifindex
)
4244 ifname
= str(ifindex
)
4250 def get_nexthops(self
, ifname_by_index
={}):
4251 nexthop
= self
.get_attribute_value(self
.RTA_GATEWAY
)
4252 multipath
= self
.get_attribute_value(self
.RTA_MULTIPATH
)
4256 rta_oif
= self
.get_attribute_value(self
.RTA_OIF
)
4257 ifname
= self
._get
_ifname
_from
_index
(rta_oif
, ifname_by_index
)
4258 nexthops
.append((nexthop
, ifname
))
4261 for (nexthop
, rtnh_ifindex
, rtnh_flags
, rtnh_hops
) in multipath
:
4262 ifname
= self
._get
_ifname
_from
_index
(rtnh_ifindex
, ifname_by_index
)
4263 nexthops
.append((nexthop
, ifname
))
4267 def get_nexthops_string(self
, ifname_by_index
={}):
4270 for (nexthop
, ifname
) in self
.get_nexthops(ifname_by_index
):
4271 output
.append(" via %s on %s" % (nexthop
, ifname
))
4273 return ",".join(output
)
4275 def decode_service_header(self
):
4277 # Nothing to do if the message did not contain a service header
4278 if self
.length
== self
.header_LEN
:
4281 (self
.family
, self
.src_len
, self
.dst_len
, self
.tos
,
4282 self
.table_id
, self
.protocol
, self
.scope
, self
.route_type
,
4284 unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
4287 color
= yellow
if self
.use_color
else None
4288 color_start
= "\033[%dm" % color
if color
else ""
4289 color_end
= "\033[0m" if color
else ""
4290 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
4292 for x
in range(0, self
.LEN
/4):
4293 if self
.line_number
== 5:
4294 extra
= "Family %s (%s:%d), Source Length %s (%d), Destination Length %s (%d), TOS %s (%d)" % \
4295 (zfilled_hex(self
.family
, 2), get_family_str(self
.family
), self
.family
,
4296 zfilled_hex(self
.src_len
, 2), self
.src_len
,
4297 zfilled_hex(self
.dst_len
, 2), self
.dst_len
,
4298 zfilled_hex(self
.tos
, 2), self
.tos
)
4299 elif self
.line_number
== 6:
4300 extra
= "Table ID %s (%d - %s), Protocol %s (%d - %s), Scope %s (%d - %s), Type %s (%d - %s)" % \
4301 (zfilled_hex(self
.table_id
, 2), self
.table_id
, self
.get_table_id_string(),
4302 zfilled_hex(self
.protocol
, 2), self
.protocol
, self
.get_protocol_string(),
4303 zfilled_hex(self
.scope
, 2), self
.scope
, self
.get_scope_string(),
4304 zfilled_hex(self
.route_type
, 2), self
.route_type
, self
.get_rt_type_string())
4305 elif self
.line_number
== 7:
4306 extra
= "Flags %s" % zfilled_hex(self
.flags
, 8)
4308 extra
= "Unexpected line number %d" % self
.line_number
4312 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
4313 self
.line_number
+= 1
4315 class Done(NetlinkPacket
):
4321 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
4322 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4324 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4327 def __init__(self
, msgtype
, debug
=False, logger
=None, use_color
=True):
4328 NetlinkPacket
.__init
__(self
, msgtype
, debug
, logger
, use_color
)
4330 self
.LEN
= calcsize(self
.PACK
)
4332 def decode_service_header(self
):
4333 foo
= unpack(self
.PACK
, self
.msg_data
[:self
.LEN
])
4336 color
= yellow
if self
.use_color
else None
4337 color_start
= "\033[%dm" % color
if color
else ""
4338 color_end
= "\033[0m" if color
else ""
4339 self
.dump_buffer
.append(" %sService Header%s" % (color_start
, color_end
))
4341 for x
in range(0, self
.LEN
/4):
4345 self
.dump_buffer
.append(data_to_color_text(self
.line_number
, color
, self
.msg_data
[start
:end
], extra
))
4346 self
.line_number
+= 1