]> git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/nlmanager/nlpacket.py
Merge branch 'master-next' into python3
[mirror_ifupdown2.git] / ifupdown2 / nlmanager / nlpacket.py
1 # Copyright (c) 2009-2013, Exa Networks Limited
2 # Copyright (c) 2009-2013, Thomas Mangin
3 # Copyright (c) 2015-2020 Cumulus Networks, Inc.
4 #
5 # All rights reserved.
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are met:
8 #
9 # Redistributions of source code must retain the above copyright notice, this
10 # list of conditions and the following disclaimer.
11 #
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.
15 #
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.
19 #
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.
30
31 import socket
32 import logging
33 import struct
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
39
40
41 from . import ipnetwork
42
43
44 log = logging.getLogger(__name__)
45 SYSLOG_EXTRA_DEBUG = 5
46
47 ETH_P_IP = 0x0800
48 ETH_P_IPV6 = 0x86DD
49
50 INFINITY_LIFE_TIME = 0xFFFFFFFF
51
52 # Interface name buffer size #define IFNAMSIZ 16 (kernel source)
53 IF_NAME_SIZE = 15 # 15 because python doesn't have \0
54
55 # Netlink message types
56 NLMSG_NOOP = 0x01
57 NLMSG_ERROR = 0x02
58 NLMSG_DONE = 0x03
59 NLMSG_OVERRUN = 0x04
60
61 RTM_NEWLINK = 0x10 # Create a new network interface
62 RTM_DELLINK = 0x11 # Destroy a network interface
63 RTM_GETLINK = 0x12 # Retrieve information about a network interface(ifinfomsg)
64 RTM_SETLINK = 0x13 #
65
66 RTM_NEWADDR = 0x14
67 RTM_DELADDR = 0x15
68 RTM_GETADDR = 0x16
69
70 RTM_NEWNEIGH = 0x1C
71 RTM_DELNEIGH = 0x1D
72 RTM_GETNEIGH = 0x1E
73
74 RTM_NEWROUTE = 0x18
75 RTM_DELROUTE = 0x19
76 RTM_GETROUTE = 0x1A
77
78 RTM_NEWQDISC = 0x24
79 RTM_DELQDISC = 0x25
80 RTM_GETQDISC = 0x26
81
82 RTM_NEWNETCONF = 80
83 RTM_DELNETCONF = 81
84 RTM_GETNETCONF = 82
85
86 RTM_NEWMDB = 84
87 RTM_DELMDB = 85
88 RTM_GETMDB = 86
89
90 # Netlink message flags
91 NLM_F_REQUEST = 0x01 # It is query message.
92 NLM_F_MULTI = 0x02 # Multipart message, terminated by NLMSG_DONE
93 NLM_F_ACK = 0x04 # Reply with ack, with zero or error code
94 NLM_F_ECHO = 0x08 # Echo this query
95
96 # Modifiers to GET query
97 NLM_F_ROOT = 0x100 # specify tree root
98 NLM_F_MATCH = 0x200 # return all matching
99 NLM_F_DUMP = NLM_F_ROOT | NLM_F_MATCH
100 NLM_F_ATOMIC = 0x400 # atomic GET
101
102 # Modifiers to NEW query
103 NLM_F_REPLACE = 0x100 # Override existing
104 NLM_F_EXCL = 0x200 # Do not touch, if it exists
105 NLM_F_CREATE = 0x400 # Create, if it does not exist
106 NLM_F_APPEND = 0x800 # Add to end of list
107
108 NLA_F_NESTED = 0x8000
109 NLA_F_NET_BYTEORDER = 0x4000
110 NLA_TYPE_MASK = ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
111
112 # Groups
113 RTMGRP_LINK = 0x1
114 RTMGRP_NOTIFY = 0x2
115 RTMGRP_NEIGH = 0x4
116 RTMGRP_TC = 0x8
117 RTMGRP_IPV4_IFADDR = 0x10
118 RTMGRP_IPV4_MROUTE = 0x20
119 RTMGRP_IPV4_ROUTE = 0x40
120 RTMGRP_IPV4_RULE = 0x80
121 RTMGRP_IPV6_IFADDR = 0x100
122 RTMGRP_IPV6_MROUTE = 0x200
123 RTMGRP_IPV6_ROUTE = 0x400
124 RTMGRP_IPV6_IFINFO = 0x800
125 RTMGRP_DECnet_IFADDR = 0x1000
126 RTMGRP_DECnet_ROUTE = 0x4000
127 RTMGRP_IPV6_PREFIX = 0x20000
128 RTNLGRP_MDB = 0x1A
129
130
131 def nl_mgrp(group):
132 """
133 The api is a reimplementation of "nl_mgrp" function from
134 iproute2/include/utils.h
135 """
136 if group > 31:
137 raise Exception("%d Invalid Group" % group)
138 else:
139 group = (1 << (group - 1)) if group else 0
140 return group
141
142
143 RTNLGRP_IPV4_NETCONF = nl_mgrp(24)
144 RTNLGRP_IPV6_NETCONF = nl_mgrp(25)
145 RTNLGRP_MPLS_NETCONF = nl_mgrp(29)
146
147
148 RTMGRP_ALL = (RTMGRP_LINK | RTMGRP_NOTIFY | RTMGRP_NEIGH | RTMGRP_TC |
149 RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_MROUTE | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_RULE |
150 RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_MROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFINFO |
151 RTMGRP_DECnet_IFADDR | RTMGRP_DECnet_ROUTE | nl_mgrp(RTNLGRP_MDB) |
152 RTMGRP_IPV6_PREFIX | RTNLGRP_IPV4_NETCONF | RTNLGRP_IPV6_NETCONF | RTNLGRP_MPLS_NETCONF)
153
154 # /etc/iproute2/rt_scopes
155 RT_SCOPES = {
156 "global": 0,
157 "universe": 0,
158 "nowhere": 255,
159 "host": 254,
160 "link": 253,
161 "site": 200
162 }
163
164 AF_MPLS = 28
165
166
167 AF_FAMILY = dict()
168
169 for family in [attr for attr in dir(socket) if attr.startswith('AF_')]:
170 AF_FAMILY[getattr(socket, family)] = family
171
172 AF_FAMILY[AF_MPLS] = 'AF_MPLS'
173
174
175 def get_family_str(family):
176 return AF_FAMILY.get(family, 'UNKNOWN')
177
178 # Colors for logging
179 red = 91
180 green = 92
181 yellow = 93
182 blue = 94
183
184 value_to_bool_dict = {
185 False: False,
186 None: False,
187 0: False,
188 '0': False,
189 'no': False,
190 'off': False,
191 'slow': False,
192 'None': False,
193 True: True,
194 1: True,
195 '1': True,
196 'on': True,
197 'yes': True,
198 'fast': True
199 }
200
201
202 def set_log_level(level):
203 log.setLevel(level)
204
205
206 def zfilled_hex(value, digits):
207 return '0x' + hex(value)[2:].zfill(digits)
208
209
210 def remove_trailing_null(line):
211 """
212 Remove the last character if it is a NULL...having that NULL
213 causes python to print a garbage character
214 """
215 if line[-1] == 0:
216 line = line[:-1]
217
218 return line
219
220
221 mac_int_to_str = lambda mac_int: ":".join(("%012x" % mac_int)[i:i + 2] for i in range(0, 12, 2))
222
223
224 def data_to_color_text(line_number, color, data, extra=''):
225 (c1, c2, c3, c4) = unpack('BBBB', data[0:4])
226 in_ascii = []
227
228 for c in (c1, c2, c3, c4):
229 char_c = chr(c)
230
231 if char_c in printable[:-5]:
232 in_ascii.append(char_c)
233 else:
234 in_ascii.append('.')
235
236 if color:
237 return ' %2d: \033[%dm0x%02x%02x%02x%02x\033[0m %s %s' % (line_number, color, c1, c2, c3, c4, ''.join(in_ascii), extra)
238
239 return ' %2d: 0x%02x%02x%02x%02x %s %s' % (line_number, c1, c2, c3, c4, ''.join(in_ascii), extra)
240
241
242 def padded_length(length):
243 return int((length + 3) // 4) * 4
244
245
246 class NetlinkPacket_IFLA_LINKINFO_Attributes:
247
248 # =========================================
249 # IFLA_LINKINFO attributes
250 # =========================================
251 IFLA_INFO_UNSPEC = 0
252 IFLA_INFO_KIND = 1
253 IFLA_INFO_DATA = 2
254 IFLA_INFO_XSTATS = 3
255 IFLA_INFO_SLAVE_KIND = 4
256 IFLA_INFO_SLAVE_DATA = 5
257 IFLA_INFO_MAX = 6
258
259 ifla_info_to_string = {
260 IFLA_INFO_UNSPEC : 'IFLA_INFO_UNSPEC',
261 IFLA_INFO_KIND : 'IFLA_INFO_KIND',
262 IFLA_INFO_DATA : 'IFLA_INFO_DATA',
263 IFLA_INFO_XSTATS : 'IFLA_INFO_XSTATS',
264 IFLA_INFO_SLAVE_KIND : 'IFLA_INFO_SLAVE_KIND',
265 IFLA_INFO_SLAVE_DATA : 'IFLA_INFO_SLAVE_DATA',
266 IFLA_INFO_MAX : 'IFLA_INFO_MAX'
267 }
268
269 # =========================================
270 # IFLA_INFO_DATA attributes for vlan
271 # =========================================
272 IFLA_VLAN_UNSPEC = 0
273 IFLA_VLAN_ID = 1
274 IFLA_VLAN_FLAGS = 2
275 IFLA_VLAN_EGRESS_QOS = 3
276 IFLA_VLAN_INGRESS_QOS = 4
277 IFLA_VLAN_PROTOCOL = 5
278
279 ifla_vlan_to_string = {
280 IFLA_VLAN_UNSPEC : 'IFLA_VLAN_UNSPEC',
281 IFLA_VLAN_ID : 'IFLA_VLAN_ID',
282 IFLA_VLAN_FLAGS : 'IFLA_VLAN_FLAGS',
283 IFLA_VLAN_EGRESS_QOS : 'IFLA_VLAN_EGRESS_QOS',
284 IFLA_VLAN_INGRESS_QOS : 'IFLA_VLAN_INGRESS_QOS',
285 IFLA_VLAN_PROTOCOL : 'IFLA_VLAN_PROTOCOL'
286 }
287
288 ifla_vlan_protocol_dict = {
289 '802.1Q': 0x8100,
290 '802.1q': 0x8100,
291
292 '802.1ad': 0x88A8,
293 '802.1AD': 0x88A8,
294 '802.1Ad': 0x88A8,
295 '802.1aD': 0x88A8,
296
297 0x8100: '802.1Q',
298 0x88A8: '802.1ad'
299 }
300
301 # =========================================
302 # IFLA_INFO_DATA attributes for macvlan
303 # =========================================
304 IFLA_MACVLAN_UNSPEC = 0
305 IFLA_MACVLAN_MODE = 1
306
307 ifla_macvlan_to_string = {
308 IFLA_MACVLAN_UNSPEC : 'IFLA_MACVLAN_UNSPEC',
309 IFLA_MACVLAN_MODE : 'IFLA_MACVLAN_MODE'
310 }
311
312 # enum macvlan_mode
313 MACVLAN_MODE_PRIVATE = 1 # don't talk to other macvlans */
314 MACVLAN_MODE_VEPA = 2 # talk to other ports through ext bridge */
315 MACVLAN_MODE_BRIDGE = 4 # talk to bridge ports directly */
316 MACVLAN_MODE_PASSTHRU = 8 # take over the underlying device */
317 MACVLAN_MODE_SOURCE = 16 # use source MAC address list to assign */
318
319 macvlan_mode_to_string = {
320 MACVLAN_MODE_PRIVATE : 'MACVLAN_MODE_PRIVATE',
321 MACVLAN_MODE_VEPA : 'MACVLAN_MODE_VEPA',
322 MACVLAN_MODE_BRIDGE : 'MACVLAN_MODE_BRIDGE',
323 MACVLAN_MODE_PASSTHRU : 'MACVLAN_MODE_PASSTHRU',
324 MACVLAN_MODE_SOURCE : 'MACVLAN_MODE_SOURCE'
325 }
326
327 # =========================================
328 # IFLA_INFO_DATA attributes for xfrm
329 # =========================================
330 IFLA_XFRM_UNSPEC = 0
331 IFLA_XFRM_LINK = 1
332 IFLA_XFRM_IF_ID = 2
333
334 ifla_xfrm_to_string = {
335 IFLA_XFRM_UNSPEC: 'IFLA_XFRM_UNSPEC',
336 IFLA_XFRM_LINK : 'IFLA_XFRM_LINK',
337 IFLA_XFRM_IF_ID : 'IFLA_XFRM_IF_ID'
338 }
339
340 # =========================================
341 # IFLA_INFO_DATA attributes for vxlan
342 # =========================================
343 IFLA_VXLAN_UNSPEC = 0
344 IFLA_VXLAN_ID = 1
345 IFLA_VXLAN_GROUP = 2
346 IFLA_VXLAN_LINK = 3
347 IFLA_VXLAN_LOCAL = 4
348 IFLA_VXLAN_TTL = 5
349 IFLA_VXLAN_TOS = 6
350 IFLA_VXLAN_LEARNING = 7
351 IFLA_VXLAN_AGEING = 8
352 IFLA_VXLAN_LIMIT = 9
353 IFLA_VXLAN_PORT_RANGE = 10
354 IFLA_VXLAN_PROXY = 11
355 IFLA_VXLAN_RSC = 12
356 IFLA_VXLAN_L2MISS = 13
357 IFLA_VXLAN_L3MISS = 14
358 IFLA_VXLAN_PORT = 15
359 IFLA_VXLAN_GROUP6 = 16
360 IFLA_VXLAN_LOCAL6 = 17
361 IFLA_VXLAN_UDP_CSUM = 18
362 IFLA_VXLAN_UDP_ZERO_CSUM6_TX = 19
363 IFLA_VXLAN_UDP_ZERO_CSUM6_RX = 20
364 IFLA_VXLAN_REMCSUM_TX = 21
365 IFLA_VXLAN_REMCSUM_RX = 22
366 IFLA_VXLAN_GBP = 23
367 IFLA_VXLAN_REMCSUM_NOPARTIAL = 24
368 IFLA_VXLAN_COLLECT_METADATA = 25
369 IFLA_VXLAN_REPLICATION_NODE = 253
370 IFLA_VXLAN_REPLICATION_TYPE = 254
371
372 ifla_vxlan_to_string = {
373 IFLA_VXLAN_UNSPEC : 'IFLA_VXLAN_UNSPEC',
374 IFLA_VXLAN_ID : 'IFLA_VXLAN_ID',
375 IFLA_VXLAN_GROUP : 'IFLA_VXLAN_GROUP',
376 IFLA_VXLAN_LINK : 'IFLA_VXLAN_LINK',
377 IFLA_VXLAN_LOCAL : 'IFLA_VXLAN_LOCAL',
378 IFLA_VXLAN_TTL : 'IFLA_VXLAN_TTL',
379 IFLA_VXLAN_TOS : 'IFLA_VXLAN_TOS',
380 IFLA_VXLAN_LEARNING : 'IFLA_VXLAN_LEARNING',
381 IFLA_VXLAN_AGEING : 'IFLA_VXLAN_AGEING',
382 IFLA_VXLAN_LIMIT : 'IFLA_VXLAN_LIMIT',
383 IFLA_VXLAN_PORT_RANGE : 'IFLA_VXLAN_PORT_RANGE',
384 IFLA_VXLAN_PROXY : 'IFLA_VXLAN_PROXY',
385 IFLA_VXLAN_RSC : 'IFLA_VXLAN_RSC',
386 IFLA_VXLAN_L2MISS : 'IFLA_VXLAN_L2MISS',
387 IFLA_VXLAN_L3MISS : 'IFLA_VXLAN_L3MISS',
388 IFLA_VXLAN_PORT : 'IFLA_VXLAN_PORT',
389 IFLA_VXLAN_GROUP6 : 'IFLA_VXLAN_GROUP6',
390 IFLA_VXLAN_LOCAL6 : 'IFLA_VXLAN_LOCAL6',
391 IFLA_VXLAN_UDP_CSUM : 'IFLA_VXLAN_UDP_CSUM',
392 IFLA_VXLAN_UDP_ZERO_CSUM6_TX : 'IFLA_VXLAN_UDP_ZERO_CSUM6_TX',
393 IFLA_VXLAN_UDP_ZERO_CSUM6_RX : 'IFLA_VXLAN_UDP_ZERO_CSUM6_RX',
394 IFLA_VXLAN_REMCSUM_TX : 'IFLA_VXLAN_REMCSUM_TX',
395 IFLA_VXLAN_REMCSUM_RX : 'IFLA_VXLAN_REMCSUM_RX',
396 IFLA_VXLAN_GBP : 'IFLA_VXLAN_GBP',
397 IFLA_VXLAN_REMCSUM_NOPARTIAL : 'IFLA_VXLAN_REMCSUM_NOPARTIAL',
398 IFLA_VXLAN_COLLECT_METADATA : 'IFLA_VXLAN_COLLECT_METADATA',
399 IFLA_VXLAN_REPLICATION_NODE : 'IFLA_VXLAN_REPLICATION_NODE',
400 IFLA_VXLAN_REPLICATION_TYPE : 'IFLA_VXLAN_REPLICATION_TYPE'
401 }
402
403 # =========================================
404 # IFLA_INFO_DATA attributes for bonds
405 # =========================================
406 IFLA_BOND_UNSPEC = 0
407 IFLA_BOND_MODE = 1
408 IFLA_BOND_ACTIVE_SLAVE = 2
409 IFLA_BOND_MIIMON = 3
410 IFLA_BOND_UPDELAY = 4
411 IFLA_BOND_DOWNDELAY = 5
412 IFLA_BOND_USE_CARRIER = 6
413 IFLA_BOND_ARP_INTERVAL = 7
414 IFLA_BOND_ARP_IP_TARGET = 8
415 IFLA_BOND_ARP_VALIDATE = 9
416 IFLA_BOND_ARP_ALL_TARGETS = 10
417 IFLA_BOND_PRIMARY = 11
418 IFLA_BOND_PRIMARY_RESELECT = 12
419 IFLA_BOND_FAIL_OVER_MAC = 13
420 IFLA_BOND_XMIT_HASH_POLICY = 14
421 IFLA_BOND_RESEND_IGMP = 15
422 IFLA_BOND_NUM_PEER_NOTIF = 16
423 IFLA_BOND_ALL_SLAVES_ACTIVE = 17
424 IFLA_BOND_MIN_LINKS = 18
425 IFLA_BOND_LP_INTERVAL = 19
426 IFLA_BOND_PACKETS_PER_SLAVE = 20
427 IFLA_BOND_AD_LACP_RATE = 21
428 IFLA_BOND_AD_SELECT = 22
429 IFLA_BOND_AD_INFO = 23
430 IFLA_BOND_AD_ACTOR_SYS_PRIO = 24
431 IFLA_BOND_AD_USER_PORT_KEY = 25
432 IFLA_BOND_AD_ACTOR_SYSTEM = 26
433 IFLA_BOND_CL_START = 60
434 IFLA_BOND_AD_LACP_BYPASS = IFLA_BOND_CL_START
435
436
437 ifla_bond_to_string = {
438 IFLA_BOND_UNSPEC : 'IFLA_BOND_UNSPEC',
439 IFLA_BOND_MODE : 'IFLA_BOND_MODE',
440 IFLA_BOND_ACTIVE_SLAVE : 'IFLA_BOND_ACTIVE_SLAVE',
441 IFLA_BOND_MIIMON : 'IFLA_BOND_MIIMON',
442 IFLA_BOND_UPDELAY : 'IFLA_BOND_UPDELAY',
443 IFLA_BOND_DOWNDELAY : 'IFLA_BOND_DOWNDELAY',
444 IFLA_BOND_USE_CARRIER : 'IFLA_BOND_USE_CARRIER',
445 IFLA_BOND_ARP_INTERVAL : 'IFLA_BOND_ARP_INTERVAL',
446 IFLA_BOND_ARP_IP_TARGET : 'IFLA_BOND_ARP_IP_TARGET',
447 IFLA_BOND_ARP_VALIDATE : 'IFLA_BOND_ARP_VALIDATE',
448 IFLA_BOND_ARP_ALL_TARGETS : 'IFLA_BOND_ARP_ALL_TARGETS',
449 IFLA_BOND_PRIMARY : 'IFLA_BOND_PRIMARY',
450 IFLA_BOND_PRIMARY_RESELECT : 'IFLA_BOND_PRIMARY_RESELECT',
451 IFLA_BOND_FAIL_OVER_MAC : 'IFLA_BOND_FAIL_OVER_MAC',
452 IFLA_BOND_XMIT_HASH_POLICY : 'IFLA_BOND_XMIT_HASH_POLICY',
453 IFLA_BOND_RESEND_IGMP : 'IFLA_BOND_RESEND_IGMP',
454 IFLA_BOND_NUM_PEER_NOTIF : 'IFLA_BOND_NUM_PEER_NOTIF',
455 IFLA_BOND_ALL_SLAVES_ACTIVE : 'IFLA_BOND_ALL_SLAVES_ACTIVE',
456 IFLA_BOND_MIN_LINKS : 'IFLA_BOND_MIN_LINKS',
457 IFLA_BOND_LP_INTERVAL : 'IFLA_BOND_LP_INTERVAL',
458 IFLA_BOND_PACKETS_PER_SLAVE : 'IFLA_BOND_PACKETS_PER_SLAVE',
459 IFLA_BOND_AD_LACP_RATE : 'IFLA_BOND_AD_LACP_RATE',
460 IFLA_BOND_AD_SELECT : 'IFLA_BOND_AD_SELECT',
461 IFLA_BOND_AD_INFO : 'IFLA_BOND_AD_INFO',
462 IFLA_BOND_AD_ACTOR_SYS_PRIO : 'IFLA_BOND_AD_ACTOR_SYS_PRIO',
463 IFLA_BOND_AD_USER_PORT_KEY : 'IFLA_BOND_AD_USER_PORT_KEY',
464 IFLA_BOND_AD_ACTOR_SYSTEM : 'IFLA_BOND_AD_ACTOR_SYSTEM',
465 IFLA_BOND_CL_START : 'IFLA_BOND_CL_START',
466 IFLA_BOND_AD_LACP_BYPASS : 'IFLA_BOND_AD_LACP_BYPASS'
467 }
468
469 IFLA_BOND_AD_INFO_UNSPEC = 0
470 IFLA_BOND_AD_INFO_AGGREGATOR = 1
471 IFLA_BOND_AD_INFO_NUM_PORTS = 2
472 IFLA_BOND_AD_INFO_ACTOR_KEY = 3
473 IFLA_BOND_AD_INFO_PARTNER_KEY = 4
474 IFLA_BOND_AD_INFO_PARTNER_MAC = 5
475
476 ifla_bond_ad_to_string = {
477 IFLA_BOND_AD_INFO_UNSPEC : 'IFLA_BOND_AD_INFO_UNSPEC',
478 IFLA_BOND_AD_INFO_AGGREGATOR : 'IFLA_BOND_AD_INFO_AGGREGATOR',
479 IFLA_BOND_AD_INFO_NUM_PORTS : 'IFLA_BOND_AD_INFO_NUM_PORTS',
480 IFLA_BOND_AD_INFO_ACTOR_KEY : 'IFLA_BOND_AD_INFO_ACTOR_KEY',
481 IFLA_BOND_AD_INFO_PARTNER_KEY : 'IFLA_BOND_AD_INFO_PARTNER_KEY',
482 IFLA_BOND_AD_INFO_PARTNER_MAC : 'IFLA_BOND_AD_INFO_PARTNER_MAC'
483 }
484
485 ifla_bond_mode_tbl = {
486 'balance-rr': 0,
487 'active-backup': 1,
488 'balance-xor': 2,
489 'broadcast': 3,
490 '802.3ad': 4,
491 'balance-tlb': 5,
492 'balance-alb': 6,
493 '0': 0,
494 '1': 1,
495 '2': 2,
496 '3': 3,
497 '4': 4,
498 '5': 5,
499 '6': 6,
500 0: 0,
501 1: 1,
502 2: 2,
503 3: 3,
504 4: 4,
505 5: 5,
506 6: 6
507 }
508
509 ifla_bond_mode_pretty_tbl = {
510 0: 'balance-rr',
511 1: 'active-backup',
512 2: 'balance-xor',
513 3: 'broadcast',
514 4: '802.3ad',
515 5: 'balance-tlb',
516 6: 'balance-alb'
517 }
518
519 ifla_bond_xmit_hash_policy_tbl = {
520 'layer2': 0,
521 'layer3+4': 1,
522 'layer2+3': 2,
523 'encap2+3': 3,
524 'encap3+4': 4,
525 '0': 0,
526 '1': 1,
527 '2': 2,
528 '3': 3,
529 '4': 4,
530 0: 0,
531 1: 1,
532 2: 2,
533 3: 3,
534 4: 4
535 }
536
537 ifla_bond_xmit_hash_policy_pretty_tbl = {
538 0: 'layer2',
539 1: 'layer3+4',
540 2: 'layer2+3',
541 3: 'encap2+3',
542 4: 'encap3+4',
543 }
544
545 # =========================================
546 # IFLA_INFO_SLAVE_DATA attributes for bonds
547 # =========================================
548 IFLA_BOND_SLAVE_UNSPEC = 0
549 IFLA_BOND_SLAVE_STATE = 1
550 IFLA_BOND_SLAVE_MII_STATUS = 2
551 IFLA_BOND_SLAVE_LINK_FAILURE_COUNT = 3
552 IFLA_BOND_SLAVE_PERM_HWADDR = 4
553 IFLA_BOND_SLAVE_QUEUE_ID = 5
554 IFLA_BOND_SLAVE_AD_AGGREGATOR_ID = 6
555 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE = 7
556 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE = 8
557 IFLA_BOND_SLAVE_CL_START = 50
558 IFLA_BOND_SLAVE_AD_RX_BYPASS = IFLA_BOND_SLAVE_CL_START
559
560 ifla_bond_slave_to_string = {
561 IFLA_BOND_SLAVE_UNSPEC : 'IFLA_BOND_SLAVE_UNSPEC',
562 IFLA_BOND_SLAVE_STATE : 'IFLA_BOND_SLAVE_STATE',
563 IFLA_BOND_SLAVE_MII_STATUS : 'IFLA_BOND_SLAVE_MII_STATUS',
564 IFLA_BOND_SLAVE_LINK_FAILURE_COUNT : 'IFLA_BOND_SLAVE_LINK_FAILURE_COUNT',
565 IFLA_BOND_SLAVE_PERM_HWADDR : 'IFLA_BOND_SLAVE_PERM_HWADDR',
566 IFLA_BOND_SLAVE_QUEUE_ID : 'IFLA_BOND_SLAVE_QUEUE_ID',
567 IFLA_BOND_SLAVE_AD_AGGREGATOR_ID : 'IFLA_BOND_SLAVE_AD_AGGREGATOR_ID',
568 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE : 'IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE',
569 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE : 'IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE',
570 IFLA_BOND_SLAVE_CL_START : 'IFLA_BOND_SLAVE_CL_START',
571 IFLA_BOND_SLAVE_AD_RX_BYPASS : 'IFLA_BOND_SLAVE_AD_RX_BYPASS'
572 }
573
574 # =========================================
575 # IFLA_PROTINFO attributes for bridge ports
576 # =========================================
577 IFLA_BRPORT_UNSPEC = 0
578 IFLA_BRPORT_STATE = 1
579 IFLA_BRPORT_PRIORITY = 2
580 IFLA_BRPORT_COST = 3
581 IFLA_BRPORT_MODE = 4
582 IFLA_BRPORT_GUARD = 5
583 IFLA_BRPORT_PROTECT = 6
584 IFLA_BRPORT_FAST_LEAVE = 7
585 IFLA_BRPORT_LEARNING = 8
586 IFLA_BRPORT_UNICAST_FLOOD = 9
587 IFLA_BRPORT_PROXYARP = 10
588 IFLA_BRPORT_LEARNING_SYNC = 11
589 IFLA_BRPORT_PROXYARP_WIFI = 12
590 IFLA_BRPORT_ROOT_ID = 13
591 IFLA_BRPORT_BRIDGE_ID = 14
592 IFLA_BRPORT_DESIGNATED_PORT = 15
593 IFLA_BRPORT_DESIGNATED_COST = 16
594 IFLA_BRPORT_ID = 17
595 IFLA_BRPORT_NO = 18
596 IFLA_BRPORT_TOPOLOGY_CHANGE_ACK = 19
597 IFLA_BRPORT_CONFIG_PENDING = 20
598 IFLA_BRPORT_MESSAGE_AGE_TIMER = 21
599 IFLA_BRPORT_FORWARD_DELAY_TIMER = 22
600 IFLA_BRPORT_HOLD_TIMER = 23
601 IFLA_BRPORT_FLUSH = 24
602 IFLA_BRPORT_MULTICAST_ROUTER = 25
603 IFLA_BRPORT_PAD = 26
604 IFLA_BRPORT_MCAST_FLOOD = 27
605 IFLA_BRPORT_MCAST_TO_UCAST = 28
606 IFLA_BRPORT_VLAN_TUNNEL = 29
607 IFLA_BRPORT_BCAST_FLOOD = 30
608 IFLA_BRPORT_GROUP_FWD_MASK = 31
609 IFLA_BRPORT_NEIGH_SUPPRESS = 32
610 IFLA_BRPORT_ISOLATED = 33
611 IFLA_BRPORT_BACKUP_PORT = 34
612
613 IFLA_BRPORT_PEER_LINK = 60
614 IFLA_BRPORT_DUAL_LINK = 61
615 IFLA_BRPORT_GROUP_FWD_MASKHI = 62
616
617 ifla_brport_to_string = {
618 IFLA_BRPORT_UNSPEC : 'IFLA_BRPORT_UNSPEC',
619 IFLA_BRPORT_STATE : 'IFLA_BRPORT_STATE',
620 IFLA_BRPORT_PRIORITY : 'IFLA_BRPORT_PRIORITY',
621 IFLA_BRPORT_COST : 'IFLA_BRPORT_COST',
622 IFLA_BRPORT_MODE : 'IFLA_BRPORT_MODE',
623 IFLA_BRPORT_GUARD : 'IFLA_BRPORT_GUARD',
624 IFLA_BRPORT_PROTECT : 'IFLA_BRPORT_PROTECT',
625 IFLA_BRPORT_FAST_LEAVE : 'IFLA_BRPORT_FAST_LEAVE',
626 IFLA_BRPORT_LEARNING : 'IFLA_BRPORT_LEARNING',
627 IFLA_BRPORT_UNICAST_FLOOD : 'IFLA_BRPORT_UNICAST_FLOOD',
628 IFLA_BRPORT_PROXYARP : 'IFLA_BRPORT_PROXYARP',
629 IFLA_BRPORT_LEARNING_SYNC : 'IFLA_BRPORT_LEARNING_SYNC',
630 IFLA_BRPORT_PROXYARP_WIFI : 'IFLA_BRPORT_PROXYARP_WIFI',
631 IFLA_BRPORT_ROOT_ID : 'IFLA_BRPORT_ROOT_ID',
632 IFLA_BRPORT_BRIDGE_ID : 'IFLA_BRPORT_BRIDGE_ID',
633 IFLA_BRPORT_DESIGNATED_PORT : 'IFLA_BRPORT_DESIGNATED_PORT',
634 IFLA_BRPORT_DESIGNATED_COST : 'IFLA_BRPORT_DESIGNATED_COST',
635 IFLA_BRPORT_ID : 'IFLA_BRPORT_ID',
636 IFLA_BRPORT_NO : 'IFLA_BRPORT_NO',
637 IFLA_BRPORT_TOPOLOGY_CHANGE_ACK : 'IFLA_BRPORT_TOPOLOGY_CHANGE_ACK',
638 IFLA_BRPORT_CONFIG_PENDING : 'IFLA_BRPORT_CONFIG_PENDING',
639 IFLA_BRPORT_MESSAGE_AGE_TIMER : 'IFLA_BRPORT_MESSAGE_AGE_TIMER',
640 IFLA_BRPORT_FORWARD_DELAY_TIMER : 'IFLA_BRPORT_FORWARD_DELAY_TIMER',
641 IFLA_BRPORT_HOLD_TIMER : 'IFLA_BRPORT_HOLD_TIMER',
642 IFLA_BRPORT_FLUSH : 'IFLA_BRPORT_FLUSH',
643 IFLA_BRPORT_MULTICAST_ROUTER : 'IFLA_BRPORT_MULTICAST_ROUTER',
644 IFLA_BRPORT_PAD : 'IFLA_BRPORT_PAD',
645 IFLA_BRPORT_MCAST_FLOOD : 'IFLA_BRPORT_MCAST_FLOOD',
646 IFLA_BRPORT_MCAST_TO_UCAST : 'IFLA_BRPORT_MCAST_TO_UCAST',
647 IFLA_BRPORT_VLAN_TUNNEL : 'IFLA_BRPORT_VLAN_TUNNEL',
648 IFLA_BRPORT_BCAST_FLOOD : 'IFLA_BRPORT_BCAST_FLOOD',
649 IFLA_BRPORT_GROUP_FWD_MASK : 'IFLA_BRPORT_GROUP_FWD_MASK',
650 IFLA_BRPORT_NEIGH_SUPPRESS : 'IFLA_BRPORT_NEIGH_SUPPRESS',
651 IFLA_BRPORT_ISOLATED : 'IFLA_BRPORT_ISOLATED',
652 IFLA_BRPORT_BACKUP_PORT : 'IFLA_BRPORT_BACKUP_PORT',
653 IFLA_BRPORT_PEER_LINK : 'IFLA_BRPORT_PEER_LINK',
654 IFLA_BRPORT_DUAL_LINK : 'IFLA_BRPORT_DUAL_LINK',
655 IFLA_BRPORT_GROUP_FWD_MASKHI : 'IFLA_BRPORT_GROUP_FWD_MASKHI'
656 }
657
658 IFLA_BR_UNSPEC = 0
659 IFLA_BR_FORWARD_DELAY = 1
660 IFLA_BR_HELLO_TIME = 2
661 IFLA_BR_MAX_AGE = 3
662 IFLA_BR_AGEING_TIME = 4
663 IFLA_BR_STP_STATE = 5
664 IFLA_BR_PRIORITY = 6
665 IFLA_BR_VLAN_FILTERING = 7
666 IFLA_BR_VLAN_PROTOCOL = 8
667 IFLA_BR_GROUP_FWD_MASK = 9
668 IFLA_BR_ROOT_ID = 10
669 IFLA_BR_BRIDGE_ID = 11
670 IFLA_BR_ROOT_PORT = 12
671 IFLA_BR_ROOT_PATH_COST = 13
672 IFLA_BR_TOPOLOGY_CHANGE = 14
673 IFLA_BR_TOPOLOGY_CHANGE_DETECTED = 15
674 IFLA_BR_HELLO_TIMER = 16
675 IFLA_BR_TCN_TIMER = 17
676 IFLA_BR_TOPOLOGY_CHANGE_TIMER = 18
677 IFLA_BR_GC_TIMER = 19
678 IFLA_BR_GROUP_ADDR = 20
679 IFLA_BR_FDB_FLUSH = 21
680 IFLA_BR_MCAST_ROUTER = 22
681 IFLA_BR_MCAST_SNOOPING = 23
682 IFLA_BR_MCAST_QUERY_USE_IFADDR = 24
683 IFLA_BR_MCAST_QUERIER = 25
684 IFLA_BR_MCAST_HASH_ELASTICITY = 26
685 IFLA_BR_MCAST_HASH_MAX = 27
686 IFLA_BR_MCAST_LAST_MEMBER_CNT = 28
687 IFLA_BR_MCAST_STARTUP_QUERY_CNT = 29
688 IFLA_BR_MCAST_LAST_MEMBER_INTVL = 30
689 IFLA_BR_MCAST_MEMBERSHIP_INTVL = 31
690 IFLA_BR_MCAST_QUERIER_INTVL = 32
691 IFLA_BR_MCAST_QUERY_INTVL = 33
692 IFLA_BR_MCAST_QUERY_RESPONSE_INTVL = 34
693 IFLA_BR_MCAST_STARTUP_QUERY_INTVL = 35
694 IFLA_BR_NF_CALL_IPTABLES = 36
695 IFLA_BR_NF_CALL_IP6TABLES = 37
696 IFLA_BR_NF_CALL_ARPTABLES = 38
697 IFLA_BR_VLAN_DEFAULT_PVID = 39
698 IFLA_BR_PAD = 40
699 IFLA_BR_VLAN_STATS_ENABLED = 41
700 IFLA_BR_MCAST_STATS_ENABLED = 42
701 IFLA_BR_MCAST_IGMP_VERSION = 43
702 IFLA_BR_MCAST_MLD_VERSION = 44
703
704 ifla_br_to_string = {
705 IFLA_BR_UNSPEC : 'IFLA_BR_UNSPEC',
706 IFLA_BR_FORWARD_DELAY : 'IFLA_BR_FORWARD_DELAY',
707 IFLA_BR_HELLO_TIME : 'IFLA_BR_HELLO_TIME',
708 IFLA_BR_MAX_AGE : 'IFLA_BR_MAX_AGE',
709 IFLA_BR_AGEING_TIME : 'IFLA_BR_AGEING_TIME',
710 IFLA_BR_STP_STATE : 'IFLA_BR_STP_STATE',
711 IFLA_BR_PRIORITY : 'IFLA_BR_PRIORITY',
712 IFLA_BR_VLAN_FILTERING : 'IFLA_BR_VLAN_FILTERING',
713 IFLA_BR_VLAN_PROTOCOL : 'IFLA_BR_VLAN_PROTOCOL',
714 IFLA_BR_GROUP_FWD_MASK : 'IFLA_BR_GROUP_FWD_MASK',
715 IFLA_BR_ROOT_ID : 'IFLA_BR_ROOT_ID',
716 IFLA_BR_BRIDGE_ID : 'IFLA_BR_BRIDGE_ID',
717 IFLA_BR_ROOT_PORT : 'IFLA_BR_ROOT_PORT',
718 IFLA_BR_ROOT_PATH_COST : 'IFLA_BR_ROOT_PATH_COST',
719 IFLA_BR_TOPOLOGY_CHANGE : 'IFLA_BR_TOPOLOGY_CHANGE',
720 IFLA_BR_TOPOLOGY_CHANGE_DETECTED : 'IFLA_BR_TOPOLOGY_CHANGE_DETECTED',
721 IFLA_BR_HELLO_TIMER : 'IFLA_BR_HELLO_TIMER',
722 IFLA_BR_TCN_TIMER : 'IFLA_BR_TCN_TIMER',
723 IFLA_BR_TOPOLOGY_CHANGE_TIMER : 'IFLA_BR_TOPOLOGY_CHANGE_TIMER',
724 IFLA_BR_GC_TIMER : 'IFLA_BR_GC_TIMER',
725 IFLA_BR_GROUP_ADDR : 'IFLA_BR_GROUP_ADDR',
726 IFLA_BR_FDB_FLUSH : 'IFLA_BR_FDB_FLUSH',
727 IFLA_BR_MCAST_ROUTER : 'IFLA_BR_MCAST_ROUTER',
728 IFLA_BR_MCAST_SNOOPING : 'IFLA_BR_MCAST_SNOOPING',
729 IFLA_BR_MCAST_QUERY_USE_IFADDR : 'IFLA_BR_MCAST_QUERY_USE_IFADDR',
730 IFLA_BR_MCAST_QUERIER : 'IFLA_BR_MCAST_QUERIER',
731 IFLA_BR_MCAST_HASH_ELASTICITY : 'IFLA_BR_MCAST_HASH_ELASTICITY',
732 IFLA_BR_MCAST_HASH_MAX : 'IFLA_BR_MCAST_HASH_MAX',
733 IFLA_BR_MCAST_LAST_MEMBER_CNT : 'IFLA_BR_MCAST_LAST_MEMBER_CNT',
734 IFLA_BR_MCAST_STARTUP_QUERY_CNT : 'IFLA_BR_MCAST_STARTUP_QUERY_CNT',
735 IFLA_BR_MCAST_LAST_MEMBER_INTVL : 'IFLA_BR_MCAST_LAST_MEMBER_INTVL',
736 IFLA_BR_MCAST_MEMBERSHIP_INTVL : 'IFLA_BR_MCAST_MEMBERSHIP_INTVL',
737 IFLA_BR_MCAST_QUERIER_INTVL : 'IFLA_BR_MCAST_QUERIER_INTVL',
738 IFLA_BR_MCAST_QUERY_INTVL : 'IFLA_BR_MCAST_QUERY_INTVL',
739 IFLA_BR_MCAST_QUERY_RESPONSE_INTVL : 'IFLA_BR_MCAST_QUERY_RESPONSE_INTVL',
740 IFLA_BR_MCAST_STARTUP_QUERY_INTVL : 'IFLA_BR_MCAST_STARTUP_QUERY_INTVL',
741 IFLA_BR_NF_CALL_IPTABLES : 'IFLA_BR_NF_CALL_IPTABLES',
742 IFLA_BR_NF_CALL_IP6TABLES : 'IFLA_BR_NF_CALL_IP6TABLES',
743 IFLA_BR_NF_CALL_ARPTABLES : 'IFLA_BR_NF_CALL_ARPTABLES',
744 IFLA_BR_VLAN_DEFAULT_PVID : 'IFLA_BR_VLAN_DEFAULT_PVID',
745 IFLA_BR_PAD : 'IFLA_BR_PAD',
746 IFLA_BR_VLAN_STATS_ENABLED : 'IFLA_BR_VLAN_STATS_ENABLED',
747 IFLA_BR_MCAST_STATS_ENABLED : 'IFLA_BR_MCAST_STATS_ENABLED',
748 IFLA_BR_MCAST_IGMP_VERSION : 'IFLA_BR_MCAST_IGMP_VERSION',
749 IFLA_BR_MCAST_MLD_VERSION : 'IFLA_BR_MCAST_MLD_VERSION'
750 }
751
752 # =========================================
753 # IFLA_INFO_DATA attributes for vrfs
754 # =========================================
755 IFLA_VRF_UNSPEC = 0
756 IFLA_VRF_TABLE = 1
757
758 ifla_vrf_to_string = {
759 IFLA_VRF_UNSPEC : 'IFLA_VRF_UNSPEC',
760 IFLA_VRF_TABLE : 'IFLA_VRF_TABLE'
761 }
762
763 # ================================================================
764 # IFLA_INFO_DATA attributes for (ip6)gre, (ip6)gretap, (ip6)erspan
765 # ================================================================
766 IFLA_GRE_UNSPEC = 0
767 IFLA_GRE_LINK = 1
768 IFLA_GRE_IFLAGS = 2
769 IFLA_GRE_OFLAGS = 3
770 IFLA_GRE_IKEY = 4
771 IFLA_GRE_OKEY = 5
772 IFLA_GRE_LOCAL = 6
773 IFLA_GRE_REMOTE = 7
774 IFLA_GRE_TTL = 8
775 IFLA_GRE_TOS = 9
776 IFLA_GRE_PMTUDISC = 10
777 IFLA_GRE_ENCAP_LIMIT = 11
778 IFLA_GRE_FLOWINFO = 12
779 IFLA_GRE_FLAGS = 13
780 IFLA_GRE_ENCAP_TYPE = 14
781 IFLA_GRE_ENCAP_FLAGS = 15
782 IFLA_GRE_ENCAP_SPORT = 16
783 IFLA_GRE_ENCAP_DPORT = 17
784 IFLA_GRE_COLLECT_METADATA = 18
785 IFLA_GRE_IGNORE_DF = 19
786 IFLA_GRE_FWMARK = 20
787 IFLA_GRE_ERSPAN_INDEX = 21
788 IFLA_GRE_ERSPAN_VER = 22
789 IFLA_GRE_ERSPAN_DIR = 23
790 IFLA_GRE_ERSPAN_HWID = 24
791
792 ifla_gre_to_string = {
793 IFLA_GRE_UNSPEC : "IFLA_GRE_UNSPEC",
794 IFLA_GRE_LINK : "IFLA_GRE_LINK",
795 IFLA_GRE_IFLAGS : "IFLA_GRE_IFLAGS",
796 IFLA_GRE_OFLAGS : "IFLA_GRE_OFLAGS",
797 IFLA_GRE_IKEY : "IFLA_GRE_IKEY",
798 IFLA_GRE_OKEY : "IFLA_GRE_OKEY",
799 IFLA_GRE_LOCAL : "IFLA_GRE_LOCAL",
800 IFLA_GRE_REMOTE : "IFLA_GRE_REMOTE",
801 IFLA_GRE_TTL : "IFLA_GRE_TTL",
802 IFLA_GRE_TOS : "IFLA_GRE_TOS",
803 IFLA_GRE_PMTUDISC : "IFLA_GRE_PMTUDISC",
804 IFLA_GRE_ENCAP_LIMIT : "IFLA_GRE_ENCAP_LIMIT",
805 IFLA_GRE_FLOWINFO : "IFLA_GRE_FLOWINFO",
806 IFLA_GRE_FLAGS : "IFLA_GRE_FLAGS",
807 IFLA_GRE_ENCAP_TYPE : "IFLA_GRE_ENCAP_TYPE",
808 IFLA_GRE_ENCAP_FLAGS : "IFLA_GRE_ENCAP_FLAGS",
809 IFLA_GRE_ENCAP_SPORT : "IFLA_GRE_ENCAP_SPORT",
810 IFLA_GRE_ENCAP_DPORT : "IFLA_GRE_ENCAP_DPORT",
811 IFLA_GRE_COLLECT_METADATA : "IFLA_GRE_COLLECT_METADATA",
812 IFLA_GRE_IGNORE_DF : "IFLA_GRE_IGNORE_DF",
813 IFLA_GRE_FWMARK : "IFLA_GRE_FWMARK",
814 IFLA_GRE_ERSPAN_INDEX : "IFLA_GRE_ERSPAN_INDEX",
815 IFLA_GRE_ERSPAN_VER : "IFLA_GRE_ERSPAN_VER",
816 IFLA_GRE_ERSPAN_DIR : "IFLA_GRE_ERSPAN_DIR",
817 IFLA_GRE_ERSPAN_HWID : "IFLA_GRE_ERSPAN_HWID",
818 }
819
820 # ===============================================
821 # IFLA_INFO_DATA attributes for ipip, sit, ip6tnl
822 # ===============================================
823 IFLA_IPTUN_UNSPEC = 0
824 IFLA_IPTUN_LINK = 1
825 IFLA_IPTUN_LOCAL = 2
826 IFLA_IPTUN_REMOTE = 3
827 IFLA_IPTUN_TTL = 4
828 IFLA_IPTUN_TOS = 5
829 IFLA_IPTUN_ENCAP_LIMIT = 6
830 IFLA_IPTUN_FLOWINFO = 7
831 IFLA_IPTUN_FLAGS = 8
832 IFLA_IPTUN_PROTO = 9
833 IFLA_IPTUN_PMTUDISC = 10
834 IFLA_IPTUN_6RD_PREFIX = 11
835 IFLA_IPTUN_6RD_RELAY_PREFIX = 12
836 IFLA_IPTUN_6RD_PREFIXLEN = 13
837 IFLA_IPTUN_6RD_RELAY_PREFIXLEN = 14
838 IFLA_IPTUN_ENCAP_TYPE = 15
839 IFLA_IPTUN_ENCAP_FLAGS = 16
840 IFLA_IPTUN_ENCAP_SPORT = 17
841 IFLA_IPTUN_ENCAP_DPORT = 18
842 IFLA_IPTUN_COLLECT_METADATA = 19
843 IFLA_IPTUN_FWMARK = 20
844
845 ifla_iptun_to_string = {
846 IFLA_IPTUN_UNSPEC : "IFLA_IPTUN_UNSPEC",
847 IFLA_IPTUN_LINK : "IFLA_IPTUN_LINK",
848 IFLA_IPTUN_LOCAL : "IFLA_IPTUN_LOCAL",
849 IFLA_IPTUN_REMOTE : "IFLA_IPTUN_REMOTE",
850 IFLA_IPTUN_TTL : "IFLA_IPTUN_TTL",
851 IFLA_IPTUN_TOS : "IFLA_IPTUN_TOS",
852 IFLA_IPTUN_ENCAP_LIMIT : "IFLA_IPTUN_ENCAP_LIMIT",
853 IFLA_IPTUN_FLOWINFO : "IFLA_IPTUN_FLOWINFO",
854 IFLA_IPTUN_FLAGS : "IFLA_IPTUN_FLAGS",
855 IFLA_IPTUN_PROTO : "IFLA_IPTUN_PROTO",
856 IFLA_IPTUN_PMTUDISC : "IFLA_IPTUN_PMTUDISC",
857 IFLA_IPTUN_6RD_PREFIX : "IFLA_IPTUN_6RD_PREFIX",
858 IFLA_IPTUN_6RD_RELAY_PREFIX : "IFLA_IPTUN_6RD_RELAY_PREFIX",
859 IFLA_IPTUN_6RD_PREFIXLEN : "IFLA_IPTUN_6RD_PREFIXLEN",
860 IFLA_IPTUN_6RD_RELAY_PREFIXLEN : "IFLA_IPTUN_6RD_RELAY_PREFIXLEN",
861 IFLA_IPTUN_ENCAP_TYPE : "IFLA_IPTUN_ENCAP_TYPE",
862 IFLA_IPTUN_ENCAP_FLAGS : "IFLA_IPTUN_ENCAP_FLAGS",
863 IFLA_IPTUN_ENCAP_SPORT : "IFLA_IPTUN_ENCAP_SPORT",
864 IFLA_IPTUN_ENCAP_DPORT : "IFLA_IPTUN_ENCAP_DPORT",
865 IFLA_IPTUN_COLLECT_METADATA : "IFLA_IPTUN_COLLECT_METADATA",
866 IFLA_IPTUN_FWMARK : "IFLA_IPTUN_FWMARK",
867 }
868
869 # =========================================
870 # IFLA_INFO_DATA attributes for vti, vti6
871 # =========================================
872 IFLA_VTI_UNSPEC = 0
873 IFLA_VTI_LINK = 1
874 IFLA_VTI_IKEY = 2
875 IFLA_VTI_OKEY = 3
876 IFLA_VTI_LOCAL = 4
877 IFLA_VTI_REMOTE = 5
878 IFLA_VTI_FWMARK = 6
879
880 ifla_vti_to_string = {
881 IFLA_VTI_UNSPEC : "IFLA_VTI_UNSPEC",
882 IFLA_VTI_LINK : "IFLA_VTI_LINK",
883 IFLA_VTI_IKEY : "IFLA_VTI_IKEY",
884 IFLA_VTI_OKEY : "IFLA_VTI_OKEY",
885 IFLA_VTI_LOCAL : "IFLA_VTI_LOCAL",
886 IFLA_VTI_REMOTE : "IFLA_VTI_REMOTE",
887 IFLA_VTI_FWMARK : "IFLA_VTI_FWMARK",
888 }
889
890
891 class Attribute(object):
892
893 def __init__(self, atype, string, logger):
894 self.atype = atype
895 self.string = string
896 self.HEADER_PACK = '=HH'
897 self.HEADER_LEN = calcsize(self.HEADER_PACK)
898 self.PACK = None
899 self.LEN = None
900 self.raw = None # raw value (i.e. int for mac address)
901 self.value = None
902 self.nested = False
903 self.net_byteorder = False
904 self.log = logger
905
906 def __str__(self):
907 return self.string
908
909 def set_value(self, value):
910 self.value = value
911
912 def set_nested(self, nested):
913 self.nested = nested
914
915 def set_net_byteorder(self, net_byteorder):
916 self.net_byteorder = net_byteorder
917
918 @staticmethod
919 def pad_bytes_needed(length):
920 """
921 Return the number of bytes that should be added to align on a 4-byte boundry
922 """
923 remainder = length % 4
924
925 if remainder:
926 return 4 - remainder
927
928 return 0
929
930 def pad(self, length, raw):
931 pad = self.pad_bytes_needed(length)
932
933 if pad:
934 raw += ("\0" * pad).encode("utf-8")
935
936 return raw
937
938 def encode(self):
939
940 if not self.LEN:
941 raise Exception('Please define an encode() method in your child attribute class, or do not use AttributeGeneric')
942
943 length = self.HEADER_LEN + self.LEN
944 attr_type_with_flags = self.atype
945
946 if self.nested:
947 attr_type_with_flags = attr_type_with_flags | NLA_F_NESTED
948
949 if self.net_byteorder:
950 attr_type_with_flags = attr_type_with_flags | NLA_F_NET_BYTEORDER
951
952 raw = pack(self.HEADER_PACK, length, attr_type_with_flags) + pack(self.PACK, self.value)
953 raw = self.pad(length, raw)
954 return raw
955
956 def decode_length_type(self, data):
957 """
958 The first two bytes of an attribute are the length, the next two bytes are the type
959 """
960 self.data = data
961 prev_atype = self.atype
962 (data1, data2) = unpack(self.HEADER_PACK, data[:self.HEADER_LEN])
963 self.length = int(data1)
964 self.atype = int(data2)
965 self.attr_end = padded_length(self.length)
966
967 self.nested = True if self.atype & NLA_F_NESTED else False
968 self.net_byteorder = True if self.atype & NLA_F_NET_BYTEORDER else False
969 self.atype = self.atype & NLA_TYPE_MASK
970
971 # Should never happen
972 assert self.atype == prev_atype, "This object changes attribute type from %d to %d, this is bad" % (prev_atype, self.atype)
973
974 def dump_first_line(self, dump_buffer, line_number, color):
975 """
976 Add the "Length....Type..." line to the dump buffer
977 """
978 if self.attr_end == self.length:
979 padded_to = ', '
980 else:
981 padded_to = ' padded to %d, ' % self.attr_end
982
983 extra = 'Length %s (%d)%sType %s%s%s (%d) %s' % \
984 (zfilled_hex(self.length, 4), self.length,
985 padded_to,
986 zfilled_hex(self.atype, 4),
987 " (NLA_F_NESTED set)" if self.nested else "",
988 " (NLA_F_NET_BYTEORDER set)" if self.net_byteorder else "",
989 self.atype,
990 self)
991
992 dump_buffer.append(data_to_color_text(line_number, color, self.data[0:4], extra))
993 return line_number + 1
994
995 def dump_lines(self, dump_buffer, line_number, color):
996 line_number = self.dump_first_line(dump_buffer, line_number, color)
997
998 for x in range(1, self.attr_end//4):
999 start = x * 4
1000 end = start + 4
1001 dump_buffer.append(data_to_color_text(line_number, color, self.data[start:end], ''))
1002 line_number += 1
1003
1004 return line_number
1005
1006 def get_pretty_value(self, obj=None):
1007 if obj and callable(obj):
1008 return obj(self.value)
1009 return self.value
1010
1011 @staticmethod
1012 def decode_one_byte_attribute(data, _=None):
1013 # we don't need to use the unpack function because bytes are a list of ints
1014 return data[4]
1015
1016 @staticmethod
1017 def decode_two_bytes_attribute(data, _=None):
1018 return unpack("=H", data[4:6])[0]
1019
1020 @staticmethod
1021 def decode_two_bytes_network_byte_order_attribute(data, _=None):
1022 # The form '!' is available for those poor souls who claim they can't
1023 # remember whether network byte order is big-endian or little-endian.
1024 return unpack("!H", data[4:6])[0]
1025
1026 @staticmethod
1027 def decode_four_bytes_attribute(data, _=None):
1028 return unpack("=L", data[4:8])[0]
1029
1030 @staticmethod
1031 def decode_eight_bytes_attribute(data, _=None):
1032 return unpack("=Q", data[4:12])[0]
1033
1034 @staticmethod
1035 def decode_mac_address_attribute(data, _=None):
1036 (data1, data2) = unpack(">LHxx", data[4:12])
1037 return mac_int_to_str(data1 << 16 | data2)
1038
1039 @staticmethod
1040 def decode_ipv4_address_attribute(data, _=None):
1041 return ipnetwork.IPNetwork(unpack(">L", data[4:8])[0])
1042
1043 @staticmethod
1044 def decode_ipv6_address_attribute(data, _=None):
1045 (data1, data2) = unpack(">QQ", data[4:20])
1046 return ipnetwork.IPNetwork(data1 << 64 | data2)
1047
1048 @staticmethod
1049 def decode_bond_ad_info_attribute(data, info_data_end):
1050 ifla_bond_ad_info = {}
1051 ad_attr_data = data[4:info_data_end]
1052
1053 while ad_attr_data:
1054 (ad_data_length, ad_data_type) = unpack("=HH", ad_attr_data[:4])
1055 ad_data_end = padded_length(ad_data_length)
1056
1057 if ad_data_type == Link.IFLA_BOND_AD_INFO_PARTNER_MAC:
1058 (data1, data2) = unpack(">LHxx", ad_attr_data[4:12])
1059 ifla_bond_ad_info[ad_data_type] = mac_int_to_str(data1 << 16 | data2)
1060
1061 ad_attr_data = ad_attr_data[ad_data_end:]
1062
1063 return ifla_bond_ad_info
1064
1065 @staticmethod
1066 def decode_vlan_protocol_attribute(data, _=None):
1067 return Link.ifla_vlan_protocol_dict.get(unpack(">H", data[4:6])[0])
1068
1069 ############################################################################
1070 # encode methods
1071 ############################################################################
1072
1073 @staticmethod
1074 def encode_one_byte_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
1075 sub_attr_pack_layout.append("HH")
1076 sub_attr_payload.append(5) # length
1077 sub_attr_payload.append(info_data_type)
1078
1079 sub_attr_pack_layout.append("Bxxx")
1080 sub_attr_payload.append(info_data_value)
1081
1082 @staticmethod
1083 def encode_bond_xmit_hash_policy_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
1084 return Attribute.encode_one_byte_attribute(
1085 sub_attr_pack_layout,
1086 sub_attr_payload,
1087 info_data_type,
1088 Link.ifla_bond_xmit_hash_policy_tbl.get(info_data_value, 0),
1089 )
1090
1091 @staticmethod
1092 def encode_bond_mode_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
1093 return Attribute.encode_one_byte_attribute(
1094 sub_attr_pack_layout,
1095 sub_attr_payload,
1096 info_data_type,
1097 Link.ifla_bond_mode_tbl.get(info_data_value, 0),
1098 )
1099
1100 @staticmethod
1101 def encode_two_bytes_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
1102 sub_attr_pack_layout.append("HH")
1103 sub_attr_payload.append(6) # length
1104 sub_attr_payload.append(info_data_type)
1105
1106 sub_attr_pack_layout.append("Hxx")
1107 sub_attr_payload.append(info_data_value)
1108
1109 @staticmethod
1110 def encode_four_bytes_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
1111 sub_attr_pack_layout.append("HH")
1112 sub_attr_payload.append(8) # length
1113 sub_attr_payload.append(info_data_type)
1114
1115 sub_attr_pack_layout.append("L")
1116 sub_attr_payload.append(info_data_value)
1117
1118 @staticmethod
1119 def encode_eight_bytes_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
1120 sub_attr_pack_layout.append("HH")
1121 sub_attr_payload.append(12) # length
1122 sub_attr_payload.append(info_data_type)
1123
1124 sub_attr_pack_layout.append("Q")
1125 sub_attr_payload.append(info_data_value)
1126
1127 @staticmethod
1128 def encode_ipv4_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
1129 sub_attr_pack_layout.append("HH")
1130 sub_attr_payload.append(8) # length
1131 sub_attr_payload.append(info_data_type)
1132
1133 sub_attr_pack_layout.append("BBBB")
1134
1135 if info_data_value:
1136 sub_attr_payload.extend(info_data_value.packed)
1137 else:
1138 sub_attr_payload.extend([0, 0, 0, 0])
1139
1140 @staticmethod
1141 def encode_ipv6_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
1142 raise NotImplementedError("ipv6 tunnel local and remote not supported yet")
1143
1144 @staticmethod
1145 def encode_vlan_protocol_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
1146 sub_attr_pack_layout.append("HH")
1147 sub_attr_payload.append(6) # length
1148 sub_attr_payload.append(info_data_type)
1149
1150 # vlan protocol
1151 vlan_protocol = NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_vlan_protocol_dict.get(info_data_value)
1152 if not vlan_protocol:
1153 raise NotImplementedError('vlan protocol %s not implemented' % info_data_value)
1154
1155 sub_attr_pack_layout.append("Hxx")
1156 sub_attr_payload.append(htons(vlan_protocol))
1157
1158 @staticmethod
1159 def encode_vxlan_port_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
1160 sub_attr_pack_layout.append("HH")
1161 sub_attr_payload.append(6)
1162 sub_attr_payload.append(info_data_type)
1163
1164 sub_attr_pack_layout.append("Hxx")
1165
1166 # byte swap
1167 swaped = pack(">H", info_data_value)
1168
1169 sub_attr_payload.append(unpack("<H", swaped)[0])
1170
1171 @staticmethod
1172 def encode_mac_address_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
1173 sub_attr_pack_layout.append("HH")
1174 sub_attr_payload.append(10) # length
1175 sub_attr_payload.append(info_data_type)
1176
1177 sub_attr_pack_layout.append("6Bxx")
1178 for mbyte in info_data_value.replace(".", " ").replace(":", " ").split():
1179 sub_attr_payload.append(int(mbyte, 16))
1180
1181
1182 class AttributeCACHEINFO(Attribute):
1183 """
1184 struct ifa_cacheinfo {
1185 __u32 ifa_prefered;
1186 __u32 ifa_valid;
1187 __u32 cstamp; /* created timestamp, hundredths of seconds */
1188 __u32 tstamp; /* updated timestamp, hundredths of seconds */
1189 };
1190 """
1191 def __init__(self, atype, string, family, logger):
1192 Attribute.__init__(self, atype, string, logger)
1193 self.PACK = "=IIII"
1194 self.LEN = calcsize(self.PACK)
1195
1196 def encode(self):
1197 ifa_prefered, ifa_valid, cstamp, tstamp = self.value
1198 return pack(self.HEADER_PACK, self.HEADER_LEN + self.LEN , self.atype) + pack(self.PACK, ifa_prefered, ifa_valid, cstamp, tstamp)
1199
1200 def decode(self, parent_msg, data):
1201 self.decode_length_type(data)
1202 try:
1203 self.value = unpack(self.PACK, self.data[4:])
1204 except struct.error:
1205 self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:])))
1206
1207
1208 class AttributeFourByteList(Attribute):
1209
1210 def __init__(self, atype, string, family, logger):
1211 Attribute.__init__(self, atype, string, logger)
1212
1213 def decode(self, parent_msg, data):
1214 self.decode_length_type(data)
1215 wordcount = (self.attr_end - 4)//4
1216 self.PACK = '=%dL' % wordcount
1217 self.LEN = calcsize(self.PACK)
1218
1219 try:
1220 self.value = unpack(self.PACK, self.data[4:])
1221 except struct.error:
1222 self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:])))
1223 raise
1224
1225 def dump_lines(self, dump_buffer, line_number, color):
1226 line_number = self.dump_first_line(dump_buffer, line_number, color)
1227 idx = 1
1228 for val in self.value:
1229 dump_buffer.append(data_to_color_text(line_number, color, self.data[4*idx:4*(idx+1)], val))
1230 line_number += 1
1231 idx += 1
1232 return line_number
1233
1234
1235 class AttributeFourByteValue(Attribute):
1236
1237 def __init__(self, atype, string, family, logger):
1238 Attribute.__init__(self, atype, string, logger)
1239 self.PACK = '=L'
1240 self.LEN = calcsize(self.PACK)
1241
1242 def decode(self, parent_msg, data):
1243 self.decode_length_type(data)
1244 assert self.attr_end == 8, "Attribute length for %s must be 8, it is %d" % (self, self.attr_end)
1245
1246 try:
1247 self.value = int(unpack(self.PACK, self.data[4:])[0])
1248 except struct.error:
1249 self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:])))
1250 raise
1251
1252 def dump_lines(self, dump_buffer, line_number, color):
1253 line_number = self.dump_first_line(dump_buffer, line_number, color)
1254 dump_buffer.append(data_to_color_text(line_number, color, self.data[4:8], self.value))
1255 return line_number + 1
1256
1257
1258 class AttributeTwoByteValue(Attribute):
1259
1260 def __init__(self, atype, string, family, logger):
1261 Attribute.__init__(self, atype, string, logger)
1262 self.PACK = '=Hxx'
1263 self.LEN = calcsize(self.PACK)
1264
1265 def decode(self, parent_msg, data):
1266 self.decode_length_type(data)
1267 assert self.attr_end == 8, "Attribute length for %s must be 8, it is %d" % (self, self.attr_end)
1268
1269 try:
1270 self.value = int(unpack(self.PACK, self.data[4:8])[0])
1271 except struct.error:
1272 self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:6])))
1273 raise
1274
1275 def encode(self):
1276 length = self.HEADER_LEN + self.LEN
1277 raw = pack(self.HEADER_PACK, length-2, self.atype) + pack(self.PACK, self.value)
1278 raw = self.pad(length, raw)
1279 return raw
1280
1281 def dump_lines(self, dump_buffer, line_number, color):
1282 line_number = self.dump_first_line(dump_buffer, line_number, color)
1283 dump_buffer.append(data_to_color_text(line_number, color, self.data[4:8], self.value))
1284 return line_number + 1
1285
1286
1287 class AttributeString(Attribute):
1288
1289 def __init__(self, atype, string, family, logger):
1290 Attribute.__init__(self, atype, string, logger)
1291 self.PACK = None
1292 self.LEN = None
1293
1294 def encode(self):
1295 # some interface names come from JSON as unicode strings
1296 # and cannot be packed as is so we must convert them to strings
1297 if isinstance(self.value, str):
1298 self.value = str(self.value)
1299 self.PACK = '%ds' % len(self.value)
1300 self.LEN = calcsize(self.PACK)
1301
1302 length = self.HEADER_LEN + self.LEN
1303 raw = pack(self.HEADER_PACK, length, self.atype) + pack(self.PACK, self.value.encode())
1304 raw = self.pad(length, raw)
1305 return raw
1306
1307 def decode(self, parent_msg, data):
1308 self.decode_length_type(data)
1309 self.PACK = '%ds' % (self.length - 4)
1310 self.LEN = calcsize(self.PACK)
1311
1312 try:
1313 self.value = remove_trailing_null(unpack(self.PACK, self.data[4:self.length])[0]).decode("utf-8")
1314 except struct.error:
1315 self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:self.length])))
1316 raise
1317
1318
1319 class AttributeStringInterfaceName(AttributeString):
1320
1321 def __init__(self, atype, string, family, logger):
1322 AttributeString.__init__(self, atype, string, family, logger)
1323
1324 def set_value(self, value):
1325 if value and len(value) > IF_NAME_SIZE:
1326 raise Exception('interface name exceeds max length of %d' % IF_NAME_SIZE)
1327 self.value = value
1328
1329
1330 class AttributeIPAddress(Attribute):
1331
1332 def __init__(self, atype, string, family, logger):
1333 Attribute.__init__(self, atype, string, logger)
1334 self.family = family
1335
1336 if self.family == AF_INET:
1337 self.PACK = '>L'
1338
1339 elif self.family == AF_INET6:
1340 self.PACK = '>QQ'
1341
1342 elif self.family == AF_BRIDGE:
1343 self.PACK = '>L'
1344
1345 else:
1346 raise Exception("%s is not a supported address family" % self.family)
1347
1348 self.LEN = calcsize(self.PACK)
1349
1350 def decode(self, parent_msg, data):
1351 self.decode_length_type(data)
1352
1353 try:
1354 try:
1355 prefixlen = parent_msg.prefixlen
1356 except AttributeError:
1357 prefixlen = None
1358 try:
1359 scope = parent_msg.scope
1360 except AttributeError:
1361 scope = 0
1362
1363 if isinstance(parent_msg, Route):
1364 if self.atype == Route.RTA_SRC:
1365 self.value = ipnetwork.IPNetwork(self.value, parent_msg.src_len)
1366 elif self.atype == Route.RTA_DST:
1367 self.value = ipnetwork.IPNetwork(self.value, parent_msg.dst_len)
1368 else:
1369 if self.family in (AF_INET, AF_BRIDGE):
1370 self.value = ipnetwork.IPNetwork(unpack(self.PACK, self.data[4:])[0], prefixlen, scope)
1371
1372 elif self.family == AF_INET6:
1373 (data1, data2) = unpack(self.PACK, self.data[4:])
1374 self.value = ipnetwork.IPNetwork(data1 << 64 | data2, prefixlen, scope)
1375
1376 else:
1377 self.log.debug("AttributeIPAddress: decode: unsupported address family ({})".format(self.family))
1378
1379 except struct.error:
1380 self.value = None
1381 self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:])))
1382 raise
1383
1384 def encode(self):
1385 length = self.HEADER_LEN + self.LEN
1386
1387 if self.family not in [AF_INET, AF_INET6, AF_BRIDGE]:
1388 raise Exception("%s is not a supported address family" % self.family)
1389
1390 raw = pack(self.HEADER_PACK, length, self.atype) + self.value.packed
1391 raw = self.pad(length, raw)
1392 return raw
1393
1394 def dump_lines(self, dump_buffer, line_number, color):
1395 line_number = self.dump_first_line(dump_buffer, line_number, color)
1396
1397 if self.family == AF_INET:
1398 dump_buffer.append(data_to_color_text(line_number, color, self.data[4:8], self.value))
1399 line_number += 1
1400
1401 elif self.family == AF_INET6:
1402
1403 for x in range(1, self.attr_end//4):
1404 start = x * 4
1405 end = start + 4
1406 dump_buffer.append(data_to_color_text(line_number, color, self.data[start:end], self.value))
1407 line_number += 1
1408
1409 elif self.family == AF_BRIDGE:
1410 dump_buffer.append(data_to_color_text(line_number, color, self.data[4:8], self.value))
1411 line_number += 1
1412
1413 return line_number
1414
1415
1416 class AttributeMACAddress(Attribute):
1417
1418 def __init__(self, atype, string, family, logger):
1419 Attribute.__init__(self, atype, string, logger)
1420 self.PACK = '>LHxx'
1421 self.LEN = calcsize(self.PACK)
1422
1423 def decode(self, parent_msg, data):
1424 self.decode_length_type(data)
1425
1426 # IFLA_ADDRESS and IFLA_BROADCAST attributes for all interfaces has been a
1427 # 6-byte MAC address. But the GRE interface uses a 4-byte IP address and
1428 # GREv6 uses a 16-byte IPv6 address for this attribute.
1429 try:
1430 # GRE interface uses a 4-byte IP address for this attribute
1431 if self.length == 8:
1432 self.value = ipnetwork.IPNetwork(unpack('>L', self.data[4:])[0])
1433
1434 # MAC Address
1435 elif self.length == 10:
1436 (data1, data2) = unpack(self.PACK, self.data[4:])
1437 self.raw = data1 << 16 | data2
1438 self.value = mac_int_to_str(self.raw)
1439 # GREv6 interface uses a 16-byte IP address for this attribute
1440 elif self.length == 20:
1441 self.value = ipnetwork.IPNetwork(unpack('>L', self.data[16:])[0])
1442
1443 else:
1444 raise Exception("Length of MACAddress attribute not supported: %d" % self.length)
1445
1446 except struct.error:
1447 self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:])))
1448 raise
1449
1450 def encode(self):
1451 length = self.HEADER_LEN + self.LEN
1452 mac_raw = int(self.value.replace('.', '').replace(':', ''), 16)
1453 raw = pack(self.HEADER_PACK, length-2, self.atype) + pack(self.PACK, mac_raw >> 16, mac_raw & 0x0000FFFF)
1454 raw = self.pad(length, raw)
1455 return raw
1456
1457 def dump_lines(self, dump_buffer, line_number, color):
1458 line_number = self.dump_first_line(dump_buffer, line_number, color)
1459 dump_buffer.append(data_to_color_text(line_number, color, self.data[4:8], self.value))
1460 line_number += 1
1461 if len(self.data) >= 12:
1462 dump_buffer.append(data_to_color_text(line_number, color, self.data[8:12]))
1463 line_number += 1
1464 return line_number
1465
1466
1467 class AttributeMplsLabel(Attribute):
1468
1469 def __init__(self, atype, string, family, logger):
1470 Attribute.__init__(self, atype, string, logger)
1471 self.family = family
1472 self.PACK = '>HBB'
1473
1474 def decode(self, parent_msg, data):
1475 self.decode_length_type(data)
1476
1477 try:
1478 (label_high, label_low_tc_s, self.ttl) = unpack(self.PACK, self.data[4:])
1479 self.s_bit = label_low_tc_s & 0x1
1480 self.traffic_class = ((label_low_tc_s & 0xf) >> 1)
1481 self.label = (label_high << 4) | (label_low_tc_s >> 4)
1482 self.value = self.label
1483
1484 except struct.error:
1485 self.value = None
1486 self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:])))
1487 raise
1488
1489 def dump_lines(self, dump_buffer, line_number, color):
1490 line_number = self.dump_first_line(dump_buffer, line_number, color)
1491 dump_buffer.append(data_to_color_text(line_number, color, self.data[4:8],
1492 'label %s, TC %s, bottom-of-stack %s, TTL %d' %
1493 (self.label, self.traffic_class, self.s_bit, self.ttl)))
1494 line_number += 1
1495
1496 return line_number
1497
1498
1499 class AttributeGeneric(Attribute):
1500
1501 def __init__(self, atype, string, family, logger):
1502 Attribute.__init__(self, atype, string, logger)
1503 self.PACK = None
1504 self.LEN = None
1505
1506 def decode(self, parent_msg, data):
1507 self.decode_length_type(data)
1508 wordcount = (self.attr_end - 4)//4
1509 self.PACK = '=%dL' % wordcount
1510 self.LEN = calcsize(self.PACK)
1511
1512 try:
1513 self.value = ''.join(map(str, unpack(self.PACK, self.data[4:])))
1514 except struct.error:
1515 self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:])))
1516 raise
1517
1518
1519 class AttributeOneByteValue(AttributeGeneric):
1520
1521 def __init__(self, atype, string, family, logger):
1522 AttributeGeneric.__init__(self, atype, string, family, logger)
1523 self.PACK = '=Bxxx'
1524 self.LEN = calcsize(self.PACK)
1525
1526 def decode(self, parent_msg, data):
1527 self.decode_length_type(data)
1528 assert self.attr_end == 8, "Attribute length for %s must be 8, it is %d" % (self, self.attr_end)
1529
1530 try:
1531 self.value = int(unpack(self.PACK, self.data[4:8])[0])
1532 except struct.error:
1533 self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:5])))
1534 raise
1535
1536 def encode(self):
1537 length = self.HEADER_LEN + self.LEN
1538 raw = pack(self.HEADER_PACK, length-3, self.atype) + pack(self.PACK, self.value)
1539 raw = self.pad(length, raw)
1540 return raw
1541
1542 def dump_lines(self, dump_buffer, line_number, color):
1543 line_number = self.dump_first_line(dump_buffer, line_number, color)
1544 dump_buffer.append(data_to_color_text(line_number, color, self.data[4:8], self.value))
1545 return line_number + 1
1546
1547
1548 class AttributeIFLA_AF_SPEC(Attribute):
1549 """
1550 value will be a dictionary such as:
1551 {
1552 Link.IFLA_BRIDGE_FLAGS: flags,
1553 Link.IFLA_BRIDGE_VLAN_INFO: (vflags, vlanid)
1554 }
1555 """
1556 def __init__(self, atype, string, family, logger):
1557 Attribute.__init__(self, atype, string, logger)
1558 self.family = family
1559
1560 def encode(self):
1561 pack_layout = [self.HEADER_PACK]
1562 payload = [0, self.atype | NLA_F_NESTED]
1563 attr_length_index = 0
1564
1565 # For now this assumes that all data will be packed in the native endian
1566 # order (=). If a field is added that needs to be packed via network
1567 # order (>) then some smarts will need to be added to split the pack_layout
1568 # string at the >, split the payload and make the needed pack() calls.
1569 #
1570 # Until we cross that bridge though we will keep things nice and simple and
1571 # pack everything via a single pack() call.
1572 sub_attr_to_add = []
1573
1574 for (sub_attr_type, sub_attr_value) in self.value.items():
1575
1576 if sub_attr_type == Link.IFLA_BRIDGE_FLAGS:
1577 sub_attr_to_add.append((sub_attr_type, sub_attr_value))
1578
1579 elif sub_attr_type == Link.IFLA_BRIDGE_VLAN_INFO:
1580 for (vlan_flag, vlan_id) in sub_attr_value:
1581 sub_attr_to_add.append((sub_attr_type, (vlan_flag, vlan_id)))
1582
1583 else:
1584 self.log.log(SYSLOG_EXTRA_DEBUG, 'Add support for encoding IFLA_AF_SPEC sub-attribute type %d' % sub_attr_type)
1585 continue
1586
1587 for (sub_attr_type, sub_attr_value) in sub_attr_to_add:
1588 sub_attr_pack_layout = ['=', 'HH']
1589 sub_attr_payload = [0, sub_attr_type]
1590 sub_attr_length_index = 0
1591
1592 if sub_attr_type == Link.IFLA_BRIDGE_FLAGS:
1593 sub_attr_pack_layout.append('H')
1594 sub_attr_payload.append(sub_attr_value)
1595
1596 elif sub_attr_type == Link.IFLA_BRIDGE_VLAN_INFO:
1597 sub_attr_pack_layout.append('HH')
1598 sub_attr_payload.append(sub_attr_value[0])
1599 sub_attr_payload.append(sub_attr_value[1])
1600
1601 sub_attr_length = calcsize(''.join(sub_attr_pack_layout))
1602 sub_attr_payload[sub_attr_length_index] = sub_attr_length
1603
1604 # add padding
1605 for x in range(self.pad_bytes_needed(sub_attr_length)):
1606 sub_attr_pack_layout.append('x')
1607
1608 # The [1:] is to remove the leading = so that when we do the ''.join() later
1609 # we do not end up with an = in the middle of the pack layout string. There
1610 # will be an = at the beginning via self.HEADER_PACK
1611 sub_attr_pack_layout = sub_attr_pack_layout[1:]
1612
1613 # Now extend the ovarall attribute pack_layout/payload to include this sub-attribute
1614 pack_layout.extend(sub_attr_pack_layout)
1615 payload.extend(sub_attr_payload)
1616
1617 pack_layout = ''.join(pack_layout)
1618
1619 # Fill in the length field
1620 length = calcsize(pack_layout)
1621 payload[attr_length_index] = length
1622
1623 raw = pack(pack_layout, *payload)
1624 raw = self.pad(length, raw)
1625 return raw
1626
1627 def decode(self, parent_msg, data):
1628 """
1629 value is a dictionary such as:
1630 {
1631 Link.IFLA_BRIDGE_FLAGS: flags,
1632 Link.IFLA_BRIDGE_VLAN_INFO: (vflags, vlanid)
1633 }
1634
1635 FROM: David Ahern
1636 The encoding of the IFLA_AF_SPEC attribute varies depending on the family
1637 used for the request (RTM_GETLINK) message. For AF_UNSPEC the encoding
1638 has another level of nesting for each address family with the type encoded
1639 first. i.e.,
1640 af_spec = nla_nest_start(skb, IFLA_AF_SPEC)
1641 for each family:
1642 af = nla_nest_start(skb, af_ops->family)
1643 af_ops->fill_link_af(skb, dev, ext_filter_mask)
1644 nest_end
1645 nest_end
1646
1647 This allows the parser to find the address family by looking at the first
1648 type.
1649
1650 Whereas AF_BRIDGE encoding is just:
1651 af_spec = nla_nest_start(skb, IFLA_AF_SPEC)
1652 br_fill_ifvlaninfo{_compressed}(skb, vg)
1653 nest_end
1654
1655 which means the parser can not use the attribute itself to know the family
1656 to which the attribute belongs.
1657
1658 /include/uapi/linux/if_link.h
1659 /*
1660 * IFLA_AF_SPEC
1661 * Contains nested attributes for address family specific attributes.
1662 * Each address family may create a attribute with the address family
1663 * number as type and create its own attribute structure in it.
1664 *
1665 * Example:
1666 * [IFLA_AF_SPEC] = {
1667 * [AF_INET] = {
1668 * [IFLA_INET_CONF] = ...,
1669 * },
1670 * [AF_INET6] = {
1671 * [IFLA_INET6_FLAGS] = ...,
1672 * [IFLA_INET6_CONF] = ...,
1673 * }
1674 * }
1675 */
1676
1677 """
1678 self.decode_length_type(data)
1679 self.value = {}
1680
1681 data = self.data[4:]
1682
1683 while data:
1684 (sub_attr_length, sub_attr_type) = unpack('=HH', data[:4])
1685 sub_attr_end = padded_length(sub_attr_length)
1686
1687 if not sub_attr_length:
1688 self.log.error('parsed a zero length sub-attr')
1689 return
1690
1691 sub_attr_data = data[4:sub_attr_end]
1692
1693 if self.family == AF_BRIDGE:
1694 if sub_attr_type == Link.IFLA_BRIDGE_FLAGS:
1695 self.value[Link.IFLA_BRIDGE_FLAGS] = unpack("=H", sub_attr_data[0:2])[0]
1696
1697 elif sub_attr_type == Link.IFLA_BRIDGE_VLAN_INFO:
1698 if Link.IFLA_BRIDGE_VLAN_INFO not in self.value:
1699 self.value[Link.IFLA_BRIDGE_VLAN_INFO] = []
1700 self.value[Link.IFLA_BRIDGE_VLAN_INFO].append(tuple(unpack("=HH", sub_attr_data[0:4])))
1701
1702 else:
1703 self.log.log(SYSLOG_EXTRA_DEBUG, 'Add support for decoding IFLA_AF_SPEC sub-attribute '
1704 'type %s (%d), length %d, padded to %d' %
1705 (parent_msg.get_ifla_bridge_af_spec_to_string(sub_attr_type),
1706 sub_attr_type, sub_attr_length, sub_attr_end))
1707
1708 elif self.family == AF_UNSPEC:
1709
1710 if sub_attr_type == AF_INET6:
1711 inet6_attr = {}
1712
1713 while sub_attr_data:
1714 (inet6_attr_length, inet6_attr_type) = unpack('=HH', sub_attr_data[:4])
1715 inet6_attr_end = padded_length(inet6_attr_length)
1716
1717 # 1 byte attr
1718 if inet6_attr_type == Link.IFLA_INET6_ADDR_GEN_MODE:
1719 inet6_attr[inet6_attr_type] = self.decode_one_byte_attribute(sub_attr_data)
1720
1721 # nlmanager doesn't support multiple kernel version
1722 # all the other attributes like IFLA_INET6_CONF are
1723 # based on DEVCONF_MAX from _UAPI_IPV6_H.
1724 # we can opti the code and break this loop once we
1725 # found the attribute that we are interested in.
1726 # It's not really worth going through all the other
1727 # attributes to log that we don't support them yet
1728 break
1729 else:
1730 self.log.log(
1731 SYSLOG_EXTRA_DEBUG,
1732 'Add support for decoding AF_INET6 IFLA_AF_SPEC '
1733 'sub-attribute type %s (%d), length %d, padded to %d'
1734 % (
1735 parent_msg.get_ifla_inet6_af_spec_to_string(inet6_attr_type),
1736 inet6_attr_type, inet6_attr_length, inet6_attr_end
1737 )
1738 )
1739
1740 sub_attr_data = sub_attr_data[inet6_attr_end:]
1741 self.value[AF_INET6] = inet6_attr
1742 else:
1743 self.value[sub_attr_type] = {}
1744
1745 # Uncomment the following block to implement the AF_INET attributes
1746 # see Link.get_ifla_inet_af_spec_to_string (dict)
1747 #elif sub_attr_type == AF_INET:
1748 # inet_attr = {}
1749 #
1750 # while sub_attr_data:
1751 # (inet_attr_length, inet_attr_type) = unpack('=HH', sub_attr_data[:4])
1752 # inet_attr_end = padded_length(inet_attr_length)
1753 #
1754 # self.log.error(
1755 # # SYSLOG_EXTRA_DEBUG,
1756 # 'Add support for decoding AF_INET IFLA_AF_SPEC '
1757 # 'sub-attribute type %s (%d), length %d, padded to %d'
1758 # % (
1759 # parent_msg.get_ifla_inet_af_spec_to_string(inet_attr_type),
1760 # inet_attr_type, inet_attr_length, inet_attr_end
1761 # )
1762 # )
1763 #
1764 # sub_attr_data = sub_attr_data[inet_attr_end:]
1765 #
1766 # self.value[AF_INET] = inet_attr
1767 else:
1768 self.log.log(SYSLOG_EXTRA_DEBUG, 'Add support for decoding IFLA_AF_SPEC sub-attribute '
1769 'family %d, length %d, padded to %d'
1770 % (self.family, sub_attr_length, sub_attr_end))
1771
1772 data = data[sub_attr_end:]
1773
1774 def dump_lines(self, dump_buffer, line_number, color):
1775 line_number = self.dump_first_line(dump_buffer, line_number, color)
1776 extra = ''
1777
1778 next_sub_attr_line = 0
1779 sub_attr_line = True
1780
1781 for x in range(1, self.attr_end//4):
1782 start = x * 4
1783 end = start + 4
1784
1785 if line_number == next_sub_attr_line:
1786 sub_attr_line = True
1787
1788 if sub_attr_line:
1789 sub_attr_line = False
1790
1791 (sub_attr_length, sub_attr_type) = unpack('=HH', self.data[start:start+4])
1792 sub_attr_end = padded_length(sub_attr_length)
1793
1794 next_sub_attr_line = line_number + (sub_attr_end//4)
1795
1796 if sub_attr_end == sub_attr_length:
1797 padded_to = ','
1798 else:
1799 padded_to = ' padded to %d,' % sub_attr_end
1800
1801 if self.family == AF_BRIDGE:
1802 extra = 'Nested Attribute - Length %s (%d)%s Type %s (%d) %s' % \
1803 (zfilled_hex(sub_attr_length, 4), sub_attr_length,
1804 padded_to,
1805 zfilled_hex(sub_attr_type, 4), sub_attr_type,
1806 Link.ifla_bridge_af_spec_to_string.get(sub_attr_type))
1807 elif self.family == AF_UNSPEC:
1808 if sub_attr_type == AF_INET6:
1809 family = 'AF_INET6'
1810 elif sub_attr_type == AF_INET:
1811 family = 'AF_INET'
1812 else:
1813 family = 'Unsupported family %d' % sub_attr_type
1814
1815 extra = 'Nested Attribute Structure for %s - Length %s (%d)%s Type %s (%d)' % (
1816 family, zfilled_hex(sub_attr_length, 4), sub_attr_length, padded_to,
1817 zfilled_hex(sub_attr_type, 4), sub_attr_type,
1818 )
1819 else:
1820 extra = ''
1821
1822 dump_buffer.append(data_to_color_text(line_number, color, self.data[start:end], extra))
1823 line_number += 1
1824
1825 return line_number
1826
1827 def get_pretty_value(self, obj=None):
1828
1829 if obj and callable(obj):
1830 return obj(self.value)
1831
1832 # We do this so we can print a more human readable dictionary
1833 # with the names of the nested keys instead of their numbers
1834 value_pretty = {}
1835
1836 if self.family == AF_BRIDGE:
1837 for (sub_key, sub_value) in self.value.items():
1838 sub_key_pretty = "(%2d) %s" % (sub_key, Link.ifla_bridge_af_spec_to_string.get(sub_key))
1839 value_pretty[sub_key_pretty] = sub_value
1840 elif self.family == AF_UNSPEC:
1841 for (family, family_attr) in self.value.items():
1842 family_value_pretty = {}
1843
1844 if family == AF_INET6:
1845 family_af_spec_to_string = Link.ifla_inet6_af_spec_to_string
1846 elif family == AF_INET:
1847 family_af_spec_to_string = Link.ifla_inet_af_spec_to_string
1848 else:
1849 continue # log error?
1850
1851 for (sub_key, sub_value) in family_attr.items():
1852 sub_key_pretty = "(%2d) %s" % (sub_key, family_af_spec_to_string.get(sub_key))
1853 family_value_pretty[sub_key_pretty] = sub_value
1854 value_pretty = family_value_pretty
1855
1856 return value_pretty
1857
1858
1859
1860 class AttributeRTA_MULTIPATH(Attribute):
1861 """
1862 /* RTA_MULTIPATH --- array of struct rtnexthop.
1863 *
1864 * "struct rtnexthop" describes all necessary nexthop information,
1865 * i.e. parameters of path to a destination via this nexthop.
1866 *
1867 * At the moment it is impossible to set different prefsrc, mtu, window
1868 * and rtt for different paths from multipath.
1869 */
1870
1871 struct rtnexthop {
1872 unsigned short rtnh_len;
1873 unsigned char rtnh_flags;
1874 unsigned char rtnh_hops;
1875 int rtnh_ifindex;
1876 };
1877 """
1878
1879 def __init__(self, atype, string, family, logger):
1880 Attribute.__init__(self, atype, string, logger)
1881 self.family = family
1882 self.PACK = None
1883 self.LEN = None
1884 self.RTNH_PACK = '=HBBL' # rtnh_len, flags, hops, ifindex
1885 self.RTNH_LEN = calcsize(self.RTNH_PACK)
1886 self.IPV4_LEN = 4
1887 self.IPV6_LEN = 16
1888
1889 def encode(self):
1890
1891 # Calculate the length
1892 if self.family == AF_INET:
1893 ip_len = self.IPV4_LEN
1894 elif self.family == AF_INET6:
1895 ip_len = self.IPV6_LEN
1896
1897 # Attribute header
1898 length = self.HEADER_LEN + ((self.RTNH_LEN + self.HEADER_LEN + ip_len) * len(self.value))
1899 raw = pack(self.HEADER_PACK, length, self.atype)
1900
1901 rtnh_flags = 0
1902 rtnh_hops = 0
1903 rtnh_len = self.RTNH_LEN + self.HEADER_LEN + ip_len
1904
1905 for (nexthop, rtnh_ifindex) in self.value:
1906
1907 # rtnh structure
1908 raw += pack(self.RTNH_PACK, rtnh_len, rtnh_flags, rtnh_hops, rtnh_ifindex)
1909
1910 # Gateway
1911 raw += pack(self.HEADER_PACK, self.HEADER_LEN + ip_len, Route.RTA_GATEWAY)
1912
1913 if self.family == AF_INET:
1914 raw += pack('>L', nexthop)
1915 elif self.family == AF_INET6:
1916 raw += pack('>QQ', nexthop >> 64, nexthop & 0x0000000000000000FFFFFFFFFFFFFFFF)
1917
1918 raw = self.pad(length, raw)
1919 return raw
1920
1921 def decode(self, parent_msg, data):
1922 self.decode_length_type(data)
1923 self.value = []
1924
1925 data = self.data[4:]
1926
1927 while data:
1928 (rtnh_len, rtnh_flags, rtnh_hops, rtnh_ifindex) = unpack(self.RTNH_PACK, data[:self.RTNH_LEN])
1929 data = data[self.RTNH_LEN:]
1930
1931 (attr_type, attr_length) = unpack(self.HEADER_PACK, self.data[:self.HEADER_LEN])
1932 data = data[self.HEADER_LEN:]
1933
1934 if self.family == AF_INET:
1935 if len(data) < self.IPV4_LEN:
1936 break
1937 nexthop = ipnetwork.IPNetwork(unpack('>L', data[:self.IPV4_LEN])[0])
1938 self.value.append((nexthop, rtnh_ifindex, rtnh_flags, rtnh_hops))
1939
1940 elif self.family == AF_INET6:
1941 if len(data) < self.IPV6_LEN:
1942 break
1943 (data1, data2) = unpack('>QQ', data[:self.IPV6_LEN])
1944 nexthop = ipnetwork.IPNetwork(data1 << 64 | data2)
1945 self.value.append((nexthop, rtnh_ifindex, rtnh_flags, rtnh_hops))
1946
1947 data = data[(rtnh_len-self.RTNH_LEN-self.HEADER_LEN):]
1948
1949 self.value = tuple(self.value)
1950
1951
1952 class AttributeIFLA_LINKINFO(Attribute):
1953 """
1954 value is a dictionary such as:
1955
1956 {
1957 Link.IFLA_INFO_KIND : 'vlan',
1958 Link.IFLA_INFO_DATA : {
1959 Link.IFLA_VLAN_ID : vlanid,
1960 }
1961 }
1962 """
1963 decode_ifla_info_nested_data_handlers = {
1964 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_INFO_DATA: {
1965 "bridge": {
1966 # 1 byte attributes ############################################
1967 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_VLAN_FILTERING: Attribute.decode_one_byte_attribute,
1968 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_TOPOLOGY_CHANGE: Attribute.decode_one_byte_attribute,
1969 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_TOPOLOGY_CHANGE_DETECTED: Attribute.decode_one_byte_attribute,
1970 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_ROUTER: Attribute.decode_one_byte_attribute,
1971 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_SNOOPING: Attribute.decode_one_byte_attribute,
1972 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_QUERY_USE_IFADDR: Attribute.decode_one_byte_attribute,
1973 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_QUERIER: Attribute.decode_one_byte_attribute,
1974 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_NF_CALL_IPTABLES: Attribute.decode_one_byte_attribute,
1975 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_NF_CALL_IP6TABLES: Attribute.decode_one_byte_attribute,
1976 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_NF_CALL_ARPTABLES: Attribute.decode_one_byte_attribute,
1977 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_VLAN_STATS_ENABLED: Attribute.decode_one_byte_attribute,
1978 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_STATS_ENABLED: Attribute.decode_one_byte_attribute,
1979 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_IGMP_VERSION: Attribute.decode_one_byte_attribute,
1980 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_MLD_VERSION: Attribute.decode_one_byte_attribute,
1981
1982 # 2 bytes attributes ###########################################
1983 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_PRIORITY: Attribute.decode_two_bytes_attribute,
1984 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_GROUP_FWD_MASK: Attribute.decode_two_bytes_attribute,
1985 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_ROOT_PORT: Attribute.decode_two_bytes_attribute,
1986 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_VLAN_DEFAULT_PVID: Attribute.decode_two_bytes_attribute,
1987
1988 # 4 bytes attributes ###########################################
1989 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_AGEING_TIME: Attribute.decode_four_bytes_attribute,
1990 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_FORWARD_DELAY: Attribute.decode_four_bytes_attribute,
1991 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_HELLO_TIME: Attribute.decode_four_bytes_attribute,
1992 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MAX_AGE: Attribute.decode_four_bytes_attribute,
1993 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_STP_STATE: Attribute.decode_four_bytes_attribute,
1994 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_ROOT_PATH_COST: Attribute.decode_four_bytes_attribute,
1995 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_HASH_ELASTICITY: Attribute.decode_four_bytes_attribute,
1996 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_HASH_MAX: Attribute.decode_four_bytes_attribute,
1997 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_LAST_MEMBER_CNT: Attribute.decode_four_bytes_attribute,
1998 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_STARTUP_QUERY_CNT: Attribute.decode_four_bytes_attribute,
1999
2000 # 8 bytes attributes ###########################################
2001 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_MEMBERSHIP_INTVL: Attribute.decode_eight_bytes_attribute,
2002 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_QUERIER_INTVL: Attribute.decode_eight_bytes_attribute,
2003 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_LAST_MEMBER_INTVL: Attribute.decode_eight_bytes_attribute,
2004 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_QUERY_INTVL: Attribute.decode_eight_bytes_attribute,
2005 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_QUERY_RESPONSE_INTVL: Attribute.decode_eight_bytes_attribute,
2006 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_STARTUP_QUERY_INTVL: Attribute.decode_eight_bytes_attribute,
2007
2008 # vlan-protocol attribute ######################################
2009 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_VLAN_PROTOCOL: Attribute.decode_vlan_protocol_attribute
2010 },
2011 "bond": {
2012 # 1 byte attributes ############################################
2013 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_MODE: Attribute.decode_one_byte_attribute,
2014 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_USE_CARRIER: Attribute.decode_one_byte_attribute,
2015 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_LACP_RATE: Attribute.decode_one_byte_attribute,
2016 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_LACP_BYPASS: Attribute.decode_one_byte_attribute,
2017 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_XMIT_HASH_POLICY: Attribute.decode_one_byte_attribute,
2018 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_NUM_PEER_NOTIF: Attribute.decode_one_byte_attribute,
2019
2020 # 2 bytes attributes ###########################################
2021 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_ACTOR_SYS_PRIO: Attribute.decode_two_bytes_attribute,
2022
2023 # 4 bytes attributes ###########################################
2024 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_MIIMON: Attribute.decode_four_bytes_attribute,
2025 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_UPDELAY: Attribute.decode_four_bytes_attribute,
2026 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_DOWNDELAY: Attribute.decode_four_bytes_attribute,
2027 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_MIN_LINKS: Attribute.decode_four_bytes_attribute,
2028 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_PRIMARY: Attribute.decode_four_bytes_attribute,
2029
2030 # mac address attributes #######################################
2031 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_ACTOR_SYSTEM: Attribute.decode_mac_address_attribute,
2032
2033 # bond ad info attribute #######################################
2034 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_INFO: Attribute.decode_bond_ad_info_attribute,
2035 },
2036 "vlan": {
2037 # 2 bytes attributes ###########################################
2038 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VLAN_ID: Attribute.decode_two_bytes_attribute,
2039
2040 # vlan-protocol attribute ######################################
2041 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VLAN_PROTOCOL: Attribute.decode_vlan_protocol_attribute
2042 },
2043 "macvlan": {
2044 # 4 bytes attributes ###########################################
2045 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_MACVLAN_MODE: Attribute.decode_four_bytes_attribute,
2046 },
2047 "vxlan": {
2048 # 1 byte attributes ############################################
2049 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_TTL: Attribute.decode_one_byte_attribute,
2050 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_TOS: Attribute.decode_one_byte_attribute,
2051 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_LEARNING: Attribute.decode_one_byte_attribute,
2052 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_PROXY: Attribute.decode_one_byte_attribute,
2053 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_RSC: Attribute.decode_one_byte_attribute,
2054 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_L2MISS: Attribute.decode_one_byte_attribute,
2055 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_L3MISS: Attribute.decode_one_byte_attribute,
2056 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_UDP_CSUM: Attribute.decode_one_byte_attribute,
2057 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_UDP_ZERO_CSUM6_TX: Attribute.decode_one_byte_attribute,
2058 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_UDP_ZERO_CSUM6_RX: Attribute.decode_one_byte_attribute,
2059 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_REMCSUM_TX: Attribute.decode_one_byte_attribute,
2060 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_REMCSUM_RX: Attribute.decode_one_byte_attribute,
2061 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_REPLICATION_TYPE: Attribute.decode_one_byte_attribute,
2062
2063 # 2 bytes network byte order attributes ########################
2064 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_PORT: Attribute.decode_two_bytes_network_byte_order_attribute,
2065
2066 # 4 bytes attributes ###########################################
2067 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_ID: Attribute.decode_four_bytes_attribute,
2068 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_LINK: Attribute.decode_four_bytes_attribute,
2069 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_AGEING: Attribute.decode_four_bytes_attribute,
2070 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_LIMIT: Attribute.decode_four_bytes_attribute,
2071 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_PORT_RANGE: Attribute.decode_four_bytes_attribute,
2072
2073 # ipv4 attributes ##############################################
2074 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_GROUP: Attribute.decode_ipv4_address_attribute,
2075 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_LOCAL: Attribute.decode_ipv4_address_attribute,
2076 },
2077 "vrf": {
2078 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VRF_TABLE: Attribute.decode_four_bytes_attribute
2079 },
2080 "xfrm": {
2081 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_XFRM_IF_ID: Attribute.decode_four_bytes_attribute,
2082 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_XFRM_LINK: Attribute.decode_four_bytes_attribute
2083 },
2084
2085 # Tunnels:
2086 # There's is a lot of copy paste here because most of the tunnels
2087 # share the same attribute key / attribute index value, but ipv6
2088 # tunnels needs special handling for their ipv6 attributes.
2089 #
2090 # "gre", "gretap", "erspan", "ip6gre", "ip6gretap", "ip6erspan" are
2091 # identical as well with special handling for LOCAL and REMOTE for
2092 # the ipv6 tunnels
2093 "gre": {
2094 # 1 byte attributes ############################################
2095 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TTL: Attribute.decode_one_byte_attribute,
2096 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TOS: Attribute.decode_one_byte_attribute,
2097 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_PMTUDISC: Attribute.decode_one_byte_attribute,
2098
2099 # 2 bytes attributes ###########################################
2100 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IFLAGS: Attribute.decode_two_bytes_attribute,
2101 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OFLAGS: Attribute.decode_two_bytes_attribute,
2102 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_TYPE: Attribute.decode_two_bytes_attribute,
2103 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_SPORT: Attribute.decode_two_bytes_attribute,
2104 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_DPORT: Attribute.decode_two_bytes_attribute,
2105 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_FLAGS: Attribute.decode_two_bytes_attribute,
2106
2107 # 4 bytes attributes ###########################################
2108 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LINK: Attribute.decode_four_bytes_attribute,
2109 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IKEY: Attribute.decode_four_bytes_attribute,
2110 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OKEY: Attribute.decode_four_bytes_attribute,
2111
2112 # ipv4 attributes ##############################################
2113 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LOCAL: Attribute.decode_ipv4_address_attribute,
2114 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_REMOTE: Attribute.decode_ipv4_address_attribute
2115 },
2116 "gretap": {
2117 # 1 byte attributes ############################################
2118 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TTL: Attribute.decode_one_byte_attribute,
2119 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TOS: Attribute.decode_one_byte_attribute,
2120 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_PMTUDISC: Attribute.decode_one_byte_attribute,
2121
2122 # 2 bytes attributes ###########################################
2123 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IFLAGS: Attribute.decode_two_bytes_attribute,
2124 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OFLAGS: Attribute.decode_two_bytes_attribute,
2125 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_TYPE: Attribute.decode_two_bytes_attribute,
2126 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_SPORT: Attribute.decode_two_bytes_attribute,
2127 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_DPORT: Attribute.decode_two_bytes_attribute,
2128 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_FLAGS: Attribute.decode_two_bytes_attribute,
2129
2130 # 4 bytes attributes ###########################################
2131 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LINK: Attribute.decode_four_bytes_attribute,
2132 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IKEY: Attribute.decode_four_bytes_attribute,
2133 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OKEY: Attribute.decode_four_bytes_attribute,
2134
2135 # ipv4 attributes ##############################################
2136 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LOCAL: Attribute.decode_ipv4_address_attribute,
2137 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_REMOTE: Attribute.decode_ipv4_address_attribute
2138 },
2139 "erspan": {
2140 # 1 byte attributes ############################################
2141 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TTL: Attribute.decode_one_byte_attribute,
2142 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TOS: Attribute.decode_one_byte_attribute,
2143 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_PMTUDISC: Attribute.decode_one_byte_attribute,
2144
2145 # 2 bytes attributes ###########################################
2146 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IFLAGS: Attribute.decode_two_bytes_attribute,
2147 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OFLAGS: Attribute.decode_two_bytes_attribute,
2148 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_TYPE: Attribute.decode_two_bytes_attribute,
2149 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_SPORT: Attribute.decode_two_bytes_attribute,
2150 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_DPORT: Attribute.decode_two_bytes_attribute,
2151 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_FLAGS: Attribute.decode_two_bytes_attribute,
2152
2153 # 4 bytes attributes ###########################################
2154 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LINK: Attribute.decode_four_bytes_attribute,
2155 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IKEY: Attribute.decode_four_bytes_attribute,
2156 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OKEY: Attribute.decode_four_bytes_attribute,
2157
2158 # ipv4 attributes ##############################################
2159 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LOCAL: Attribute.decode_ipv4_address_attribute,
2160 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_REMOTE: Attribute.decode_ipv4_address_attribute
2161 },
2162 "ip6gre": {
2163 # 1 byte attributes ############################################
2164 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TTL: Attribute.decode_one_byte_attribute,
2165 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TOS: Attribute.decode_one_byte_attribute,
2166 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_PMTUDISC: Attribute.decode_one_byte_attribute,
2167
2168 # 2 bytes attributes ###########################################
2169 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IFLAGS: Attribute.decode_two_bytes_attribute,
2170 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OFLAGS: Attribute.decode_two_bytes_attribute,
2171 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_TYPE: Attribute.decode_two_bytes_attribute,
2172 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_SPORT: Attribute.decode_two_bytes_attribute,
2173 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_DPORT: Attribute.decode_two_bytes_attribute,
2174 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_FLAGS: Attribute.decode_two_bytes_attribute,
2175
2176 # 4 bytes attributes ###########################################
2177 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LINK: Attribute.decode_four_bytes_attribute,
2178 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IKEY: Attribute.decode_four_bytes_attribute,
2179 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OKEY: Attribute.decode_four_bytes_attribute,
2180
2181 # ipv6 attributes ##############################################
2182 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LOCAL: Attribute.decode_ipv6_address_attribute,
2183 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_REMOTE: Attribute.decode_ipv6_address_attribute
2184 },
2185 "ip6gretap": {
2186 # 1 byte attributes ############################################
2187 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TTL: Attribute.decode_one_byte_attribute,
2188 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TOS: Attribute.decode_one_byte_attribute,
2189 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_PMTUDISC: Attribute.decode_one_byte_attribute,
2190
2191 # 2 bytes attributes ###########################################
2192 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IFLAGS: Attribute.decode_two_bytes_attribute,
2193 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OFLAGS: Attribute.decode_two_bytes_attribute,
2194 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_TYPE: Attribute.decode_two_bytes_attribute,
2195 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_SPORT: Attribute.decode_two_bytes_attribute,
2196 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_DPORT: Attribute.decode_two_bytes_attribute,
2197 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_FLAGS: Attribute.decode_two_bytes_attribute,
2198
2199 # 4 bytes attributes ###########################################
2200 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LINK: Attribute.decode_four_bytes_attribute,
2201 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IKEY: Attribute.decode_four_bytes_attribute,
2202 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OKEY: Attribute.decode_four_bytes_attribute,
2203
2204 # ipv6 attributes ##############################################
2205 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LOCAL: Attribute.decode_ipv6_address_attribute,
2206 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_REMOTE: Attribute.decode_ipv6_address_attribute
2207 },
2208 "ip6erspan": {
2209 # 1 byte attributes ############################################
2210 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TTL: Attribute.decode_one_byte_attribute,
2211 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TOS: Attribute.decode_one_byte_attribute,
2212 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_PMTUDISC: Attribute.decode_one_byte_attribute,
2213
2214 # 2 bytes attributes ###########################################
2215 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IFLAGS: Attribute.decode_two_bytes_attribute,
2216 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OFLAGS: Attribute.decode_two_bytes_attribute,
2217 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_TYPE: Attribute.decode_two_bytes_attribute,
2218 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_SPORT: Attribute.decode_two_bytes_attribute,
2219 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_DPORT: Attribute.decode_two_bytes_attribute,
2220 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_FLAGS: Attribute.decode_two_bytes_attribute,
2221
2222 # 4 bytes attributes ###########################################
2223 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LINK: Attribute.decode_four_bytes_attribute,
2224 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IKEY: Attribute.decode_four_bytes_attribute,
2225 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OKEY: Attribute.decode_four_bytes_attribute,
2226
2227 # ipv6 attributes ##############################################
2228 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LOCAL: Attribute.decode_ipv6_address_attribute,
2229 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_REMOTE: Attribute.decode_ipv6_address_attribute
2230 },
2231
2232 # "ipip", "sit", "ip6tnl" are identical as well except for some
2233 # special ipv6 handling for LOCAL and REMOTE.
2234 "ipip": {
2235 # 1 byte attributes ############################################
2236 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_TTL: Attribute.decode_one_byte_attribute,
2237 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_TOS: Attribute.decode_one_byte_attribute,
2238 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_PMTUDISC: Attribute.decode_one_byte_attribute,
2239
2240 # 2 bytes attributes ###########################################
2241 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_ENCAP_TYPE: Attribute.decode_two_bytes_attribute,
2242 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_ENCAP_SPORT: Attribute.decode_two_bytes_attribute,
2243 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_ENCAP_DPORT: Attribute.decode_two_bytes_attribute,
2244 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_ENCAP_FLAGS: Attribute.decode_two_bytes_attribute,
2245
2246 # 4 bytes attributes ###########################################
2247 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_LINK: Attribute.decode_four_bytes_attribute,
2248
2249 # ipv4 attributes ##############################################
2250 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_LOCAL: Attribute.decode_ipv4_address_attribute,
2251 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_REMOTE: Attribute.decode_ipv4_address_attribute,
2252 },
2253 "sit": {
2254 # 1 byte attributes ############################################
2255 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_TTL: Attribute.decode_one_byte_attribute,
2256 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_TOS: Attribute.decode_one_byte_attribute,
2257 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_PMTUDISC: Attribute.decode_one_byte_attribute,
2258
2259 # 2 bytes attributes ###########################################
2260 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_ENCAP_TYPE: Attribute.decode_two_bytes_attribute,
2261 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_ENCAP_SPORT: Attribute.decode_two_bytes_attribute,
2262 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_ENCAP_DPORT: Attribute.decode_two_bytes_attribute,
2263 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_ENCAP_FLAGS: Attribute.decode_two_bytes_attribute,
2264
2265 # 4 bytes attributes ###########################################
2266 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_LINK: Attribute.decode_four_bytes_attribute,
2267
2268 # ipv4 attributes ##############################################
2269 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_LOCAL: Attribute.decode_ipv4_address_attribute,
2270 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_REMOTE: Attribute.decode_ipv4_address_attribute,
2271 },
2272 "ip6tnl": {
2273 # 1 byte attributes ############################################
2274 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_TTL: Attribute.decode_one_byte_attribute,
2275 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_TOS: Attribute.decode_one_byte_attribute,
2276 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_PMTUDISC: Attribute.decode_one_byte_attribute,
2277
2278 # 2 bytes attributes ###########################################
2279 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_ENCAP_TYPE: Attribute.decode_two_bytes_attribute,
2280 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_ENCAP_SPORT: Attribute.decode_two_bytes_attribute,
2281 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_ENCAP_DPORT: Attribute.decode_two_bytes_attribute,
2282 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_ENCAP_FLAGS: Attribute.decode_two_bytes_attribute,
2283
2284 # 4 bytes attributes ###########################################
2285 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_LINK: Attribute.decode_four_bytes_attribute,
2286
2287 # ipv6 attributes ##############################################
2288 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_LOCAL: Attribute.decode_ipv6_address_attribute,
2289 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_IPTUN_REMOTE: Attribute.decode_ipv6_address_attribute,
2290 },
2291
2292 # Same story with "vti", "vti6"...
2293 "vti": {
2294 # 4 bytes attributes ###########################################
2295 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VTI_LINK: Attribute.decode_four_bytes_attribute,
2296 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VTI_IKEY: Attribute.decode_four_bytes_attribute,
2297 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VTI_OKEY: Attribute.decode_four_bytes_attribute,
2298
2299 # ipv4 attributes ##############################################
2300 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VTI_LOCAL: Attribute.decode_ipv4_address_attribute,
2301 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VTI_REMOTE: Attribute.decode_ipv4_address_attribute
2302 },
2303 "vti6": {
2304 # 4 bytes attributes ###########################################
2305 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VTI_LINK: Attribute.decode_four_bytes_attribute,
2306 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VTI_IKEY: Attribute.decode_four_bytes_attribute,
2307 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VTI_OKEY: Attribute.decode_four_bytes_attribute,
2308
2309 # ipv6 attributes ##############################################
2310 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VTI_LOCAL: Attribute.decode_ipv6_address_attribute,
2311 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VTI_REMOTE: Attribute.decode_ipv6_address_attribute
2312 }
2313 },
2314 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_INFO_SLAVE_DATA: {
2315 "bridge": {
2316 # 1 byte attributes ############################################
2317 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_STATE: Attribute.decode_one_byte_attribute,
2318 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_MODE: Attribute.decode_one_byte_attribute,
2319 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_GUARD: Attribute.decode_one_byte_attribute,
2320 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_PROTECT: Attribute.decode_one_byte_attribute,
2321 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_FAST_LEAVE: Attribute.decode_one_byte_attribute,
2322 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_LEARNING: Attribute.decode_one_byte_attribute,
2323 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_UNICAST_FLOOD: Attribute.decode_one_byte_attribute,
2324 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_PROXYARP: Attribute.decode_one_byte_attribute,
2325 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_LEARNING_SYNC: Attribute.decode_one_byte_attribute,
2326 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_PROXYARP_WIFI: Attribute.decode_one_byte_attribute,
2327 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK: Attribute.decode_one_byte_attribute,
2328 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_CONFIG_PENDING: Attribute.decode_one_byte_attribute,
2329 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_MULTICAST_ROUTER: Attribute.decode_one_byte_attribute,
2330 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_MCAST_FLOOD: Attribute.decode_one_byte_attribute,
2331 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_BCAST_FLOOD: Attribute.decode_one_byte_attribute,
2332 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_MCAST_TO_UCAST: Attribute.decode_one_byte_attribute,
2333 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_VLAN_TUNNEL: Attribute.decode_one_byte_attribute,
2334 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_PEER_LINK: Attribute.decode_one_byte_attribute,
2335 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_DUAL_LINK: Attribute.decode_one_byte_attribute,
2336 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_NEIGH_SUPPRESS: Attribute.decode_one_byte_attribute,
2337
2338 # 2 bytes attributes ###########################################
2339 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_PRIORITY: Attribute.decode_two_bytes_attribute,
2340 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_DESIGNATED_PORT: Attribute.decode_two_bytes_attribute,
2341 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_DESIGNATED_COST: Attribute.decode_two_bytes_attribute,
2342 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_ID: Attribute.decode_two_bytes_attribute,
2343 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_NO: Attribute.decode_two_bytes_attribute,
2344 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_GROUP_FWD_MASK: Attribute.decode_two_bytes_attribute,
2345 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_GROUP_FWD_MASKHI: Attribute.decode_two_bytes_attribute,
2346
2347 # 4 bytes attributes ###########################################
2348 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_COST: Attribute.decode_four_bytes_attribute,
2349 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_BACKUP_PORT: Attribute.decode_four_bytes_attribute,
2350 },
2351 "bond": {
2352 # 1 byte attributes ############################################
2353 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_SLAVE_STATE: Attribute.decode_one_byte_attribute,
2354 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_SLAVE_MII_STATUS: Attribute.decode_one_byte_attribute,
2355 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE: Attribute.decode_one_byte_attribute,
2356 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_SLAVE_AD_RX_BYPASS: Attribute.decode_one_byte_attribute,
2357
2358 # 2 bytes attributes ###########################################
2359 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_SLAVE_QUEUE_ID: Attribute.decode_two_bytes_attribute,
2360 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_SLAVE_AD_AGGREGATOR_ID: Attribute.decode_two_bytes_attribute,
2361
2362 # 4 bytes attributes ###########################################
2363 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_SLAVE_PERM_HWADDR: Attribute.decode_four_bytes_attribute,
2364 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_SLAVE_LINK_FAILURE_COUNT: Attribute.decode_four_bytes_attribute,
2365 }
2366 }
2367 }
2368
2369 encode_ifla_info_nested_data_handlers = {
2370 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_INFO_DATA: {
2371 "vlan": {
2372 # 2 bytes attributes ###########################################
2373 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VLAN_ID: Attribute.encode_two_bytes_attribute,
2374
2375 # vlan-protocol attribute ######################################
2376 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VLAN_PROTOCOL: Attribute.encode_vlan_protocol_attribute,
2377 },
2378 "macvlan": {
2379 # 4 bytes attributes ###########################################
2380 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_MACVLAN_MODE: Attribute.encode_four_bytes_attribute,
2381 },
2382 "vxlan": {
2383 # 1 byte attributes ############################################
2384 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_TTL: Attribute.encode_one_byte_attribute,
2385 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_TOS: Attribute.encode_one_byte_attribute,
2386 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_LEARNING: Attribute.encode_one_byte_attribute,
2387 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_PROXY: Attribute.encode_one_byte_attribute,
2388 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_RSC: Attribute.encode_one_byte_attribute,
2389 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_L2MISS: Attribute.encode_one_byte_attribute,
2390 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_L3MISS: Attribute.encode_one_byte_attribute,
2391 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_UDP_CSUM: Attribute.encode_one_byte_attribute,
2392 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_UDP_ZERO_CSUM6_TX: Attribute.encode_one_byte_attribute,
2393 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_UDP_ZERO_CSUM6_RX: Attribute.encode_one_byte_attribute,
2394 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_REMCSUM_TX: Attribute.encode_one_byte_attribute,
2395 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_REMCSUM_RX: Attribute.encode_one_byte_attribute,
2396 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_REPLICATION_TYPE: Attribute.encode_one_byte_attribute,
2397
2398 # 4 bytes attributes ###########################################
2399 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_ID: Attribute.encode_four_bytes_attribute,
2400 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_LINK: Attribute.encode_four_bytes_attribute,
2401 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_AGEING: Attribute.encode_four_bytes_attribute,
2402 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_LIMIT: Attribute.encode_four_bytes_attribute,
2403 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_PORT_RANGE: Attribute.encode_four_bytes_attribute,
2404
2405 # ipv4 attributes ##############################################
2406 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_GROUP: Attribute.encode_ipv4_attribute,
2407 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_LOCAL: Attribute.encode_ipv4_attribute,
2408
2409 # vxlan-port attribute #########################################
2410 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VXLAN_PORT: Attribute.encode_vxlan_port_attribute,
2411 },
2412 "bond": {
2413 # 1 byte attributes ############################################
2414 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_NUM_PEER_NOTIF: Attribute.encode_one_byte_attribute,
2415 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_USE_CARRIER: Attribute.encode_one_byte_attribute,
2416 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_LACP_BYPASS: Attribute.encode_one_byte_attribute,
2417 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_LACP_RATE: Attribute.encode_one_byte_attribute,
2418
2419 # bond-mode attribute ##########################################
2420 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_MODE: Attribute.encode_bond_mode_attribute,
2421
2422 # bond-xmit-hash-policy attribute ##############################
2423 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_XMIT_HASH_POLICY: Attribute.encode_bond_xmit_hash_policy_attribute,
2424
2425 # 2 bytes attributes ###########################################
2426 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_ACTOR_SYS_PRIO: Attribute.encode_two_bytes_attribute,
2427
2428 # 4 bytes attributes ###########################################
2429 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_MIIMON: Attribute.encode_four_bytes_attribute,
2430 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_UPDELAY: Attribute.encode_four_bytes_attribute,
2431 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_DOWNDELAY: Attribute.encode_four_bytes_attribute,
2432 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_MIN_LINKS: Attribute.encode_four_bytes_attribute,
2433 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_PRIMARY: Attribute.encode_four_bytes_attribute,
2434
2435 # mac address attribute ########################################
2436 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_ACTOR_SYSTEM: Attribute.encode_mac_address_attribute
2437 },
2438 "vrf": {
2439 # 4 bytes attributes ###########################################
2440 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_VRF_TABLE: Attribute.encode_four_bytes_attribute
2441 },
2442 "bridge": {
2443 # 1 byte attributes ############################################
2444 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_VLAN_FILTERING: Attribute.encode_one_byte_attribute,
2445 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_TOPOLOGY_CHANGE: Attribute.encode_one_byte_attribute,
2446 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_TOPOLOGY_CHANGE_DETECTED: Attribute.encode_one_byte_attribute,
2447 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_ROUTER: Attribute.encode_one_byte_attribute,
2448 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_SNOOPING: Attribute.encode_one_byte_attribute,
2449 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_QUERY_USE_IFADDR: Attribute.encode_one_byte_attribute,
2450 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_QUERIER: Attribute.encode_one_byte_attribute,
2451 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_NF_CALL_IPTABLES: Attribute.encode_one_byte_attribute,
2452 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_NF_CALL_IP6TABLES: Attribute.encode_one_byte_attribute,
2453 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_NF_CALL_ARPTABLES: Attribute.encode_one_byte_attribute,
2454 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_VLAN_STATS_ENABLED: Attribute.encode_one_byte_attribute,
2455 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_STATS_ENABLED: Attribute.encode_one_byte_attribute,
2456 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_IGMP_VERSION: Attribute.encode_one_byte_attribute,
2457 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_MLD_VERSION: Attribute.encode_one_byte_attribute,
2458
2459 # 2 bytes attributes ###########################################
2460 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_PRIORITY: Attribute.encode_two_bytes_attribute,
2461 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_GROUP_FWD_MASK: Attribute.encode_two_bytes_attribute,
2462 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_ROOT_PORT: Attribute.encode_two_bytes_attribute,
2463 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_VLAN_DEFAULT_PVID: Attribute.encode_two_bytes_attribute,
2464
2465 # 4 bytes attributes ###########################################
2466 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_FORWARD_DELAY: Attribute.encode_four_bytes_attribute,
2467 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_HELLO_TIME: Attribute.encode_four_bytes_attribute,
2468 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MAX_AGE: Attribute.encode_four_bytes_attribute,
2469 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_AGEING_TIME: Attribute.encode_four_bytes_attribute,
2470 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_STP_STATE: Attribute.encode_four_bytes_attribute,
2471 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_ROOT_PATH_COST: Attribute.encode_four_bytes_attribute,
2472 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_HASH_ELASTICITY: Attribute.encode_four_bytes_attribute,
2473 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_HASH_MAX: Attribute.encode_four_bytes_attribute,
2474 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_LAST_MEMBER_CNT: Attribute.encode_four_bytes_attribute,
2475 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_STARTUP_QUERY_CNT: Attribute.encode_four_bytes_attribute,
2476
2477 # 8 bytes attributes ###########################################
2478 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_LAST_MEMBER_INTVL: Attribute.encode_eight_bytes_attribute,
2479 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_MEMBERSHIP_INTVL: Attribute.encode_eight_bytes_attribute,
2480 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_QUERIER_INTVL: Attribute.encode_eight_bytes_attribute,
2481 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_QUERY_INTVL: Attribute.encode_eight_bytes_attribute,
2482 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_QUERY_RESPONSE_INTVL: Attribute.encode_eight_bytes_attribute,
2483 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_STARTUP_QUERY_INTVL: Attribute.encode_eight_bytes_attribute,
2484
2485 # vlan-protocol attribute ######################################
2486 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_VLAN_PROTOCOL: Attribute.encode_vlan_protocol_attribute
2487 },
2488 # Tunnels:
2489 # There's is a lot of copy paste here because most of the tunnels
2490 # share the same attribute key / attribute index value, but ipv6
2491 # tunnels needs special handling for their ipv6 attributes.
2492 #
2493 # "gre", "gretap", "erspan", "ip6gre", "ip6gretap", "ip6erspan" are
2494 # identical as well with special handling for LOCAL and REMOTE for
2495 # the ipv6 tunnels
2496 "gre": { # == ("gre", "gretap", "erspan")
2497 # 1 byte attributes ############################################
2498 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TTL: Attribute.encode_one_byte_attribute,
2499 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TOS: Attribute.encode_one_byte_attribute,
2500 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_PMTUDISC: Attribute.encode_one_byte_attribute,
2501
2502 # 2 bytes attributes ###########################################
2503 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IFLAGS: Attribute.encode_two_bytes_attribute,
2504 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OFLAGS: Attribute.encode_two_bytes_attribute,
2505 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_TYPE: Attribute.encode_two_bytes_attribute,
2506 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_SPORT: Attribute.encode_two_bytes_attribute,
2507 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_DPORT: Attribute.encode_two_bytes_attribute,
2508 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_FLAGS: Attribute.encode_two_bytes_attribute,
2509
2510 # 4 bytes attributes ###########################################
2511 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LINK: Attribute.encode_four_bytes_attribute,
2512 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IKEY: Attribute.encode_four_bytes_attribute,
2513 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OKEY: Attribute.encode_four_bytes_attribute,
2514
2515 # ipv4 attributes ##############################################
2516 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LOCAL: Attribute.encode_ipv4_attribute,
2517 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_REMOTE: Attribute.encode_ipv4_attribute,
2518 },
2519 "gretap": { # == ("gre", "gretap", "erspan")
2520 # 1 byte attributes ############################################
2521 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TTL: Attribute.encode_one_byte_attribute,
2522 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TOS: Attribute.encode_one_byte_attribute,
2523 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_PMTUDISC: Attribute.encode_one_byte_attribute,
2524
2525 # 2 bytes attributes ###########################################
2526 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IFLAGS: Attribute.encode_two_bytes_attribute,
2527 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OFLAGS: Attribute.encode_two_bytes_attribute,
2528 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_TYPE: Attribute.encode_two_bytes_attribute,
2529 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_SPORT: Attribute.encode_two_bytes_attribute,
2530 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_DPORT: Attribute.encode_two_bytes_attribute,
2531 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_FLAGS: Attribute.encode_two_bytes_attribute,
2532
2533 # 4 bytes attributes ###########################################
2534 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LINK: Attribute.encode_four_bytes_attribute,
2535 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IKEY: Attribute.encode_four_bytes_attribute,
2536 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OKEY: Attribute.encode_four_bytes_attribute,
2537
2538 # ipv4 attributes ##############################################
2539 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LOCAL: Attribute.encode_ipv4_attribute,
2540 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_REMOTE: Attribute.encode_ipv4_attribute,
2541 },
2542 "erspan": { # == ("gre", "gretap", "erspan")
2543 # 1 byte attributes ############################################
2544 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TTL: Attribute.encode_one_byte_attribute,
2545 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TOS: Attribute.encode_one_byte_attribute,
2546 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_PMTUDISC: Attribute.encode_one_byte_attribute,
2547
2548 # 2 bytes attributes ###########################################
2549 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IFLAGS: Attribute.encode_two_bytes_attribute,
2550 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OFLAGS: Attribute.encode_two_bytes_attribute,
2551 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_TYPE: Attribute.encode_two_bytes_attribute,
2552 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_SPORT: Attribute.encode_two_bytes_attribute,
2553 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_DPORT: Attribute.encode_two_bytes_attribute,
2554 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_FLAGS: Attribute.encode_two_bytes_attribute,
2555
2556 # 4 bytes attributes ###########################################
2557 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LINK: Attribute.encode_four_bytes_attribute,
2558 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IKEY: Attribute.encode_four_bytes_attribute,
2559 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OKEY: Attribute.encode_four_bytes_attribute,
2560
2561 # ipv4 attributes ##############################################
2562 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LOCAL: Attribute.encode_ipv4_attribute,
2563 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_REMOTE: Attribute.encode_ipv4_attribute,
2564 },
2565 "ip6gre": { # == ("ip6gre", "ip6gretap", "ip6erspan")
2566 # 1 byte attributes ############################################
2567 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TTL: Attribute.encode_one_byte_attribute,
2568 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TOS: Attribute.encode_one_byte_attribute,
2569 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_PMTUDISC: Attribute.encode_one_byte_attribute,
2570
2571 # 2 bytes attributes ###########################################
2572 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IFLAGS: Attribute.encode_two_bytes_attribute,
2573 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OFLAGS: Attribute.encode_two_bytes_attribute,
2574 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_TYPE: Attribute.encode_two_bytes_attribute,
2575 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_SPORT: Attribute.encode_two_bytes_attribute,
2576 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_DPORT: Attribute.encode_two_bytes_attribute,
2577 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_FLAGS: Attribute.encode_two_bytes_attribute,
2578
2579 # 4 bytes attributes ###########################################
2580 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LINK: Attribute.encode_four_bytes_attribute,
2581 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IKEY: Attribute.encode_four_bytes_attribute,
2582 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OKEY: Attribute.encode_four_bytes_attribute,
2583
2584 # ipv6 attributes ##############################################
2585 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LOCAL: Attribute.encode_ipv6_attribute,
2586 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_REMOTE: Attribute.encode_ipv6_attribute,
2587 },
2588 "ip6gretap": { # == ("ip6gre", "ip6gretap", "ip6erspan")
2589 # 1 byte attributes ############################################
2590 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TTL: Attribute.encode_one_byte_attribute,
2591 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TOS: Attribute.encode_one_byte_attribute,
2592 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_PMTUDISC: Attribute.encode_one_byte_attribute,
2593
2594 # 2 bytes attributes ###########################################
2595 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IFLAGS: Attribute.encode_two_bytes_attribute,
2596 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OFLAGS: Attribute.encode_two_bytes_attribute,
2597 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_TYPE: Attribute.encode_two_bytes_attribute,
2598 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_SPORT: Attribute.encode_two_bytes_attribute,
2599 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_DPORT: Attribute.encode_two_bytes_attribute,
2600 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_FLAGS: Attribute.encode_two_bytes_attribute,
2601
2602 # 4 bytes attributes ###########################################
2603 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LINK: Attribute.encode_four_bytes_attribute,
2604 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IKEY: Attribute.encode_four_bytes_attribute,
2605 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OKEY: Attribute.encode_four_bytes_attribute,
2606
2607 # ipv6 attributes ##############################################
2608 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LOCAL: Attribute.encode_ipv6_attribute,
2609 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_REMOTE: Attribute.encode_ipv6_attribute,
2610 },
2611 "ip6erspan": { # == ("ip6gre", "ip6gretap", "ip6erspan")
2612 # 1 byte attributes ############################################
2613 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TTL: Attribute.encode_one_byte_attribute,
2614 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_TOS: Attribute.encode_one_byte_attribute,
2615 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_PMTUDISC: Attribute.encode_one_byte_attribute,
2616
2617 # 2 bytes attributes ###########################################
2618 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IFLAGS: Attribute.encode_two_bytes_attribute,
2619 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OFLAGS: Attribute.encode_two_bytes_attribute,
2620 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_TYPE: Attribute.encode_two_bytes_attribute,
2621 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_SPORT: Attribute.encode_two_bytes_attribute,
2622 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_DPORT: Attribute.encode_two_bytes_attribute,
2623 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_ENCAP_FLAGS: Attribute.encode_two_bytes_attribute,
2624
2625 # 4 bytes attributes ###########################################
2626 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LINK: Attribute.encode_four_bytes_attribute,
2627 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_IKEY: Attribute.encode_four_bytes_attribute,
2628 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_OKEY: Attribute.encode_four_bytes_attribute,
2629
2630 # ipv6 attributes ##############################################
2631 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_LOCAL: Attribute.encode_ipv6_attribute,
2632 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_GRE_REMOTE: Attribute.encode_ipv6_attribute,
2633 }
2634 },
2635 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_INFO_SLAVE_DATA: {
2636 "bridge": {
2637 # 1 byte attributes ############################################
2638 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_STATE: Attribute.encode_one_byte_attribute,
2639 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_MODE: Attribute.encode_one_byte_attribute,
2640 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_GUARD: Attribute.encode_one_byte_attribute,
2641 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_PROTECT: Attribute.encode_one_byte_attribute,
2642 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_FAST_LEAVE: Attribute.encode_one_byte_attribute,
2643 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_LEARNING: Attribute.encode_one_byte_attribute,
2644 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_UNICAST_FLOOD: Attribute.encode_one_byte_attribute,
2645 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_PROXYARP: Attribute.encode_one_byte_attribute,
2646 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_LEARNING_SYNC: Attribute.encode_one_byte_attribute,
2647 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_PROXYARP_WIFI: Attribute.encode_one_byte_attribute,
2648 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK: Attribute.encode_one_byte_attribute,
2649 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_CONFIG_PENDING: Attribute.encode_one_byte_attribute,
2650 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_MULTICAST_ROUTER: Attribute.encode_one_byte_attribute,
2651 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_MCAST_FLOOD: Attribute.encode_one_byte_attribute,
2652 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_MCAST_TO_UCAST: Attribute.encode_one_byte_attribute,
2653 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_VLAN_TUNNEL: Attribute.encode_one_byte_attribute,
2654 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_BCAST_FLOOD: Attribute.encode_one_byte_attribute,
2655 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_PEER_LINK: Attribute.encode_one_byte_attribute,
2656 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_DUAL_LINK: Attribute.encode_one_byte_attribute,
2657 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_NEIGH_SUPPRESS: Attribute.encode_one_byte_attribute,
2658
2659 # 2 bytes attributes ###########################################
2660 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_PRIORITY: Attribute.encode_two_bytes_attribute,
2661 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_DESIGNATED_PORT: Attribute.encode_two_bytes_attribute,
2662 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_DESIGNATED_COST: Attribute.encode_two_bytes_attribute,
2663 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_ID: Attribute.encode_two_bytes_attribute,
2664 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_NO: Attribute.encode_two_bytes_attribute,
2665 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_GROUP_FWD_MASK: Attribute.encode_two_bytes_attribute,
2666 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_GROUP_FWD_MASKHI: Attribute.encode_two_bytes_attribute,
2667
2668 # 4 bytes attributes ###########################################
2669 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_COST: Attribute.encode_four_bytes_attribute,
2670 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BRPORT_BACKUP_PORT: Attribute.encode_four_bytes_attribute,
2671 },
2672 }
2673 }
2674
2675 ifla_info_nested_data_attributes_to_string_dict = {
2676 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_INFO_DATA: {
2677 "bond": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_bond_to_string,
2678 "vlan": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_vlan_to_string,
2679 "vxlan": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_vxlan_to_string,
2680 "bridge": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_br_to_string,
2681 "macvlan": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_macvlan_to_string,
2682 "vrf": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_vrf_to_string,
2683 "gre": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_gre_to_string,
2684 "gretap": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_gre_to_string,
2685 "erspan": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_gre_to_string,
2686 "ip6gre": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_gre_to_string,
2687 "ip6gretap": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_gre_to_string,
2688 "ip6erspan": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_gre_to_string,
2689 "vti": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_vti_to_string,
2690 "vti6": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_vti_to_string,
2691 "ipip": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_iptun_to_string,
2692 "sit": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_iptun_to_string,
2693 "ip6tnl": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_iptun_to_string
2694 },
2695 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_INFO_SLAVE_DATA: {
2696 "bridge": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_brport_to_string,
2697 "bond": NetlinkPacket_IFLA_LINKINFO_Attributes.ifla_bond_slave_to_string
2698 }
2699 }
2700
2701 def __init__(self, atype, string, family, logger):
2702 Attribute.__init__(self, atype, string, logger)
2703
2704 def encode_ifla_info_nested_data(self, sub_attr_pack_layout, sub_attr_type, sub_attr_type_string, sub_attr_value, encode_handlers, ifla_info_nested_attr_to_str_dict, kind):
2705 sub_attr_payload = [0, sub_attr_type | NLA_F_NESTED]
2706
2707 if not encode_handlers:
2708 self.log.log(
2709 SYSLOG_EXTRA_DEBUG,
2710 "Add support for encoding %s for %s link kind" % (sub_attr_type_string, kind)
2711 )
2712 else:
2713 for (info_data_type, info_data_value) in sub_attr_value.items():
2714 encode_handler = encode_handlers.get(info_data_type)
2715
2716 if encode_handler:
2717 encode_handler(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value)
2718 else:
2719 self.log.log(
2720 SYSLOG_EXTRA_DEBUG,
2721 "Add support for encoding %s %s sub-attribute %s (%d)"
2722 % (
2723 sub_attr_type_string,
2724 kind,
2725 ifla_info_nested_attr_to_str_dict.get(info_data_type),
2726 info_data_type
2727 )
2728 )
2729
2730 return sub_attr_payload
2731
2732 def encode(self):
2733 pack_layout = [self.HEADER_PACK]
2734 payload = [0, self.atype | NLA_F_NESTED]
2735 attr_length_index = 0
2736
2737 kind = self.value.get(Link.IFLA_INFO_KIND)
2738 slave_kind = self.value.get(Link.IFLA_INFO_SLAVE_KIND)
2739
2740 if not slave_kind and kind not in (
2741 "vrf",
2742 "vlan",
2743 "vxlan",
2744 "bond",
2745 "dummy",
2746 "bridge",
2747 "macvlan",
2748 "gre",
2749 "gretap",
2750 "erspan",
2751 "ip6gre",
2752 "ip6gretap",
2753 "ip6erspan",
2754 "vti",
2755 "vti6",
2756 "ipip",
2757 "sit",
2758 "ip6tnl",
2759
2760 ):
2761 self.log.debug('Unsupported IFLA_INFO_KIND %s' % kind)
2762 return
2763
2764 elif not kind and slave_kind != 'bridge':
2765 # only support brport for now.
2766 raise Exception('Unsupported IFLA_INFO_SLAVE_KIND %s' % slave_kind)
2767
2768 # For now this assumes that all data will be packed in the native endian
2769 # order (=). If a field is added that needs to be packed via network
2770 # order (>) then some smarts will need to be added to split the pack_layout
2771 # string at the >, split the payload and make the needed pack() calls.
2772 # Until we cross that bridge though we will keep things nice and simple and
2773 # pack everything via a single pack() call.
2774
2775 for (sub_attr_type, sub_attr_value) in self.value.items():
2776 sub_attr_pack_layout = ['=', 'HH']
2777 sub_attr_payload = [0, sub_attr_type]
2778 sub_attr_length_index = 0
2779
2780 if sub_attr_type in (Link.IFLA_INFO_KIND, Link.IFLA_INFO_SLAVE_KIND):
2781 sub_attr_pack_layout.append('%ds' % len(sub_attr_value))
2782 sub_attr_payload.append(sub_attr_value.encode("utf-8"))
2783
2784 elif sub_attr_type == Link.IFLA_INFO_DATA:
2785 sub_attr_payload = self.encode_ifla_info_nested_data(
2786 sub_attr_pack_layout,
2787 sub_attr_type,
2788 "IFLA_INFO_DATA",
2789 sub_attr_value,
2790 self.encode_ifla_info_nested_data_handlers.get(Link.IFLA_INFO_DATA, {}).get(kind),
2791 self.ifla_info_nested_data_attributes_to_string_dict.get(Link.IFLA_INFO_DATA, {}).get(kind),
2792 kind
2793 )
2794
2795 elif sub_attr_type == Link.IFLA_INFO_SLAVE_DATA:
2796 sub_attr_payload = self.encode_ifla_info_nested_data(
2797 sub_attr_pack_layout,
2798 sub_attr_type,
2799 "IFLA_INFO_SLAVE_DATA",
2800 sub_attr_value,
2801 self.encode_ifla_info_nested_data_handlers.get(Link.IFLA_INFO_SLAVE_DATA, {}).get(slave_kind),
2802 self.ifla_info_nested_data_attributes_to_string_dict.get(Link.IFLA_INFO_SLAVE_DATA, {}).get(slave_kind),
2803 slave_kind
2804 )
2805
2806 else:
2807 self.log.log(SYSLOG_EXTRA_DEBUG, 'Add support for encoding IFLA_LINKINFO sub-attribute type %d' % sub_attr_type)
2808 continue
2809
2810 sub_attr_length = calcsize(''.join(sub_attr_pack_layout))
2811 sub_attr_payload[sub_attr_length_index] = sub_attr_length
2812
2813 # add padding
2814 for x in range(self.pad_bytes_needed(sub_attr_length)):
2815 sub_attr_pack_layout.append('x')
2816
2817 # The [1:] is to remove the leading = so that when we do the ''.join() later
2818 # we do not end up with an = in the middle of the pack layout string. There
2819 # will be an = at the beginning via self.HEADER_PACK
2820 sub_attr_pack_layout = sub_attr_pack_layout[1:]
2821
2822 # Now extend the ovarall attribute pack_layout/payload to include this sub-attribute
2823 pack_layout.extend(sub_attr_pack_layout)
2824 payload.extend(sub_attr_payload)
2825
2826 pack_layout = ''.join(pack_layout)
2827
2828 # Fill in the length field
2829 length = calcsize(pack_layout)
2830 payload[attr_length_index] = length
2831
2832 raw = pack(pack_layout, *payload)
2833 raw = self.pad(length, raw)
2834 return raw
2835
2836 def get_bool_value(self, value, default=None):
2837 try:
2838 return value_to_bool_dict[value]
2839 except KeyError:
2840 self.log.debug('%s: unsupported boolean value' % value)
2841 return default
2842
2843 def get_index(self, tbl, attr, value, default=None):
2844 try:
2845 return tbl[value]
2846 except KeyError:
2847 self.log.debug('unsupported %s value %s (%s)' % (attr, value, tbl.keys()))
2848 return default
2849
2850 def decode_ifla_info_nested_data(self, kind, ifla_info_nested_kind_str, sub_attr_type, sub_attr_type_str, data, sub_attr_end):
2851 sub_attr_data = data[4:sub_attr_end]
2852 ifla_info_nested_data = {}
2853
2854 if not kind:
2855 self.log.warning("%s is not known...we cannot parse %s" % (ifla_info_nested_kind_str, sub_attr_type_str))
2856 else:
2857 ifla_info_nested_data_handlers = self.decode_ifla_info_nested_data_handlers.get(sub_attr_type, {}).get(kind)
2858 ifla_info_nested_attr_to_str_dict = self.ifla_info_nested_data_attributes_to_string_dict.get(sub_attr_type, {}).get(kind)
2859
2860 if not ifla_info_nested_data_handlers or not ifla_info_nested_attr_to_str_dict:
2861 self.log.log(
2862 SYSLOG_EXTRA_DEBUG,
2863 "%s: decode: unsupported %s %s"
2864 % (sub_attr_type_str, ifla_info_nested_kind_str, kind)
2865 )
2866 else:
2867 while sub_attr_data:
2868 (info_nested_data_length, info_nested_data_type) = unpack("=HH", sub_attr_data[:4])
2869 info_nested_data_end = padded_length(info_nested_data_length)
2870 handler = ifla_info_nested_data_handlers.get(info_nested_data_type)
2871 try:
2872 if handler:
2873 ifla_info_nested_data[info_nested_data_type] = handler(sub_attr_data, info_nested_data_end)
2874 else:
2875 self.log.log(
2876 SYSLOG_EXTRA_DEBUG,
2877 "Add support for decoding %s %s, attribute %s (%s)"
2878 % (
2879 ifla_info_nested_kind_str,
2880 kind,
2881 ifla_info_nested_attr_to_str_dict.get(info_nested_data_type, "UNKNOWN"),
2882 info_nested_data_type
2883 )
2884 )
2885 except Exception as e:
2886 self.log.warning(
2887 "%s: %s: attribute %s: %s (%s)"
2888 % (
2889 ifla_info_nested_kind_str,
2890 kind,
2891 ifla_info_nested_attr_to_str_dict.get(info_nested_data_type, "UNKNOWN"),
2892 info_nested_data_type,
2893 str(e)
2894 )
2895 )
2896
2897 sub_attr_data = sub_attr_data[info_nested_data_end:]
2898
2899 return ifla_info_nested_data
2900
2901 def decode(self, parent_msg, data):
2902 """
2903 value is a dictionary such as:
2904
2905 {
2906 Link.IFLA_INFO_KIND : 'vlan',
2907 Link.IFLA_INFO_DATA : {
2908 Link.IFLA_VLAN_ID : vlanid,
2909 }
2910 }
2911 """
2912 self.decode_length_type(data)
2913 self.value = {}
2914
2915 data = self.data[4:]
2916
2917 # IFLA_MACVLAN_MODE and IFLA_VLAN_ID both have a value of 1 and both are
2918 # valid IFLA_INFO_DATA entries :( The sender must TX IFLA_INFO_KIND
2919 # first in order for us to know if "1" is IFLA_MACVLAN_MODE vs IFLA_VLAN_ID.
2920
2921 while data:
2922 (sub_attr_length, sub_attr_type) = unpack('=HH', data[:4])
2923 sub_attr_end = padded_length(sub_attr_length)
2924
2925 if sub_attr_type & NLA_F_NESTED:
2926 sub_attr_type ^= NLA_F_NESTED
2927
2928 if not sub_attr_length:
2929 self.log.error('parsed a zero length sub-attr')
2930 return
2931
2932 if sub_attr_type in (Link.IFLA_INFO_KIND, Link.IFLA_INFO_SLAVE_KIND):
2933 self.value[sub_attr_type] = remove_trailing_null(unpack("%ds" % (sub_attr_length - 4), data[4:sub_attr_length])[0]).decode("utf-8")
2934
2935 elif sub_attr_type == Link.IFLA_INFO_DATA:
2936 self.value[Link.IFLA_INFO_DATA] = self.decode_ifla_info_nested_data(
2937 self.value.get(Link.IFLA_INFO_KIND), "IFLA_INFO_KIND",
2938 Link.IFLA_INFO_DATA, "IFLA_INFO_DATA",
2939 data, sub_attr_end,
2940 )
2941
2942 elif sub_attr_type == Link.IFLA_INFO_SLAVE_DATA:
2943 self.value[Link.IFLA_INFO_SLAVE_DATA] = self.decode_ifla_info_nested_data(
2944 self.value.get(Link.IFLA_INFO_SLAVE_KIND), "IFLA_INFO_SLAVE_KIND",
2945 Link.IFLA_INFO_SLAVE_DATA, "IFLA_INFO_SLAVE_DATA",
2946 data, sub_attr_end,
2947 )
2948
2949 else:
2950 self.log.log(
2951 SYSLOG_EXTRA_DEBUG,
2952 'Add support for decoding IFLA_LINKINFO sub-attribute type %s (%d), length %d, padded to %d'
2953 % (parent_msg.get_ifla_info_string(sub_attr_type), sub_attr_type, sub_attr_length, sub_attr_end)
2954 )
2955
2956 data = data[sub_attr_end:]
2957
2958 def dump_lines(self, dump_buffer, line_number, color):
2959 line_number = self.dump_first_line(dump_buffer, line_number, color)
2960 extra = ''
2961
2962 next_sub_attr_line = 0
2963 sub_attr_line = True
2964
2965 for x in range(1, self.attr_end//4):
2966 start = x * 4
2967 end = start + 4
2968
2969 if line_number == next_sub_attr_line:
2970 sub_attr_line = True
2971
2972 if sub_attr_line:
2973 sub_attr_line = False
2974
2975 (sub_attr_length, sub_attr_type) = unpack('=HH', self.data[start:start+4])
2976 sub_attr_end = padded_length(sub_attr_length)
2977
2978 next_sub_attr_line = line_number + (sub_attr_end//4)
2979
2980 if sub_attr_end == sub_attr_length:
2981 padded_to = ', '
2982 else:
2983 padded_to = ' padded to %d, ' % sub_attr_end
2984
2985 if sub_attr_type & NLA_F_NESTED:
2986 sub_attr_type ^= NLA_F_NESTED
2987
2988 extra = 'Nested Attribute - Length %s (%d)%s Type %s (%d) %s (%s)' % \
2989 (zfilled_hex(sub_attr_length, 4), sub_attr_length,
2990 padded_to,
2991 zfilled_hex(sub_attr_type, 4), sub_attr_type,
2992 Link.ifla_info_to_string.get(sub_attr_type), sub_attr_type)
2993 else:
2994 extra = ''
2995
2996 dump_buffer.append(data_to_color_text(line_number, color, self.data[start:end], extra))
2997 line_number += 1
2998
2999 return line_number
3000
3001 def get_pretty_value(self, obj=None):
3002
3003 if obj and callable(obj):
3004 return obj(self.value)
3005
3006 value_pretty = self.value
3007 ifla_info_kind = self.value.get(Link.IFLA_INFO_KIND)
3008 ifla_info_slave_kind = self.value.get(Link.IFLA_INFO_SLAVE_KIND)
3009
3010 kind_dict = {
3011 Link.IFLA_INFO_DATA: self.ifla_info_nested_data_attributes_to_string_dict.get(Link.IFLA_INFO_DATA, {}).get(ifla_info_kind),
3012 Link.IFLA_INFO_SLAVE_DATA: self.ifla_info_nested_data_attributes_to_string_dict.get(Link.IFLA_INFO_SLAVE_DATA, {}).get(ifla_info_slave_kind)
3013 }
3014 if ifla_info_kind or ifla_info_slave_kind:
3015 value_pretty = {}
3016
3017 for (sub_key, sub_value) in self.value.items():
3018 sub_key_pretty = "(%2d) %s" % (sub_key, Link.ifla_info_to_string.get(sub_key, 'UNKNOWN'))
3019 sub_value_pretty = sub_value
3020
3021 if sub_key in (Link.IFLA_INFO_DATA, Link.IFLA_INFO_SLAVE_DATA):
3022 kind_to_string_dict = kind_dict.get(sub_key, {})
3023 sub_value_pretty = {}
3024
3025 for (sub_sub_key, sub_sub_value) in sub_value.items():
3026 sub_sub_key_pretty = "(%2d) %s" % (sub_sub_key, kind_to_string_dict.get(sub_sub_key, 'UNKNOWN'))
3027 sub_value_pretty[sub_sub_key_pretty] = sub_sub_value
3028
3029 value_pretty[sub_key_pretty] = sub_value_pretty
3030
3031 return value_pretty
3032
3033
3034 class AttributeIFLA_PROTINFO(Attribute):
3035 """
3036 IFLA_PROTINFO nested attributes.
3037 """
3038 def __init__(self, atype, string, family, logger):
3039 Attribute.__init__(self, atype, string, logger)
3040 self.family = family
3041
3042 def encode(self):
3043 pack_layout = [self.HEADER_PACK]
3044 payload = [0, self.atype | NLA_F_NESTED]
3045 attr_length_index = 0
3046
3047 if self.family not in (AF_BRIDGE,):
3048 raise Exception('Unsupported IFLA_PROTINFO family %d' % self.family)
3049
3050 # For now this assumes that all data will be packed in the native endian
3051 # order (=). If a field is added that needs to be packed via network
3052 # order (>) then some smarts will need to be added to split the pack_layout
3053 # string at the >, split the payload and make the needed pack() calls.
3054 #
3055 # Until we cross that bridge though we will keep things nice and simple and
3056 # pack everything via a single pack() call.
3057
3058 for (sub_attr_type, sub_attr_value) in self.value.items():
3059 sub_attr_pack_layout = ['=', 'HH']
3060 sub_attr_payload = [0, sub_attr_type]
3061 sub_attr_length_index = 0
3062
3063 if self.family == AF_BRIDGE:
3064 # 1 Byte attributes
3065 if sub_attr_type in (Link.IFLA_BRPORT_STATE,
3066 Link.IFLA_BRPORT_MODE,
3067 Link.IFLA_BRPORT_GUARD,
3068 Link.IFLA_BRPORT_PROTECT,
3069 Link.IFLA_BRPORT_FAST_LEAVE,
3070 Link.IFLA_BRPORT_LEARNING,
3071 Link.IFLA_BRPORT_UNICAST_FLOOD,
3072 Link.IFLA_BRPORT_PROXYARP,
3073 Link.IFLA_BRPORT_LEARNING_SYNC,
3074 Link.IFLA_BRPORT_PROXYARP_WIFI,
3075 Link.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
3076 Link.IFLA_BRPORT_CONFIG_PENDING,
3077 Link.IFLA_BRPORT_FLUSH,
3078 Link.IFLA_BRPORT_MULTICAST_ROUTER,
3079 Link.IFLA_BRPORT_PEER_LINK,
3080 Link.IFLA_BRPORT_DUAL_LINK,
3081 Link.IFLA_BRPORT_NEIGH_SUPPRESS):
3082 sub_attr_pack_layout.append('B')
3083 sub_attr_payload.append(sub_attr_value)
3084
3085 # 2 Byte attributes
3086 elif sub_attr_type in (Link.IFLA_BRPORT_PRIORITY,
3087 Link.IFLA_BRPORT_DESIGNATED_PORT,
3088 Link.IFLA_BRPORT_DESIGNATED_COST,
3089 Link.IFLA_BRPORT_ID,
3090 Link.IFLA_BRPORT_NO):
3091 sub_attr_pack_layout.append('H')
3092 sub_attr_payload.append(sub_attr_value)
3093
3094 # 4 Byte attributes
3095 elif sub_attr_type in (Link.IFLA_BRPORT_COST, Link.IFLA_BRPORT_BACKUP_PORT):
3096 sub_attr_pack_layout.append('L')
3097 sub_attr_payload.append(sub_attr_value)
3098
3099 # 8 Byte attributes
3100 elif sub_attr_type in (Link.IFLA_BRPORT_MESSAGE_AGE_TIMER,
3101 Link.IFLA_BRPORT_FORWARD_DELAY_TIMER,
3102 Link.IFLA_BRPORT_HOLD_TIMER):
3103 sub_attr_pack_layout.append('Q')
3104 sub_attr_payload.append(sub_attr_value)
3105
3106 else:
3107 self.log.log(SYSLOG_EXTRA_DEBUG, 'Add support for encoding IFLA_PROTINFO sub-attribute type %d' % sub_attr_type)
3108
3109 sub_attr_length = calcsize(''.join(sub_attr_pack_layout))
3110 sub_attr_payload[sub_attr_length_index] = sub_attr_length
3111
3112 # add padding
3113 sub_attr_pack_layout[-1] = "%s%s" % (sub_attr_pack_layout[-1], "x" * self.pad_bytes_needed(sub_attr_length))
3114
3115 # The [1:] is to remove the leading = so that when we do the ''.join() later
3116 # we do not end up with an = in the middle of the pack layout string. There
3117 # will be an = at the beginning via self.HEADER_PACK
3118 sub_attr_pack_layout = sub_attr_pack_layout[1:]
3119
3120 # Now extend the ovarall attribute pack_layout/payload to include this sub-attribute
3121 pack_layout.extend(sub_attr_pack_layout)
3122 payload.extend(sub_attr_payload)
3123
3124 pack_layout = ''.join(pack_layout)
3125
3126 # Fill in the length field
3127 length = calcsize(pack_layout)
3128 payload[attr_length_index] = length
3129
3130 raw = pack(pack_layout, *payload)
3131 raw = self.pad(length, raw)
3132 return raw
3133
3134 def decode(self, parent_msg, data):
3135 """
3136 value is a dictionary such as:
3137 {
3138 Link.IFLA_BRPORT_STATE : 3,
3139 Link.IFLA_BRPORT_PRIORITY : 8
3140 Link.IFLA_BRPORT_COST : 2
3141 ...
3142 }
3143 """
3144 self.decode_length_type(data)
3145 self.value = {}
3146
3147 data = self.data[4:]
3148
3149 while data:
3150 (sub_attr_length, sub_attr_type) = unpack('=HH', data[:4])
3151 sub_attr_end = padded_length(sub_attr_length)
3152
3153 if not sub_attr_length:
3154 self.log.error('parsed a zero length sub-attr')
3155 return
3156
3157 if self.family == AF_BRIDGE:
3158
3159 # 1 Byte attributes
3160 if sub_attr_type in (Link.IFLA_BRPORT_STATE,
3161 Link.IFLA_BRPORT_MODE,
3162 Link.IFLA_BRPORT_GUARD,
3163 Link.IFLA_BRPORT_PROTECT,
3164 Link.IFLA_BRPORT_FAST_LEAVE,
3165 Link.IFLA_BRPORT_LEARNING,
3166 Link.IFLA_BRPORT_UNICAST_FLOOD,
3167 Link.IFLA_BRPORT_PROXYARP,
3168 Link.IFLA_BRPORT_LEARNING_SYNC,
3169 Link.IFLA_BRPORT_PROXYARP_WIFI,
3170 Link.IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
3171 Link.IFLA_BRPORT_CONFIG_PENDING,
3172 Link.IFLA_BRPORT_FLUSH,
3173 Link.IFLA_BRPORT_MULTICAST_ROUTER,
3174 Link.IFLA_BRPORT_PEER_LINK,
3175 Link.IFLA_BRPORT_DUAL_LINK,
3176 Link.IFLA_BRPORT_NEIGH_SUPPRESS):
3177 self.value[sub_attr_type] = self.decode_one_byte_attribute(data)
3178
3179 # 2 Byte attributes
3180 elif sub_attr_type in (Link.IFLA_BRPORT_PRIORITY,
3181 Link.IFLA_BRPORT_DESIGNATED_PORT,
3182 Link.IFLA_BRPORT_DESIGNATED_COST,
3183 Link.IFLA_BRPORT_ID,
3184 Link.IFLA_BRPORT_NO):
3185 self.value[sub_attr_type] = unpack('=H', data[4:6])[0]
3186
3187 # 4 Byte attributes
3188 elif sub_attr_type in (Link.IFLA_BRPORT_COST, Link.IFLA_BRPORT_BACKUP_PORT):
3189 self.value[sub_attr_type] = unpack('=L', data[4:8])[0]
3190
3191 # 8 Byte attributes
3192 elif sub_attr_type in (Link.IFLA_BRPORT_MESSAGE_AGE_TIMER,
3193 Link.IFLA_BRPORT_FORWARD_DELAY_TIMER,
3194 Link.IFLA_BRPORT_HOLD_TIMER):
3195 self.value[sub_attr_type] = unpack('=Q', data[4:12])[0]
3196
3197 else:
3198 self.log.log(SYSLOG_EXTRA_DEBUG, 'Add support for decoding IFLA_PROTINFO sub-attribute type %s (%d), length %d, padded to %d' %
3199 (parent_msg.get_ifla_brport_string(sub_attr_type), sub_attr_type, sub_attr_length, sub_attr_end))
3200
3201 data = data[sub_attr_end:]
3202
3203 def dump_lines(self, dump_buffer, line_number, color):
3204 line_number = self.dump_first_line(dump_buffer, line_number, color)
3205 extra = ''
3206
3207 next_sub_attr_line = 0
3208 sub_attr_line = True
3209
3210 for x in range(1, self.attr_end//4):
3211 start = x * 4
3212 end = start + 4
3213
3214 if line_number == next_sub_attr_line:
3215 sub_attr_line = True
3216
3217 if sub_attr_line:
3218 sub_attr_line = False
3219
3220 (sub_attr_length, sub_attr_type) = unpack('=HH', self.data[start:start+4])
3221 sub_attr_end = padded_length(sub_attr_length)
3222
3223 next_sub_attr_line = line_number + (sub_attr_end//4)
3224
3225 if sub_attr_end == sub_attr_length:
3226 padded_to = ', '
3227 else:
3228 padded_to = ' padded to %d, ' % sub_attr_end
3229
3230 extra = 'Nested Attribute - Length %s (%d)%s Type %s (%d) %s' % \
3231 (zfilled_hex(sub_attr_length, 4), sub_attr_length,
3232 padded_to,
3233 zfilled_hex(sub_attr_type, 4), sub_attr_type,
3234 Link.ifla_brport_to_string.get(sub_attr_type))
3235 else:
3236 extra = ''
3237
3238 dump_buffer.append(data_to_color_text(line_number, color, self.data[start:end], extra))
3239 line_number += 1
3240
3241 return line_number
3242
3243 def get_pretty_value(self, obj=None):
3244
3245 if obj and callable(obj):
3246 return obj(self.value)
3247
3248 value_pretty = {}
3249
3250 for (sub_key, sub_value) in self.value.items():
3251 sub_key_pretty = "(%2d) %s" % (sub_key, Link.ifla_brport_to_string.get(sub_key, 'UNKNOWN'))
3252 sub_value_pretty = sub_value
3253 value_pretty[sub_key_pretty] = sub_value_pretty
3254
3255 return value_pretty
3256
3257
3258
3259 class NetlinkPacket(object):
3260 """
3261 Netlink Header
3262
3263 0 1 2 3
3264 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
3265 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3266 | Length |
3267 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3268 | Type | Flags |
3269 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3270 | Sequence Number |
3271 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3272 | Process ID (PID) |
3273 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3274 """
3275
3276 header_PACK = 'IHHII'
3277 header_LEN = calcsize(header_PACK)
3278
3279 # Netlink packet types
3280 # /usr/include/linux/rtnetlink.h
3281 type_to_string = {
3282 NLMSG_NOOP : 'NLMSG_NOOP',
3283 NLMSG_ERROR : 'NLMSG_ERROR',
3284 NLMSG_DONE : 'NLMSG_DONE',
3285 NLMSG_OVERRUN : 'NLMSG_OVERRUN',
3286 RTM_NEWLINK : 'RTM_NEWLINK',
3287 RTM_DELLINK : 'RTM_DELLINK',
3288 RTM_GETLINK : 'RTM_GETLINK',
3289 RTM_SETLINK : 'RTM_SETLINK',
3290 RTM_NEWADDR : 'RTM_NEWADDR',
3291 RTM_DELADDR : 'RTM_DELADDR',
3292 RTM_GETADDR : 'RTM_GETADDR',
3293 RTM_NEWNEIGH : 'RTM_NEWNEIGH',
3294 RTM_DELNEIGH : 'RTM_DELNEIGH',
3295 RTM_GETNEIGH : 'RTM_GETNEIGH',
3296 RTM_NEWROUTE : 'RTM_NEWROUTE',
3297 RTM_DELROUTE : 'RTM_DELROUTE',
3298 RTM_GETROUTE : 'RTM_GETROUTE',
3299 RTM_NEWQDISC : 'RTM_NEWQDISC',
3300 RTM_DELQDISC : 'RTM_DELQDISC',
3301 RTM_GETQDISC : 'RTM_GETQDISC',
3302 RTM_NEWNETCONF: 'RTM_NEWNETCONF',
3303 RTM_GETNETCONF: 'RTM_GETNETCONF',
3304 RTM_DELNETCONF: 'RTM_DELNETCONF',
3305 RTM_NEWMDB : 'RTM_NEWMDB',
3306 RTM_DELMDB : 'RTM_DELMDB',
3307 RTM_GETMDB : 'RTM_GETMDB'
3308 }
3309
3310 af_family_to_string = {
3311 AF_INET : 'inet',
3312 AF_INET6 : 'inet6'
3313 }
3314
3315 def __init__(self, msgtype, debug, owner_logger=None, use_color=True, rx=False, tx=False):
3316 self.msgtype = msgtype
3317 self.attributes = {}
3318 self.dump_buffer = ['']
3319 self.line_number = 1
3320 self.debug = debug
3321 self.message = None
3322 self.use_color = use_color
3323 self.family = None
3324 self.rx = rx
3325 self.tx = tx
3326 self.priv_flags = 0
3327
3328 if owner_logger:
3329 self.log = owner_logger
3330 else:
3331 self.log = log
3332
3333 def __str__(self):
3334 return self.get_type_string()
3335
3336 def get_string(self, to_string, index):
3337 """
3338 Used to do lookups in all of the various FOO_to_string dictionaries
3339 but returns 'UNKNOWN' if the key is bogus
3340 """
3341 if index in to_string:
3342 return to_string[index]
3343 return 'UNKNOWN'
3344
3345 def get_type_string(self, msgtype=None):
3346 if not msgtype:
3347 msgtype = self.msgtype
3348 return self.get_string(self.type_to_string, msgtype)
3349
3350 def get_flags_string(self):
3351 foo = []
3352
3353 for (flag, flag_string) in self.flag_to_string.items():
3354 if self.flags & flag:
3355 foo.append(flag_string)
3356
3357 return ', '.join(foo)
3358
3359 def decode_packet(self, length, flags, seq, pid, data):
3360 self.length = length
3361 self.flags = flags
3362 self.seq = seq
3363 self.pid = pid
3364 self.header_data = data[0:self.header_LEN]
3365 self.msg_data = data[self.header_LEN:length]
3366
3367 self.decode_netlink_header()
3368 self.decode_service_header()
3369
3370 # NLMSG_ERROR is special case, it does not have attributes to decode
3371 if self.msgtype != NLMSG_ERROR:
3372 self.decode_attributes()
3373
3374 def get_netlink_header_flags_string(self, msg_type, flags):
3375 foo = []
3376
3377 if flags & NLM_F_REQUEST:
3378 foo.append('NLM_F_REQUEST')
3379
3380 if flags & NLM_F_MULTI:
3381 foo.append('NLM_F_MULTI')
3382
3383 if flags & NLM_F_ACK:
3384 foo.append('NLM_F_ACK')
3385
3386 if flags & NLM_F_ECHO:
3387 foo.append('NLM_F_ECHO')
3388
3389 # Modifiers to GET query
3390 if msg_type in (RTM_GETLINK, RTM_GETADDR, RTM_GETNEIGH, RTM_GETROUTE, RTM_GETQDISC, RTM_GETNETCONF, RTM_GETMDB):
3391 if flags & NLM_F_DUMP:
3392 foo.append('NLM_F_DUMP')
3393 else:
3394 if flags & NLM_F_MATCH:
3395 foo.append('NLM_F_MATCH')
3396
3397 if flags & NLM_F_ROOT:
3398 foo.append('NLM_F_ROOT')
3399
3400 if flags & NLM_F_ATOMIC:
3401 foo.append('NLM_F_ATOMIC')
3402
3403 # Modifiers to NEW query
3404 elif msg_type in (RTM_NEWLINK, RTM_NEWADDR, RTM_NEWNEIGH, RTM_NEWROUTE, RTM_NEWQDISC, RTM_NEWMDB):
3405 if flags & NLM_F_REPLACE:
3406 foo.append('NLM_F_REPLACE')
3407
3408 if flags & NLM_F_EXCL:
3409 foo.append('NLM_F_EXCL')
3410
3411 if flags & NLM_F_CREATE:
3412 foo.append('NLM_F_CREATE')
3413
3414 if flags & NLM_F_APPEND:
3415 foo.append('NLM_F_APPEND')
3416
3417 return ', '.join(foo)
3418
3419 # When we first RXed the netlink message we had to decode the header to
3420 # determine what type of netlink message we were dealing with. So the
3421 # header has actually already been decoded...what we do here is
3422 # populate the dump_buffer lines with the header content.
3423 def decode_netlink_header(self):
3424
3425 if not self.debug:
3426 return
3427
3428 header_data = self.header_data
3429
3430 # Print the netlink header in red
3431 netlink_header_length = 16
3432 color = red if self.use_color else None
3433 color_start = "\033[%dm" % color if color else ""
3434 color_end = "\033[0m" if color else ""
3435 self.dump_buffer.append(" %sNetlink Header%s" % (color_start, color_end))
3436
3437 for x in range(0, netlink_header_length // 4):
3438 start = x * 4
3439 end = start + 4
3440
3441 if self.line_number == 1:
3442 data = unpack('=L', header_data[start:end])[0]
3443 extra = "Length %s (%d)" % (zfilled_hex(data, 8), data)
3444
3445 elif self.line_number == 2:
3446 (data1, data2) = unpack('HH', header_data[start:end])
3447 extra = "Type %s (%d - %s), Flags %s (%s)" % \
3448 (zfilled_hex(data1, 4), data1, self.get_type_string(data1),
3449 zfilled_hex(data2, 4), self.get_netlink_header_flags_string(data1, data2))
3450
3451 elif self.line_number == 3:
3452 data = unpack('=L', header_data[start:end])[0]
3453 extra = "Sequence Number %s (%d)" % (zfilled_hex(data, 8), data)
3454
3455 elif self.line_number == 4:
3456 data = unpack('=L', header_data[start:end])[0]
3457 extra = "Process ID %s (%d)" % (zfilled_hex(data, 8), data)
3458 else:
3459 extra = "Unexpected line number %d" % self.line_number
3460
3461 self.dump_buffer.append(data_to_color_text(self.line_number, color, header_data[start:end], extra))
3462 self.line_number += 1
3463
3464 def decode_attributes(self):
3465 """
3466 Decode the attributes and populate the dump_buffer
3467 """
3468
3469 if self.debug:
3470 self.dump_buffer.append(" Attributes")
3471 color = green if self.use_color else None
3472
3473 data = self.msg_data[self.LEN:]
3474
3475 while data:
3476 (length, attr_type) = unpack('=HH', data[:4])
3477
3478 # If this is zero we will stay in this loop for forever
3479 if not length:
3480 self.log.error('Length is zero')
3481 return
3482
3483 if len(data) < length:
3484 self.log.error("Buffer underrun %d < %d" % (len(data), length))
3485 return
3486
3487 attr = self.add_attribute(attr_type, None)
3488
3489 # Find the end of 'data' for this attribute and decode our section
3490 # of 'data'. attributes are padded for alignment thus the attr_end.
3491 #
3492 # How the attribute is decoded/unpacked is specific per AttributeXXXX class.
3493 attr_end = padded_length(length)
3494 attr.decode(self, data[0:attr_end])
3495
3496 if self.debug:
3497 self.line_number = attr.dump_lines(self.dump_buffer, self.line_number, color)
3498
3499 # Alternate back and forth between green and blue
3500 if self.use_color:
3501 if color == green:
3502 color = blue
3503 else:
3504 color = green
3505
3506 data = data[attr_end:]
3507
3508 def add_attribute(self, attr_type, value):
3509 nested = True if attr_type & NLA_F_NESTED else False
3510 net_byteorder = True if attr_type & NLA_F_NET_BYTEORDER else False
3511 attr_type = attr_type & NLA_TYPE_MASK
3512
3513 # Given an attr_type (say RTA_DST) find the type of AttributeXXXX class
3514 # that we will use to store this attribute...AttributeIPAddress in the
3515 # case of RTA_DST.
3516 if attr_type in self.attribute_to_class:
3517 (attr_string, attr_class) = self.attribute_to_class[attr_type]
3518
3519 '''
3520 attribute_to_class is a dictionary where the key is the attr_type, it doesn't
3521 take the family into account. For now we'll handle this as a special case for
3522 MPLS but long term we may need to make key a tuple of the attr_type and family.
3523 '''
3524 if self.msgtype not in (RTM_NEWNETCONF, RTM_GETNETCONF, RTM_DELNETCONF) and attr_type == Route.RTA_DST and self.family == AF_MPLS:
3525 attr_string = 'RTA_DST'
3526 attr_class = AttributeMplsLabel
3527
3528 else:
3529 attr_string = "UNKNOWN_ATTRIBUTE_%d" % attr_type
3530 attr_class = AttributeGeneric
3531 self.log.debug("Attribute %d is not defined in %s.attribute_to_class, assuming AttributeGeneric" %
3532 (attr_type, self.__class__.__name__))
3533
3534 attr = attr_class(attr_type, attr_string, self.family, self.log)
3535
3536 attr.set_value(value)
3537 attr.set_nested(nested)
3538 attr.set_net_byteorder(net_byteorder)
3539
3540 # self.attributes is a dictionary keyed by the attribute type where
3541 # the value is an instance of the corresponding AttributeXXXX class.
3542 self.attributes[attr_type] = attr
3543
3544 return attr
3545
3546 def get_attribute_value(self, attr_type, default=None):
3547 if attr_type not in self.attributes:
3548 return default
3549
3550 return self.attributes[attr_type].value
3551
3552 def get_attr_string(self, attr_type):
3553 """
3554 Example: If attr_type is Address.IFA_CACHEINFO return the string 'IFA_CACHEINFO'
3555 """
3556 if attr_type in self.attribute_to_class:
3557 (attr_string, attr_class) = self.attribute_to_class[attr_type]
3558 return attr_string
3559 return str(attr_type)
3560
3561 def build_message(self, seq, pid):
3562 self.seq = seq
3563 self.pid = pid
3564 attrs = bytes()
3565
3566 for attr in self.attributes.values():
3567 attrs += attr.encode()
3568
3569 self.length = self.header_LEN + len(self.body) + len(attrs)
3570 self.header_data = pack(self.header_PACK, self.length, self.msgtype, self.flags, self.seq, self.pid)
3571
3572 if not attrs:
3573 self.msg_data = self.body
3574 else:
3575 self.msg_data = self.body + attrs
3576
3577 self.message = self.header_data + self.msg_data
3578
3579 if self.debug:
3580 self.decode_netlink_header()
3581 self.decode_service_header()
3582 self.decode_attributes()
3583 self.dump("TXed %s, length %d, seq %d, pid %d, flags 0x%x (%s)" %
3584 (self, self.length, self.seq, self.pid, self.flags,
3585 self.get_netlink_header_flags_string(self.msgtype, self.flags)))
3586
3587 def pretty_display_dict(self, dic, level):
3588 for k,v in dic.items():
3589 if isinstance(v, dict):
3590 self.log.debug(' '*level + str(k) + ':')
3591 self.pretty_display_dict(v, level+5)
3592 else:
3593 self.log.debug(' '*level + str(k) + ': ' + str(v))
3594
3595 # Print the netlink message in hex. This is only used for debugging.
3596 def dump(self, desc=None):
3597 attr_string = {}
3598
3599 if desc is None:
3600 desc = "RXed %s, length %d, seq %d, pid %d, flags 0x%x" % (self, self.length, self.seq, self.pid, self.flags)
3601
3602 for (attr_type, attr_obj) in self.attributes.items():
3603 key_string = "(%2d) %s" % (attr_type, self.get_attr_string(attr_type))
3604 attr_string[key_string] = attr_obj.get_pretty_value()
3605
3606 if self.use_color:
3607 self.log.debug("%s\n%s\n\nAttributes Summary\n%s\n" %
3608 (desc, '\n'.join(self.dump_buffer), pformat(attr_string)))
3609 else:
3610 # Assume if we are not allowing color output we also don't want embedded
3611 # newline characters in the output. Output each line individually.
3612 self.log.debug(desc)
3613 for line in self.dump_buffer:
3614 self.log.debug(line)
3615 self.log.debug("")
3616 self.log.debug("Attributes Summary")
3617 self.pretty_display_dict(attr_string, 1)
3618
3619
3620 class Address(NetlinkPacket):
3621 """
3622 Service Header
3623 0 1 2 3
3624 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
3625 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3626 | Family | Length | Flags | Scope |
3627 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3628 | Interface Index |
3629 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3630 """
3631
3632 # Address attributes
3633 # /usr/include/linux/if_addr.h
3634 IFA_UNSPEC = 0x00
3635 IFA_ADDRESS = 0x01
3636 IFA_LOCAL = 0x02
3637 IFA_LABEL = 0x03
3638 IFA_BROADCAST = 0x04
3639 IFA_ANYCAST = 0x05
3640 IFA_CACHEINFO = 0x06
3641 IFA_MULTICAST = 0x07
3642 IFA_FLAGS = 0x08
3643 IFA_RT_PRIORITY = 0x09 # 32, priority / metricfor prefix route
3644
3645 attribute_to_class = {
3646 IFA_UNSPEC : ('IFA_UNSPEC', AttributeGeneric),
3647 IFA_ADDRESS : ('IFA_ADDRESS', AttributeIPAddress),
3648 IFA_LOCAL : ('IFA_LOCAL', AttributeIPAddress),
3649 IFA_LABEL : ('IFA_LABEL', AttributeString),
3650 IFA_BROADCAST : ('IFA_BROADCAST', AttributeIPAddress),
3651 IFA_ANYCAST : ('IFA_ANYCAST', AttributeIPAddress),
3652 IFA_CACHEINFO : ('IFA_CACHEINFO', AttributeCACHEINFO),
3653 IFA_MULTICAST : ('IFA_MULTICAST', AttributeIPAddress),
3654 IFA_FLAGS : ('IFA_FLAGS', AttributeGeneric),
3655 IFA_RT_PRIORITY : ('IFA_RT_PRIORITY', AttributeFourByteValue)
3656 }
3657
3658 # Address flags
3659 # /usr/include/linux/if_addr.h
3660 IFA_F_SECONDARY = 0x01
3661 IFA_F_NODAD = 0x02
3662 IFA_F_OPTIMISTIC = 0x04
3663 IFA_F_DADFAILED = 0x08
3664 IFA_F_HOMEADDRESS = 0x10
3665 IFA_F_DEPRECATED = 0x20
3666 IFA_F_TENTATIVE = 0x40
3667 IFA_F_PERMANENT = 0x80
3668
3669 flag_to_string = {
3670 IFA_F_SECONDARY : 'IFA_F_SECONDARY',
3671 IFA_F_NODAD : 'IFA_F_NODAD',
3672 IFA_F_OPTIMISTIC : 'IFA_F_OPTIMISTIC',
3673 IFA_F_DADFAILED : 'IFA_F_DADFAILED',
3674 IFA_F_HOMEADDRESS : 'IFA_F_HOMEADDRESS',
3675 IFA_F_DEPRECATED : 'IFA_F_DEPRECATED',
3676 IFA_F_TENTATIVE : 'IFA_F_TENTATIVE',
3677 IFA_F_PERMANENT : 'IFA_F_PERMANENT'
3678 }
3679
3680 def __init__(self, msgtype, debug=False, logger=None, use_color=True):
3681 NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
3682 self.PACK = '4Bi'
3683 self.LEN = calcsize(self.PACK)
3684
3685 def decode_service_header(self):
3686
3687 # Nothing to do if the message did not contain a service header
3688 if self.length == self.header_LEN:
3689 return
3690
3691 (self.family, self.prefixlen, self.flags, self.scope,
3692 self.ifindex) = \
3693 unpack(self.PACK, self.msg_data[:self.LEN])
3694
3695 if self.debug:
3696 color = yellow if self.use_color else None
3697 color_start = "\033[%dm" % color if color else ""
3698 color_end = "\033[0m" if color else ""
3699 self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
3700
3701 for x in range(0, self.LEN//4):
3702 if self.line_number == 5:
3703 extra = "Family %s (%s:%d), Length %s (%d), Flags %s, Scope %s (%d)" % \
3704 (zfilled_hex(self.family, 2), get_family_str(self.family), self.family,
3705 zfilled_hex(self.prefixlen, 2), self.prefixlen,
3706 zfilled_hex(self.flags, 2),
3707 zfilled_hex(self.scope, 2), self.scope)
3708 elif self.line_number == 6:
3709 extra = "Interface Index %s (%d)" % (zfilled_hex(self.ifindex, 8), self.ifindex)
3710 else:
3711 extra = "Unexpected line number %d" % self.line_number
3712
3713 start = x * 4
3714 end = start + 4
3715 self.dump_buffer.append(data_to_color_text(self.line_number, color, self.msg_data[start:end], extra))
3716 self.line_number += 1
3717
3718
3719 class Error(NetlinkPacket):
3720
3721 # Error codes
3722 # /include/netlink/errno.h
3723 NLE_SUCCESS = 0x00
3724 NLE_FAILURE = 0x01
3725 NLE_INTR = 0x02
3726 NLE_BAD_SOCK = 0x03
3727 NLE_AGAIN = 0x04
3728 NLE_NOMEM = 0x05
3729 NLE_EXIST = 0x06
3730 NLE_INVAL = 0x07
3731 NLE_RANGE = 0x08
3732 NLE_MSGSIZE = 0x09
3733 NLE_OPNOTSUPP = 0x0A
3734 NLE_AF_NOSUPPORT = 0x0B
3735 NLE_OBJ_NOTFOUND = 0x0C
3736 NLE_NOATTR = 0x0D
3737 NLE_MISSING_ATTR = 0x0E
3738 NLE_AF_MISMATCH = 0x0F
3739 NLE_SEQ_MISMATCH = 0x10
3740 NLE_MSG_OVERFLOW = 0x11
3741 NLE_MSG_TRUNC = 0x12
3742 NLE_NOADDR = 0x13
3743 NLE_SRCRT_NOSUPPORT = 0x14
3744 NLE_MSG_TOOSHORT = 0x15
3745 NLE_MSGTYPE_NOSUPPORT = 0x16
3746 NLE_OBJ_MISMATCH = 0x17
3747 NLE_NOCACHE = 0x18
3748 NLE_BUSY = 0x19
3749 NLE_PROTO_MISMATCH = 0x1A
3750 NLE_NOACCESS = 0x1B
3751 NLE_PERM = 0x1C
3752 NLE_PKTLOC_FILE = 0x1D
3753 NLE_PARSE_ERR = 0x1E
3754 NLE_NODEV = 0x1F
3755 NLE_IMMUTABLE = 0x20
3756 NLE_DUMP_INTR = 0x21
3757 NLE_ATTRSIZE = 0x22
3758
3759 error_to_string = {
3760 NLE_SUCCESS : 'NLE_SUCCESS',
3761 NLE_FAILURE : 'NLE_FAILURE',
3762 NLE_INTR : 'NLE_INTR',
3763 NLE_BAD_SOCK : 'NLE_BAD_SOCK',
3764 NLE_AGAIN : 'NLE_AGAIN',
3765 NLE_NOMEM : 'NLE_NOMEM',
3766 NLE_EXIST : 'NLE_EXIST',
3767 NLE_INVAL : 'NLE_INVAL',
3768 NLE_RANGE : 'NLE_RANGE',
3769 NLE_MSGSIZE : 'NLE_MSGSIZE',
3770 NLE_OPNOTSUPP : 'NLE_OPNOTSUPP',
3771 NLE_AF_NOSUPPORT : 'NLE_AF_NOSUPPORT',
3772 NLE_OBJ_NOTFOUND : 'NLE_OBJ_NOTFOUND',
3773 NLE_NOATTR : 'NLE_NOATTR',
3774 NLE_MISSING_ATTR : 'NLE_MISSING_ATTR',
3775 NLE_AF_MISMATCH : 'NLE_AF_MISMATCH',
3776 NLE_SEQ_MISMATCH : 'NLE_SEQ_MISMATCH',
3777 NLE_MSG_OVERFLOW : 'NLE_MSG_OVERFLOW',
3778 NLE_MSG_TRUNC : 'NLE_MSG_TRUNC',
3779 NLE_NOADDR : 'NLE_NOADDR',
3780 NLE_SRCRT_NOSUPPORT : 'NLE_SRCRT_NOSUPPORT',
3781 NLE_MSG_TOOSHORT : 'NLE_MSG_TOOSHORT',
3782 NLE_MSGTYPE_NOSUPPORT : 'NLE_MSGTYPE_NOSUPPORT',
3783 NLE_OBJ_MISMATCH : 'NLE_OBJ_MISMATCH',
3784 NLE_NOCACHE : 'NLE_NOCACHE',
3785 NLE_BUSY : 'NLE_BUSY',
3786 NLE_PROTO_MISMATCH : 'NLE_PROTO_MISMATCH',
3787 NLE_NOACCESS : 'NLE_NOACCESS',
3788 NLE_PERM : 'NLE_PERM',
3789 NLE_PKTLOC_FILE : 'NLE_PKTLOC_FILE',
3790 NLE_PARSE_ERR : 'NLE_PARSE_ERR',
3791 NLE_NODEV : 'NLE_NODEV',
3792 NLE_IMMUTABLE : 'NLE_IMMUTABLE',
3793 NLE_DUMP_INTR : 'NLE_DUMP_INTR',
3794 NLE_ATTRSIZE : 'NLE_ATTRSIZE'
3795 }
3796
3797 error_to_human_readable_string = {
3798 NLE_SUCCESS: "Success",
3799 NLE_FAILURE: "Unspecific failure",
3800 NLE_INTR: "Interrupted system call",
3801 NLE_BAD_SOCK: "Bad socket",
3802 NLE_AGAIN: "Try again",
3803 NLE_NOMEM: "Out of memory",
3804 NLE_EXIST: "Object exists",
3805 NLE_INVAL: "Invalid input data or parameter",
3806 NLE_RANGE: "Input data out of range",
3807 NLE_MSGSIZE: "Message size not sufficient",
3808 NLE_OPNOTSUPP: "Operation not supported",
3809 NLE_AF_NOSUPPORT: "Address family not supported",
3810 NLE_OBJ_NOTFOUND: "Object not found",
3811 NLE_NOATTR: "Attribute not available",
3812 NLE_MISSING_ATTR: "Missing attribute",
3813 NLE_AF_MISMATCH: "Address family mismatch",
3814 NLE_SEQ_MISMATCH: "Message sequence number mismatch",
3815 NLE_MSG_OVERFLOW: "Kernel reported message overflow",
3816 NLE_MSG_TRUNC: "Kernel reported truncated message",
3817 NLE_NOADDR: "Invalid address for specified address family",
3818 NLE_SRCRT_NOSUPPORT: "Source based routing not supported",
3819 NLE_MSG_TOOSHORT: "Netlink message is too short",
3820 NLE_MSGTYPE_NOSUPPORT: "Netlink message type is not supported",
3821 NLE_OBJ_MISMATCH: "Object type does not match cache",
3822 NLE_NOCACHE: "Unknown or invalid cache type",
3823 NLE_BUSY: "Object busy",
3824 NLE_PROTO_MISMATCH: "Protocol mismatch",
3825 NLE_NOACCESS: "No Access",
3826 NLE_PERM: "Operation not permitted",
3827 NLE_PKTLOC_FILE: "Unable to open packet location file",
3828 NLE_PARSE_ERR: "Unable to parse object",
3829 NLE_NODEV: "No such device",
3830 NLE_IMMUTABLE: "Immutable attribute",
3831 NLE_DUMP_INTR: "Dump inconsistency detected, interrupted",
3832 NLE_ATTRSIZE: "Attribute max length exceeded",
3833 }
3834
3835 def __init__(self, msgtype, debug=False, logger=None, use_color=True):
3836 NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
3837 self.PACK = '=iLHHLL'
3838 self.LEN = calcsize(self.PACK)
3839
3840 def decode_service_header(self):
3841
3842 # Nothing to do if the message did not contain a service header
3843 if self.length == self.header_LEN:
3844 return
3845
3846 (self.negative_errno, self.bad_msg_len, self.bad_msg_type,
3847 self.bad_msg_flag, self.bad_msg_seq, self.bad_msg_pid) =\
3848 unpack(self.PACK, self.msg_data[:self.LEN])
3849
3850 if self.debug:
3851 color = yellow if self.use_color else None
3852 color_start = "\033[%dm" % color if color else ""
3853 color_end = "\033[0m" if color else ""
3854 self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
3855
3856 for x in range(0, self.LEN//4):
3857
3858 if self.line_number == 5:
3859 error_number = abs(self.negative_errno)
3860 extra = "Error Number %s is %s (%s)" % (self.negative_errno, self.error_to_string.get(error_number), self.error_to_human_readable_string.get(error_number))
3861 # zfilled_hex(self.negative_errno, 2)
3862
3863 elif self.line_number == 6:
3864 extra = "Length %s (%d)" % (zfilled_hex(self.bad_msg_len, 8), self.bad_msg_len)
3865
3866 elif self.line_number == 7:
3867 extra = "Type %s (%d - %s), Flags %s (%s)" % \
3868 (zfilled_hex(self.bad_msg_type, 4), self.bad_msg_type, self.get_type_string(self.bad_msg_type),
3869 zfilled_hex(self.bad_msg_flag, 4), self.get_netlink_header_flags_string(self.bad_msg_type, self.bad_msg_flag))
3870
3871 elif self.line_number == 8:
3872 extra = "Sequence Number %s (%d)" % (zfilled_hex(self.bad_msg_seq, 8), self.bad_msg_seq)
3873
3874 elif self.line_number == 9:
3875 extra = "Process ID %s (%d)" % (zfilled_hex(self.bad_msg_pid, 8), self.bad_msg_pid)
3876
3877 else:
3878 extra = "Unexpected line number %d" % self.line_number
3879
3880 start = x * 4
3881 end = start + 4
3882 self.dump_buffer.append(data_to_color_text(self.line_number, color, self.msg_data[start:end], extra))
3883 self.line_number += 1
3884
3885
3886 class Link(NetlinkPacket, NetlinkPacket_IFLA_LINKINFO_Attributes):
3887 """
3888 Service Header
3889
3890 0 1 2 3
3891 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
3892 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3893 | Family | Reserved | Device Type |
3894 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3895 | Interface Index |
3896 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3897 | Device Flags |
3898 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3899 | Change Mask |
3900 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3901 """
3902
3903 # Link attributes
3904 # /usr/include/linux/if_link.h
3905 IFLA_UNSPEC = 0
3906 IFLA_ADDRESS = 1
3907 IFLA_BROADCAST = 2
3908 IFLA_IFNAME = 3
3909 IFLA_MTU = 4
3910 IFLA_LINK = 5
3911 IFLA_QDISC = 6
3912 IFLA_STATS = 7
3913 IFLA_COST = 8
3914 IFLA_PRIORITY = 9
3915 IFLA_MASTER = 10
3916 IFLA_WIRELESS = 11
3917 IFLA_PROTINFO = 12
3918 IFLA_TXQLEN = 13
3919 IFLA_MAP = 14
3920 IFLA_WEIGHT = 15
3921 IFLA_OPERSTATE = 16
3922 IFLA_LINKMODE = 17
3923 IFLA_LINKINFO = 18
3924 IFLA_NET_NS_PID = 19
3925 IFLA_IFALIAS = 20
3926 IFLA_NUM_VF = 21
3927 IFLA_VFINFO_LIST = 22
3928 IFLA_STATS64 = 23
3929 IFLA_VF_PORTS = 24
3930 IFLA_PORT_SELF = 25
3931 IFLA_AF_SPEC = 26
3932 IFLA_GROUP = 27
3933 IFLA_NET_NS_FD = 28
3934 IFLA_EXT_MASK = 29
3935 IFLA_PROMISCUITY = 30
3936 IFLA_NUM_TX_QUEUES = 31
3937 IFLA_NUM_RX_QUEUES = 32
3938 IFLA_CARRIER = 33
3939 IFLA_PHYS_PORT_ID = 34
3940 IFLA_CARRIER_CHANGES = 35
3941 IFLA_PHYS_SWITCH_ID = 36
3942 IFLA_LINK_NETNSID = 37
3943 IFLA_PHYS_PORT_NAME = 38
3944 IFLA_PROTO_DOWN = 39
3945 IFLA_GSO_MAX_SEGS = 40
3946 IFLA_GSO_MAX_SIZE = 41
3947 IFLA_PAD = 42
3948 IFLA_XDP = 43
3949 IFLA_EVENT = 44
3950 IFLA_NEW_NETNSID = 45
3951 IFLA_IF_NETNSID = 46
3952 IFLA_CARRIER_UP_COUNT = 47
3953 IFLA_CARRIER_DOWN_COUNT = 48
3954 IFLA_NEW_IFINDEX = 49
3955 IFLA_MIN_MTU = 50
3956 IFLA_MAX_MTU = 51
3957
3958 attribute_to_class = {
3959 IFLA_UNSPEC : ('IFLA_UNSPEC', AttributeGeneric),
3960 IFLA_ADDRESS : ('IFLA_ADDRESS', AttributeMACAddress),
3961 IFLA_BROADCAST : ('IFLA_BROADCAST', AttributeMACAddress),
3962 IFLA_IFNAME : ('IFLA_IFNAME', AttributeStringInterfaceName),
3963 IFLA_MTU : ('IFLA_MTU', AttributeFourByteValue),
3964 IFLA_LINK : ('IFLA_LINK', AttributeFourByteValue),
3965 IFLA_QDISC : ('IFLA_QDISC', AttributeString),
3966 IFLA_STATS : ('IFLA_STATS', AttributeGeneric),
3967 IFLA_COST : ('IFLA_COST', AttributeGeneric),
3968 IFLA_PRIORITY : ('IFLA_PRIORITY', AttributeGeneric),
3969 IFLA_MASTER : ('IFLA_MASTER', AttributeFourByteValue),
3970 IFLA_WIRELESS : ('IFLA_WIRELESS', AttributeGeneric),
3971 IFLA_PROTINFO : ('IFLA_PROTINFO', AttributeIFLA_PROTINFO),
3972 IFLA_TXQLEN : ('IFLA_TXQLEN', AttributeFourByteValue),
3973 IFLA_MAP : ('IFLA_MAP', AttributeGeneric),
3974 IFLA_WEIGHT : ('IFLA_WEIGHT', AttributeGeneric),
3975 IFLA_OPERSTATE : ('IFLA_OPERSTATE', AttributeOneByteValue),
3976 IFLA_LINKMODE : ('IFLA_LINKMODE', AttributeOneByteValue),
3977 IFLA_LINKINFO : ('IFLA_LINKINFO', AttributeIFLA_LINKINFO),
3978 IFLA_NET_NS_PID : ('IFLA_NET_NS_PID', AttributeGeneric),
3979 IFLA_IFALIAS : ('IFLA_IFALIAS', AttributeString),
3980 IFLA_NUM_VF : ('IFLA_NUM_VF', AttributeGeneric),
3981 IFLA_VFINFO_LIST : ('IFLA_VFINFO_LIST', AttributeGeneric),
3982 IFLA_STATS64 : ('IFLA_STATS64', AttributeGeneric),
3983 IFLA_VF_PORTS : ('IFLA_VF_PORTS', AttributeGeneric),
3984 IFLA_PORT_SELF : ('IFLA_PORT_SELF', AttributeGeneric),
3985 IFLA_AF_SPEC : ('IFLA_AF_SPEC', AttributeIFLA_AF_SPEC),
3986 IFLA_GROUP : ('IFLA_GROUP', AttributeFourByteValue),
3987 IFLA_NET_NS_FD : ('IFLA_NET_NS_FD', AttributeGeneric),
3988 IFLA_EXT_MASK : ('IFLA_EXT_MASK', AttributeFourByteValue),
3989 IFLA_PROMISCUITY : ('IFLA_PROMISCUITY', AttributeGeneric),
3990 IFLA_NUM_TX_QUEUES : ('IFLA_NUM_TX_QUEUES', AttributeGeneric),
3991 IFLA_NUM_RX_QUEUES : ('IFLA_NUM_RX_QUEUES', AttributeGeneric),
3992 IFLA_CARRIER : ('IFLA_CARRIER', AttributeGeneric),
3993 IFLA_PHYS_PORT_ID : ('IFLA_PHYS_PORT_ID', AttributeGeneric),
3994 IFLA_CARRIER_CHANGES : ('IFLA_CARRIER_CHANGES', AttributeGeneric),
3995 IFLA_PHYS_SWITCH_ID : ('IFLA_PHYS_SWITCH_ID', AttributeGeneric),
3996 IFLA_LINK_NETNSID : ('IFLA_LINK_NETNSID', AttributeGeneric),
3997 IFLA_PHYS_PORT_NAME : ('IFLA_PHYS_PORT_NAME', AttributeGeneric),
3998 IFLA_PROTO_DOWN : ('IFLA_PROTO_DOWN', AttributeOneByteValue),
3999 IFLA_GSO_MAX_SEGS : ('IFLA_GSO_MAX_SEGS', AttributeFourByteValue),
4000 IFLA_GSO_MAX_SIZE : ('IFLA_GSO_MAX_SIZE', AttributeFourByteValue),
4001 IFLA_PAD : ('IFLA_PAD', AttributeGeneric),
4002 IFLA_XDP : ('IFLA_XDP', AttributeGeneric),
4003 IFLA_EVENT : ('IFLA_EVENT', AttributeFourByteValue),
4004 IFLA_NEW_NETNSID : ('IFLA_NEW_NETNSID', AttributeFourByteValue),
4005 IFLA_IF_NETNSID : ('IFLA_IF_NETNSID', AttributeFourByteValue),
4006 IFLA_CARRIER_UP_COUNT : ('IFLA_CARRIER_UP_COUNT', AttributeFourByteValue),
4007 IFLA_CARRIER_DOWN_COUNT : ('IFLA_CARRIER_DOWN_COUNT', AttributeFourByteValue),
4008 IFLA_NEW_IFINDEX : ('IFLA_NEW_IFINDEX', AttributeFourByteValue),
4009 IFLA_MIN_MTU : ('IFLA_MIN_MTU', AttributeFourByteValue),
4010 IFLA_MAX_MTU : ('IFLA_MAX_MTU', AttributeFourByteValue),
4011 }
4012
4013 # Link flags
4014 # /usr/include/linux/if.h
4015 IFF_UP = 0x0001 # Interface is administratively up.
4016 IFF_BROADCAST = 0x0002 # Valid broadcast address set.
4017 IFF_DEBUG = 0x0004 # Internal debugging flag.
4018 IFF_LOOPBACK = 0x0008 # Interface is a loopback interface.
4019 IFF_POINTOPOINT = 0x0010 # Interface is a point-to-point link.
4020 IFF_NOTRAILERS = 0x0020 # Avoid use of trailers.
4021 IFF_RUNNING = 0x0040 # Interface is operationally up.
4022 IFF_NOARP = 0x0080 # No ARP protocol needed for this interface.
4023 IFF_PROMISC = 0x0100 # Interface is in promiscuous mode.
4024 IFF_ALLMULTI = 0x0200 # Receive all multicast packets.
4025 IFF_MASTER = 0x0400 # Master of a load balancing bundle.
4026 IFF_SLAVE = 0x0800 # Slave of a load balancing bundle.
4027 IFF_MULTICAST = 0x1000 # Supports multicast.
4028 IFF_PORTSEL = 0x2000 # Is able to select media type via ifmap.
4029 IFF_AUTOMEDIA = 0x4000 # Auto media selection active.
4030 IFF_DYNAMIC = 0x8000 # Interface was dynamically created.
4031 IFF_LOWER_UP = 0x10000 # driver signals L1 up
4032 IFF_DORMANT = 0x20000 # driver signals dormant
4033 IFF_ECHO = 0x40000 # echo sent packet
4034 IFF_PROTO_DOWN = 0x1000000 # protocol is down on the interface
4035
4036 flag_to_string = {
4037 IFF_UP : 'IFF_UP',
4038 IFF_BROADCAST : 'IFF_BROADCAST',
4039 IFF_DEBUG : 'IFF_DEBUG',
4040 IFF_LOOPBACK : 'IFF_LOOPBACK',
4041 IFF_POINTOPOINT : 'IFF_POINTOPOINT',
4042 IFF_NOTRAILERS : 'IFF_NOTRAILERS',
4043 IFF_RUNNING : 'IFF_RUNNING',
4044 IFF_NOARP : 'IFF_NOARP',
4045 IFF_PROMISC : 'IFF_PROMISC',
4046 IFF_ALLMULTI : 'IFF_ALLMULTI',
4047 IFF_MASTER : 'IFF_MASTER',
4048 IFF_SLAVE : 'IFF_SLAVE',
4049 IFF_MULTICAST : 'IFF_MULTICAST',
4050 IFF_PORTSEL : 'IFF_PORTSEL',
4051 IFF_AUTOMEDIA : 'IFF_AUTOMEDIA',
4052 IFF_DYNAMIC : 'IFF_DYNAMIC',
4053 IFF_LOWER_UP : 'IFF_LOWER_UP',
4054 IFF_DORMANT : 'IFF_DORMANT',
4055 IFF_ECHO : 'IFF_ECHO',
4056 IFF_PROTO_DOWN : 'IFF_PROTO_DOWN'
4057 }
4058
4059 # RFC 2863 operational status
4060 IF_OPER_UNKNOWN = 0
4061 IF_OPER_NOTPRESENT = 1
4062 IF_OPER_DOWN = 2
4063 IF_OPER_LOWERLAYERDOWN = 3
4064 IF_OPER_TESTING = 4
4065 IF_OPER_DORMANT = 5
4066 IF_OPER_UP = 6
4067
4068 oper_to_string = {
4069 IF_OPER_UNKNOWN : 'IF_OPER_UNKNOWN',
4070 IF_OPER_NOTPRESENT : 'IF_OPER_NOTPRESENT',
4071 IF_OPER_DOWN : 'IF_OPER_DOWN',
4072 IF_OPER_LOWERLAYERDOWN : 'IF_OPER_LOWERLAYERDOWN',
4073 IF_OPER_TESTING : 'IF_OPER_TESTING',
4074 IF_OPER_DORMANT : 'IF_OPER_DORMANT',
4075 IF_OPER_UP : 'IF_OPER_UP'
4076 }
4077
4078 # Link types
4079 # /usr/include/linux/if_arp.h
4080 # ARP protocol HARDWARE identifiers
4081 ARPHRD_NETROM = 0 # from KA9Q: NET/ROM pseudo
4082 ARPHRD_ETHER = 1 # Ethernet 10Mbps
4083 ARPHRD_EETHER = 2 # Experimental Ethernet
4084 ARPHRD_AX25 = 3 # AX.25 Level 2
4085 ARPHRD_PRONET = 4 # PROnet token ring
4086 ARPHRD_CHAOS = 5 # Chaosnet
4087 ARPHRD_IEEE802 = 6 # IEEE 802.2 Ethernet/TR/TB
4088 ARPHRD_ARCNET = 7 # ARCnet
4089 ARPHRD_APPLETLK = 8 # APPLEtalk
4090 ARPHRD_DLCI = 15 # Frame Relay DLCI
4091 ARPHRD_ATM = 19 # ATM
4092 ARPHRD_METRICOM = 23 # Metricom STRIP (new IANA id)
4093 ARPHRD_IEEE1394 = 24 # IEEE 1394 IPv4 - RFC 2734
4094 ARPHRD_EUI64 = 27 # EUI-64
4095 ARPHRD_INFINIBAND = 32 # InfiniBand
4096 # Dummy types for non ARP hardware
4097 ARPHRD_SLIP = 256
4098 ARPHRD_CSLIP = 257
4099 ARPHRD_SLIP6 = 258
4100 ARPHRD_CSLIP6 = 259
4101 ARPHRD_RSRVD = 260 # Notional KISS type
4102 ARPHRD_ADAPT = 264
4103 ARPHRD_ROSE = 270
4104 ARPHRD_X25 = 271 # CCITT X.25
4105 ARPHRD_HWX25 = 272 # Boards with X.25 in firmware
4106 ARPHRD_CAN = 280 # Controller Area Network
4107 ARPHRD_PPP = 512
4108 ARPHRD_CISCO = 513 # Cisco HDLC
4109 ARPHRD_HDLC = ARPHRD_CISCO
4110 ARPHRD_LAPB = 516 # LAPB
4111 ARPHRD_DDCMP = 517 # Digital's DDCMP protocol
4112 ARPHRD_RAWHDLC = 518 # Raw HDLC
4113 ARPHRD_TUNNEL = 768 # IPIP tunnel
4114 ARPHRD_TUNNEL6 = 769 # IP6IP6 tunnel
4115 ARPHRD_FRAD = 770 # Frame Relay Access Device
4116 ARPHRD_SKIP = 771 # SKIP vif
4117 ARPHRD_LOOPBACK = 772 # Loopback device
4118 ARPHRD_LOCALTLK = 773 # Localtalk device
4119 ARPHRD_FDDI = 774 # Fiber Distributed Data Interface
4120 ARPHRD_BIF = 775 # AP1000 BIF
4121 ARPHRD_SIT = 776 # sit0 device - IPv6-in-IPv4
4122 ARPHRD_IPDDP = 777 # IP over DDP tunneller
4123 ARPHRD_IPGRE = 778 # GRE over IP
4124 ARPHRD_PIMREG = 779 # PIMSM register interface
4125 ARPHRD_HIPPI = 780 # High Performance Parallel Interface
4126 ARPHRD_ASH = 781 # Nexus 64Mbps Ash
4127 ARPHRD_ECONET = 782 # Acorn Econet
4128 ARPHRD_IRDA = 783 # Linux-IrDA
4129 ARPHRD_FCPP = 784 # Point to point fibrechannel
4130 ARPHRD_FCAL = 785 # Fibrechannel arbitrated loop
4131 ARPHRD_FCPL = 786 # Fibrechannel public loop
4132 ARPHRD_FCFABRIC = 787 # Fibrechannel fabric
4133 # 787->799 reserved for fibrechannel media types
4134 ARPHRD_IEEE802_TR = 800 # Magic type ident for TR
4135 ARPHRD_IEEE80211 = 801 # IEEE 802.11
4136 ARPHRD_IEEE80211_PRISM = 802 # IEEE 802.11 + Prism2 header
4137 ARPHRD_IEEE80211_RADIOTAP = 803 # IEEE 802.11 + radiotap header
4138 ARPHRD_IEEE802154 = 804
4139 ARPHRD_PHONET = 820 # PhoNet media type
4140 ARPHRD_PHONET_PIPE = 821 # PhoNet pipe header
4141 ARPHRD_CAIF = 822 # CAIF media type
4142 ARPHRD_VOID = 0xFFFF # Void type, nothing is known
4143 ARPHRD_NONE = 0xFFFE # zero header length
4144
4145 link_type_to_string = {
4146 ARPHRD_NETROM : 'ARPHRD_NETROM',
4147 ARPHRD_ETHER : 'ARPHRD_ETHER',
4148 ARPHRD_EETHER : 'ARPHRD_EETHER',
4149 ARPHRD_AX25 : 'ARPHRD_AX25',
4150 ARPHRD_PRONET : 'ARPHRD_PRONET',
4151 ARPHRD_CHAOS : 'ARPHRD_CHAOS',
4152 ARPHRD_IEEE802 : 'ARPHRD_IEEE802',
4153 ARPHRD_ARCNET : 'ARPHRD_ARCNET',
4154 ARPHRD_APPLETLK : 'ARPHRD_APPLETLK',
4155 ARPHRD_DLCI : 'ARPHRD_DLCI',
4156 ARPHRD_ATM : 'ARPHRD_ATM',
4157 ARPHRD_METRICOM : 'ARPHRD_METRICOM',
4158 ARPHRD_IEEE1394 : 'ARPHRD_IEEE1394',
4159 ARPHRD_EUI64 : 'ARPHRD_EUI64',
4160 ARPHRD_INFINIBAND : 'ARPHRD_INFINIBAND',
4161 ARPHRD_SLIP : 'ARPHRD_SLIP',
4162 ARPHRD_CSLIP : 'ARPHRD_CSLIP',
4163 ARPHRD_SLIP6 : 'ARPHRD_SLIP6',
4164 ARPHRD_CSLIP6 : 'ARPHRD_CSLIP6',
4165 ARPHRD_RSRVD : 'ARPHRD_RSRVD',
4166 ARPHRD_ADAPT : 'ARPHRD_ADAPT',
4167 ARPHRD_ROSE : 'ARPHRD_ROSE',
4168 ARPHRD_X25 : 'ARPHRD_X25',
4169 ARPHRD_HWX25 : 'ARPHRD_HWX25',
4170 ARPHRD_CAN : 'ARPHRD_CAN',
4171 ARPHRD_PPP : 'ARPHRD_PPP',
4172 ARPHRD_CISCO : 'ARPHRD_CISCO',
4173 ARPHRD_HDLC : 'ARPHRD_HDLC',
4174 ARPHRD_LAPB : 'ARPHRD_LAPB',
4175 ARPHRD_DDCMP : 'ARPHRD_DDCMP',
4176 ARPHRD_RAWHDLC : 'ARPHRD_RAWHDLC',
4177 ARPHRD_TUNNEL : 'ARPHRD_TUNNEL',
4178 ARPHRD_TUNNEL6 : 'ARPHRD_TUNNEL6',
4179 ARPHRD_FRAD : 'ARPHRD_FRAD',
4180 ARPHRD_SKIP : 'ARPHRD_SKIP',
4181 ARPHRD_LOOPBACK : 'ARPHRD_LOOPBACK',
4182 ARPHRD_LOCALTLK : 'ARPHRD_LOCALTLK',
4183 ARPHRD_FDDI : 'ARPHRD_FDDI',
4184 ARPHRD_BIF : 'ARPHRD_BIF',
4185 ARPHRD_SIT : 'ARPHRD_SIT',
4186 ARPHRD_IPDDP : 'ARPHRD_IPDDP',
4187 ARPHRD_IPGRE : 'ARPHRD_IPGRE',
4188 ARPHRD_PIMREG : 'ARPHRD_PIMREG',
4189 ARPHRD_HIPPI : 'ARPHRD_HIPPI',
4190 ARPHRD_ASH : 'ARPHRD_ASH',
4191 ARPHRD_ECONET : 'ARPHRD_ECONET',
4192 ARPHRD_IRDA : 'ARPHRD_IRDA',
4193 ARPHRD_FCPP : 'ARPHRD_FCPP',
4194 ARPHRD_FCAL : 'ARPHRD_FCAL',
4195 ARPHRD_FCPL : 'ARPHRD_FCPL',
4196 ARPHRD_FCFABRIC : 'ARPHRD_FCFABRIC',
4197 ARPHRD_IEEE802_TR : 'ARPHRD_IEEE802_TR',
4198 ARPHRD_IEEE80211 : 'ARPHRD_IEEE80211',
4199 ARPHRD_IEEE80211_PRISM : 'ARPHRD_IEEE80211_PRISM',
4200 ARPHRD_IEEE80211_RADIOTAP : 'ARPHRD_IEEE80211_RADIOTAP',
4201 ARPHRD_IEEE802154 : 'ARPHRD_IEEE802154',
4202 ARPHRD_PHONET : 'ARPHRD_PHONET',
4203 ARPHRD_PHONET_PIPE : 'ARPHRD_PHONET_PIPE',
4204 ARPHRD_CAIF : 'ARPHRD_CAIF',
4205 ARPHRD_VOID : 'ARPHRD_VOID',
4206 ARPHRD_NONE : 'ARPHRD_NONE'
4207 }
4208
4209 # Subtype attributes for IFLA_AF_SPEC
4210 IFLA_INET6_UNSPEC = 0
4211 IFLA_INET6_FLAGS = 1 # link flags
4212 IFLA_INET6_CONF = 2 # sysctl parameters
4213 IFLA_INET6_STATS = 3 # statistics
4214 IFLA_INET6_MCAST = 4 # MC things. What of them?
4215 IFLA_INET6_CACHEINFO = 5 # time values and max reasm size
4216 IFLA_INET6_ICMP6STATS = 6 # statistics (icmpv6)
4217 IFLA_INET6_TOKEN = 7 # device token
4218 IFLA_INET6_ADDR_GEN_MODE = 8 # implicit address generator mode
4219 __IFLA_INET6_MAX = 9
4220
4221 ifla_inet6_af_spec_to_string = {
4222 IFLA_INET6_UNSPEC : 'IFLA_INET6_UNSPEC',
4223 IFLA_INET6_FLAGS : 'IFLA_INET6_FLAGS',
4224 IFLA_INET6_CONF : 'IFLA_INET6_CONF',
4225 IFLA_INET6_STATS : 'IFLA_INET6_STATS',
4226 IFLA_INET6_MCAST : 'IFLA_INET6_MCAST',
4227 IFLA_INET6_CACHEINFO : 'IFLA_INET6_CACHEINFO',
4228 IFLA_INET6_ICMP6STATS : 'IFLA_INET6_ICMP6STATS',
4229 IFLA_INET6_TOKEN : 'IFLA_INET6_TOKEN',
4230 IFLA_INET6_ADDR_GEN_MODE : 'IFLA_INET6_ADDR_GEN_MODE',
4231 }
4232
4233 # IFLA_INET6_ADDR_GEN_MODE values
4234 IN6_ADDR_GEN_MODE_EUI64 = 0
4235 IN6_ADDR_GEN_MODE_NONE = 1
4236 IN6_ADDR_GEN_MODE_STABLE_PRIVACY = 2
4237 IN6_ADDR_GEN_MODE_RANDOM = 3
4238
4239 ifla_inet6_addr_gen_mode_dict = {
4240 IN6_ADDR_GEN_MODE_EUI64: "eui64",
4241 IN6_ADDR_GEN_MODE_NONE: "none",
4242 IN6_ADDR_GEN_MODE_STABLE_PRIVACY: "stable_secret",
4243 IN6_ADDR_GEN_MODE_RANDOM: "random"
4244 }
4245
4246 # Subtype attrbutes AF_INET
4247 IFLA_INET_UNSPEC = 0
4248 IFLA_INET_CONF = 1
4249 __IFLA_INET_MAX = 2
4250
4251 ifla_inet_af_spec_to_string = {
4252 IFLA_INET_UNSPEC : 'IFLA_INET_UNSPEC',
4253 IFLA_INET_CONF : 'IFLA_INET_CONF',
4254 }
4255
4256 # BRIDGE IFLA_AF_SPEC attributes
4257 IFLA_BRIDGE_FLAGS = 0
4258 IFLA_BRIDGE_MODE = 1
4259 IFLA_BRIDGE_VLAN_INFO = 2
4260
4261 ifla_bridge_af_spec_to_string = {
4262 IFLA_BRIDGE_FLAGS : 'IFLA_BRIDGE_FLAGS',
4263 IFLA_BRIDGE_MODE : 'IFLA_BRIDGE_MODE',
4264 IFLA_BRIDGE_VLAN_INFO : 'IFLA_BRIDGE_VLAN_INFO'
4265 }
4266
4267 # BRIDGE_VLAN_INFO flags
4268 BRIDGE_VLAN_INFO_MASTER = 1 << 0 # Operate on Bridge device as well
4269 BRIDGE_VLAN_INFO_PVID = 1 << 1 # VLAN is PVID, ingress untagged
4270 BRIDGE_VLAN_INFO_UNTAGGED = 1 << 2 # VLAN egresses untagged
4271 BRIDGE_VLAN_INFO_RANGE_BEGIN = 1 << 3 # VLAN is start of vlan range
4272 BRIDGE_VLAN_INFO_RANGE_END = 1 << 4 # VLAN is end of vlan range
4273 BRIDGE_VLAN_INFO_BRENTRY = 1 << 5 # Global bridge VLAN entry
4274
4275 bridge_vlan_to_string = {
4276 BRIDGE_VLAN_INFO_MASTER : 'BRIDGE_VLAN_INFO_MASTER',
4277 BRIDGE_VLAN_INFO_PVID : 'BRIDGE_VLAN_INFO_PVID',
4278 BRIDGE_VLAN_INFO_UNTAGGED : 'BRIDGE_VLAN_INFO_UNTAGGED',
4279 BRIDGE_VLAN_INFO_RANGE_BEGIN : 'BRIDGE_VLAN_INFO_RANGE_BEGIN',
4280 BRIDGE_VLAN_INFO_RANGE_END : 'BRIDGE_VLAN_INFO_RANGE_END',
4281 BRIDGE_VLAN_INFO_BRENTRY : 'BRIDGE_VLAN_INFO_BRENTRY'
4282 }
4283
4284 # Bridge flags
4285 BRIDGE_FLAGS_MASTER = 1
4286 BRIDGE_FLAGS_SELF = 2
4287
4288 bridge_flags_to_string = {
4289 BRIDGE_FLAGS_MASTER : 'BRIDGE_FLAGS_MASTER',
4290 BRIDGE_FLAGS_SELF : 'BRIDGE_FLAGS_SELF'
4291 }
4292
4293 # filters for IFLA_EXT_MASK
4294 RTEXT_FILTER_VF = 1 << 0
4295 RTEXT_FILTER_BRVLAN = 1 << 1
4296 RTEXT_FILTER_BRVLAN_COMPRESSED = 1 << 2
4297 RTEXT_FILTER_SKIP_STATS = 1 << 3
4298
4299 rtext_to_string = {
4300 RTEXT_FILTER_VF : 'RTEXT_FILTER_VF',
4301 RTEXT_FILTER_BRVLAN : 'RTEXT_FILTER_BRVLAN',
4302 RTEXT_FILTER_BRVLAN_COMPRESSED : 'RTEXT_FILTER_BRVLAN_COMPRESSED',
4303 RTEXT_FILTER_SKIP_STATS : 'RTEXT_FILTER_SKIP_STATS'
4304 }
4305
4306 def __init__(self, msgtype, debug=False, logger=None, use_color=True):
4307 NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
4308 self.PACK = 'BxHiII'
4309 self.LEN = calcsize(self.PACK)
4310
4311 def get_link_type_string(self, index):
4312 return self.get_string(self.link_type_to_string, index)
4313
4314 def get_ifla_inet6_af_spec_to_string(self, index):
4315 return self.get_string(self.ifla_inet6_af_spec_to_string, index)
4316
4317 def get_ifla_inet_af_spec_to_string(self, index):
4318 return self.get_string(self.ifla_inet_af_spec_to_string, index)
4319
4320 def get_ifla_bridge_af_spec_to_string(self, index):
4321 return self.get_string(self.ifla_bridge_af_spec_to_string, index)
4322
4323 def get_ifla_info_string(self, index):
4324 return self.get_string(self.ifla_info_to_string, index)
4325
4326 def get_ifla_vlan_string(self, index):
4327 return self.get_string(self.ifla_vlan_to_string, index)
4328
4329 def get_ifla_vxlan_string(self, index):
4330 return self.get_string(self.ifla_vxlan_to_string, index)
4331
4332 def get_ifla_vrf_string(self, index):
4333 return self.get_string(self.ifla_vrf_to_string, index)
4334
4335 def get_ifla_bond_slave_string(self, index):
4336 return self.get_string(self.ifla_bond_slave_to_string, index)
4337
4338 def get_ifla_macvlan_string(self, index):
4339 return self.get_string(self.ifla_macvlan_to_string, index)
4340
4341 def get_macvlan_mode_string(self, index):
4342 return self.get_string(self.macvlan_mode_to_string, index)
4343
4344 def get_ifla_gre_string(self, index):
4345 return self.get_string(self.ifla_gre_to_string, index)
4346
4347 def get_ifla_vti_string(self, index):
4348 return self.get_string(self.ifla_vti_to_string, index)
4349
4350 def get_ifla_iptun_string(self, index):
4351 return self.get_string(self.ifla_iptun_to_string, index)
4352
4353 def get_ifla_bond_string(self, index):
4354 return self.get_string(self.ifla_bond_to_string, index)
4355
4356 def get_ifla_bond_ad_string(self, index):
4357 return self.get_string(self.ifla_bond_ad_to_string, index)
4358
4359 def get_ifla_brport_string(self, index):
4360 return self.get_string(self.ifla_brport_to_string, index)
4361
4362 def get_ifla_br_string(self, index):
4363 return self.get_string(self.ifla_br_to_string, index)
4364
4365 def get_bridge_vlan_string(self, index):
4366 return self.get_string(self.bridge_vlan_to_string, index)
4367
4368 def get_bridge_flags_string(self, index):
4369 return self.get_string(self.bridge_flags_to_string, index)
4370
4371 def decode_service_header(self):
4372
4373 # Nothing to do if the message did not contain a service header
4374 if self.length == self.header_LEN:
4375 return
4376
4377 (self.family, self.device_type,
4378 self.ifindex,
4379 self.flags,
4380 self.change_mask) = \
4381 unpack(self.PACK, self.msg_data[:self.LEN])
4382
4383 if self.debug:
4384 color = yellow if self.use_color else None
4385 color_start = "\033[%dm" % color if color else ""
4386 color_end = "\033[0m" if color else ""
4387 self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
4388
4389 for x in range(0, self.LEN//4):
4390 if self.line_number == 5:
4391 extra = "Family %s (%s:%d), Device Type %s (%d - %s)" % \
4392 (zfilled_hex(self.family, 2), get_family_str(self.family), self.family,
4393 zfilled_hex(self.device_type, 4), self.device_type, self.get_link_type_string(self.device_type))
4394 elif self.line_number == 6:
4395 extra = "Interface Index %s (%d)" % (zfilled_hex(self.ifindex, 8), self.ifindex)
4396 elif self.line_number == 7:
4397 extra = "Device Flags %s (%s)" % (zfilled_hex(self.flags, 8), self.get_flags_string())
4398 elif self.line_number == 8:
4399 extra = "Change Mask %s" % zfilled_hex(self.change_mask, 8)
4400 else:
4401 extra = "Unexpected line number %d" % self.line_number
4402
4403 start = x * 4
4404 end = start + 4
4405 self.dump_buffer.append(data_to_color_text(self.line_number, color, self.msg_data[start:end], extra))
4406 self.line_number += 1
4407
4408 def is_up(self):
4409 if self.flags & Link.IFF_UP:
4410 return True
4411 return False
4412
4413
4414 class AttributeMDBA_MDB(Attribute):
4415 """
4416 /* Bridge multicast database attributes
4417 * [MDBA_MDB] = {
4418 * [MDBA_MDB_ENTRY] = {
4419 * [MDBA_MDB_ENTRY_INFO] {
4420 * struct br_mdb_entry
4421 * [MDBA_MDB_EATTR attributes]
4422 * }
4423 * }
4424 * }
4425 """
4426 """
4427 Current we support only MDB Dump and no MDB_GET.
4428 The code has been written to handle multiple entries in a single msg.
4429 data -- alignment
4430 MDBA_MDB ===> data[0:4]
4431 MDBA_MDB_ENTRY ===> data[4:8]
4432 MDBA_MDB_ENTRY_INFO ===> data[8:12]
4433 br_mdb_entry -- ===> ifindex data[12:16]
4434 -- ===> state,flags,vide data[16:20]
4435 -- ===> ip_addr data[20:36]
4436 -- ===> proto data[36:40]
4437 -- ===> MDB_MDB_EATTR_TIMER data[40:44]
4438 -- Timer Value data[44:48]
4439 """
4440
4441 def __init__(self, atype, string, family, logger):
4442 Attribute.__init__(self, atype, string, logger)
4443
4444 def decode(self, parent_msg, data):
4445 self.decode_length_type(data)
4446
4447 data = self.data[4:]
4448 if parent_msg.msgtype == RTM_GETMDB:
4449 self.value = []
4450 while data:
4451 (sub_attr_length, sub_attr_type) = unpack('=HH', data[:4])
4452 sub_attr_end = padded_length(sub_attr_length)
4453 sub_attr_data = data[4:sub_attr_end]
4454
4455 mdb_entry = {}
4456 mdb_entry[MDB.MDBA_MDB_ENTRY] = []
4457 if not sub_attr_length:
4458 self.log.error('parsed a zero length sub-attr')
4459 return
4460
4461 if sub_attr_type == MDB.MDBA_MDB_ENTRY:
4462 while sub_attr_data:
4463 nested_mdb_entry = {}
4464 (nested_attr_length,nested_attr_type) = unpack('=HH',sub_attr_data[:4])
4465 nested_attr_end = padded_length(nested_attr_length)
4466 if nested_attr_type == MDB.MDBA_MDB_ENTRY_INFO:
4467 (ifindex, state, flags, vid) = unpack('=LBBH',sub_attr_data[4:12])
4468 info = [ifindex,state,flags,vid]
4469 proto = unpack('=H',sub_attr_data[28:30])[0]
4470 if proto == htons(ETH_P_IP):
4471 ip_addr = ipnetwork.IPNetwork(unpack('>L', sub_attr_data[12:16])[0])
4472 else:
4473 (data1, data2) = unpack('>QQ',sub_attr_data[12:28])
4474 ip_addr = ipnetwork.IPNetwork(data1 << 64 | data2)
4475
4476 info.append(ip_addr)
4477
4478 try:
4479 (timer_attr_length,timer_attr_type) = unpack('=HH',sub_attr_data[32:36])
4480 if(timer_attr_type ) == MDB.MDBA_MDB_EATTR_TIMER:
4481 info.append({MDB.MDBA_MDB_EATTR_TIMER: (unpack('=I',sub_attr_data[36:40])[0])*0.01})
4482 except struct.error:
4483 self.log.error('No TimerAttribute')
4484 nested_mdb_entry[MDB.MDBA_MDB_ENTRY] = info
4485 mdb_entry[MDB.MDBA_MDB_ENTRY].append(nested_mdb_entry)
4486 sub_attr_data = sub_attr_data[nested_attr_end:]
4487 self.value.append(mdb_entry)
4488 data = data[sub_attr_end:]
4489
4490 else:
4491 self.value = {}
4492 while data:
4493 (sub_attr_length, sub_attr_type) = unpack('=HH', data[:4])
4494 sub_attr_end = padded_length(sub_attr_length)
4495 sub_attr_data = data[4:]
4496 if not sub_attr_length:
4497 self.log.error('parsed a zero length sub-attr')
4498 return
4499
4500 if sub_attr_type == MDB.MDBA_MDB_ENTRY:
4501 (nested_attr_length,nested_attr_type) = unpack('=HH',sub_attr_data[:4])
4502 if nested_attr_type == MDB.MDBA_MDB_ENTRY_INFO:
4503 self.value[MDB.MDBA_MDB_ENTRY] = {}
4504 (ifindex,state,flags,vid) = unpack('=LBBH',sub_attr_data[4:12])
4505 info = (ifindex,state,flags,vid)
4506 info = list(info)
4507 proto = unpack('=H',sub_attr_data[28:30])[0]
4508 if proto == 8:
4509 ip_addr = ipnetwork.IPNetwork(unpack('>L', sub_attr_data[12:16])[0])
4510 else:
4511 (data1, data2) = unpack('>QQ',sub_attr_data[12:28])
4512 ip_addr = ipnetwork.IPNetwork(data1 << 64 | data2)
4513
4514 info.append(ip_addr)
4515 self.value[MDB.MDBA_MDB_ENTRY][MDB.MDBA_MDB_ENTRY_INFO] = info
4516 data = data[sub_attr_end:]
4517
4518 def dump_lines(self, dump_buffer, line_number, color):
4519 line_number = self.dump_first_line(dump_buffer, line_number, color)
4520
4521 dump_buffer.append(data_to_color_text(line_number, color, self.data[0:4], self.value))
4522 return line_number + 1
4523
4524
4525
4526 class AttributeMDBA_ROUTER(Attribute):
4527 """
4528 /*
4529 * [MDBA_ROUTER] = {
4530 * [MDBA_ROUTER_PORT] = {
4531 * u32 ifindex
4532 * [MDBA_ROUTER_PATTR attributes]
4533 * }
4534 * }
4535 */
4536 """
4537
4538 def __init__(self, atype, string, family, logger):
4539 Attribute.__init__(self, atype, string, logger)
4540
4541 def decode(self, parent_msg, data):
4542 self.decode_length_type(data)
4543 data = self.data[4:]
4544 if parent_msg.msgtype == RTM_GETMDB:
4545 self.value = []
4546 while data:
4547 (sub_attr_length, sub_attr_type) = unpack('=HH', data[:4])
4548 sub_attr_end = padded_length(sub_attr_length)
4549 sub_attr_data = data[4:sub_attr_end]
4550 router_entry = {}
4551
4552 if not sub_attr_length:
4553 self.log.error('parsed a zero length sub-attr')
4554 return
4555
4556 if sub_attr_type == MDB.MDBA_ROUTER_PORT:
4557 ifindex = unpack('=I',sub_attr_data[:4])[0]
4558 sub_attr_data = sub_attr_data[4:]
4559 timer_info = {}
4560 type_info = {}
4561 while sub_attr_data:
4562 (nested_sub_attr_length, nested_sub_attr_type) = unpack('=HH',sub_attr_data[:4])
4563 nested_sub_attr_data = sub_attr_data[4:]
4564 nested_sub_attr_end = padded_length(nested_sub_attr_length)
4565 if nested_sub_attr_type == MDB.MDBA_ROUTER_PATTR_TIMER:
4566 timer_info[MDB.MDBA_ROUTER_PATTR_TIMER] = (unpack('=L',nested_sub_attr_data[ :4])[0])*0.01
4567 elif nested_sub_attr_type == MDB.MDBA_ROUTER_PATTR_TYPE:
4568 type_info[MDB.MDBA_ROUTER_PATTR_TYPE] = unpack('=B',nested_sub_attr_data[:1])[0]
4569 else:
4570 raise Exception("Invalid Router Port Attribute")
4571 sub_attr_data = sub_attr_data[nested_sub_attr_end:]
4572 router_entry[MDB.MDBA_ROUTER_PORT] = [ifindex,timer_info,type_info]
4573
4574 self.value.append(router_entry)
4575 data = data[sub_attr_end:]
4576
4577 else:
4578 self.value = {}
4579 while data:
4580 (sub_attr_length, sub_attr_type) = unpack('=HH', data[:4])
4581 sub_attr_end = padded_length(sub_attr_length)
4582 sub_attr_data = data[4:]
4583
4584 if not sub_attr_length:
4585 self.log.error('parsed a zero length sub-attr')
4586 return
4587
4588 if sub_attr_type == MDB.MDBA_ROUTER_PORT:
4589 ifindex = unpack('=L',sub_attr_data[:4])[0]
4590 self.value[MDB.MDBA_ROUTER_PORT] = ifindex
4591 data = data[sub_attr_end:]
4592
4593 def dump_lines(self, dump_buffer, line_number, color):
4594 line_number = self.dump_first_line(dump_buffer, line_number, color)
4595
4596 dump_buffer.append(data_to_color_text(line_number, color, self.data[0:4], self.value))
4597 return line_number + 1
4598
4599
4600 class AttributeMDBA_SET_ENTRY(Attribute):
4601
4602 def __init__(self, atype, string, family, logger):
4603 Attribute.__init__(self, atype, string, logger)
4604 self.PACK = None
4605 self.LEN = None
4606
4607 def set_value(self, value):
4608 self.value = value
4609
4610
4611 def encode(self):
4612 if self.value:
4613 (ifindex, flags, state,vid, ip, proto) = self.value
4614 if proto == htons(ETH_P_IP):
4615 self.PACK = '=IBBHLxxxxxxxxxxxxHxx'
4616 reorder = unpack('<L', ip.packed)[0]
4617 ip = ipnetwork.IPv4Address(reorder)
4618
4619 self.LEN = calcsize(self.PACK)
4620 length = self.HEADER_LEN + self.LEN
4621 #TODO Please check the encoding for Ipv6
4622 raw = pack(self.HEADER_PACK, length, self.atype) + pack(self.PACK, ifindex, flags, state, vid, ip, proto)
4623 elif proto == htons(ETH_P_IPV6):
4624 self.PACK = '=IBBHQQHxx'
4625 (data1, data2) = unpack('<QQ', ip.packed)
4626 self.LEN = calcsize(self.PACK)
4627 length = self.HEADER_LEN + self.LEN
4628 raw = pack(self.HEADER_PACK, length, self.atype) + pack(self.PACK, ifindex, flags, state, vid, data1,data2, proto)
4629
4630 else:
4631 raise Exception("%d Invalid Proto" % proto)
4632 raw = self.pad(length, raw)
4633 return raw
4634
4635
4636 def decode(self, parent_msg, data):
4637 self.decode_length_type(data)
4638 if self.length == 32:
4639 proto = unpack('=H', data[28:30])[0]
4640 if proto == htons(ETH_P_IP):
4641 self.PACK = '=IBBHLxxxxxxxxxxxxHxx'
4642 (ifindex, flags, state,vid, ip, proto) = unpack(self.PACK, self.data[4:])
4643 elif proto == htons(ETH_P_IPV6):
4644 self.PACK = '=IBBHQQHxx'
4645 (ifindex, flags, state,vid, data1,data2, proto) = unpack(self.PACK, self.data[4:])
4646 ip = ipnetwork.IPNetwork(data1 << 64 | data2)
4647 else:
4648 raise Exception("%d Invalid Proto" % proto)
4649 self.LEN = calcsize(self.PACK)
4650 self.value = (ifindex, flags, state,vid, ip, proto)
4651 else:
4652 raise Exception("Invalid Attribute Length")
4653
4654
4655
4656 class MDB(NetlinkPacket):
4657 """
4658 Service Header
4659 0 1 2 3
4660 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
4661 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4662 | Family | Reserved1 | Reserved2 |
4663 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4664 | Interface Index |
4665 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4666
4667 struct br_port_msg {
4668 __u8 family;
4669 __u32 ifindex;
4670 };
4671
4672 RTM_GETMDB - Service Header
4673
4674 /* Bridge multicast database attributes
4675 * [MDBA_MDB] = {
4676 * [MDBA_MDB_ENTRY] = {
4677 * [MDBA_MDB_ENTRY_INFO] {
4678 * struct br_mdb_entry
4679 * [MDBA_MDB_EATTR attributes]
4680 * }
4681 * }
4682 * }
4683 * [MDBA_ROUTER] = {
4684 * [MDBA_ROUTER_PORT] = {
4685 * u32 ifindex
4686 * [MDBA_ROUTER_PATTR attributes]
4687 * }
4688 * }
4689 */
4690
4691 struct br_mdb_entry {
4692 __u32 ifindex;
4693 #define MDB_TEMPORARY 0
4694 #define MDB_PERMANENT 1
4695 __u8 state;
4696 #define MDB_FLAGS_OFFLOAD (1 << 0)
4697 #define MDB_FLAGS_FAST_LEAVE (1 << 1)
4698 __u8 flags;
4699 __u16 vid;
4700 struct {
4701 union {
4702 __be32 ip4;
4703 struct in6_addr ip6;
4704 } u;
4705 __be16 proto;
4706 } addr;
4707 };
4708 """
4709 MDBA_UNSPEC = 0
4710 MDBA_MDB = 1
4711 MDBA_ROUTER = 2
4712 __MDBA_MAX = 3
4713 MDBA_MAX = (__MDBA_MAX - 1)
4714
4715 #MDBA Set Attributes
4716 MDBA_SET_ENTRY_UNSPEC = 0
4717 MDBA_SET_ENTRY = 1
4718 __MDBA_SET_ENTRY_MAX = 2
4719 MDBA_SET_ENTRY_MAX = (__MDBA_SET_ENTRY_MAX - 1)
4720
4721 #MDBA flags
4722 MDB_FLAGS_OFFLOAD = 1 << 0
4723 MDB_FLAGS_FAST_LEAVE = 1 << 1
4724
4725 #MDBA Attributes
4726 MDBA_MDB_UNSPEC = 0
4727 MDBA_MDB_ENTRY = 1
4728 __MDBA_MDB_MAX = 2
4729 MDBA_MDB_MAX = (__MDBA_MDB_MAX - 1)
4730
4731 MDBA_MDB_ENTRY_UNSPEC = 0
4732 MDBA_MDB_ENTRY_INFO = 1
4733 __MDBA_MDB_ENTRY_MAX = 2
4734 MDBA_MDB_ENTRY_MAX = (__MDBA_MDB_ENTRY_MAX - 1)
4735
4736 MDBA_MDB_EATTR_UNSPEC = 0
4737 MDBA_MDB_EATTR_TIMER = 1
4738 __MDBA_MDB_EATTR_MAX = 2
4739 MDBA_MDB_ENTRY_MAX = (__MDBA_MDB_EATTR_MAX -1)
4740
4741 # router port attributes
4742 MDBA_ROUTER_UNSPEC = 0
4743 MDBA_ROUTER_PORT = 1
4744 __MDBA_ROUTER_MAX = 2
4745 MDBA_ROUTER_MAX = (__MDBA_ROUTER_MAX - 1)
4746
4747
4748 MDBA_ROUTER_PATTR_UNSPEC = 0
4749 MDBA_ROUTER_PATTR_TIMER = 1
4750 MDBA_ROUTER_PATTR_TYPE = 2
4751 __MDBA_ROUTER_PATTR_MAX = 3
4752 MDBA_ROUTER_PATTR_MAX = (__MDBA_ROUTER_PATTR_MAX - 1)
4753
4754 MDB_RTR_TYPE_DISABLED = 0
4755 MDB_RTR_TYPE_TEMP_QUERY = 1
4756 MDB_RTR_TYPE_PERM = 2
4757 MDB_RTR_TYPE_TEMP = 3
4758
4759
4760 def __init__(self, msgtype, debug=False, logger=None, use_color=True, rx=False, tx=False):
4761 NetlinkPacket.__init__(self, msgtype, debug, logger, use_color, rx, tx)
4762 if self.tx and msgtype in (RTM_NEWMDB, RTM_DELMDB):
4763 self.attribute_to_class = {
4764 self.MDBA_UNSPEC: ('MDBA_SET_ENTRY_UNSPEC', AttributeGeneric),
4765 self.MDBA_SET_ENTRY: ('MDBA_SET_ENTRY', AttributeMDBA_SET_ENTRY),
4766 }
4767 else:
4768 self.attribute_to_class = {
4769 self.MDBA_UNSPEC: ('MDBA_UNSPEC', AttributeGeneric),
4770 self.MDBA_MDB: ('MDBA_MDB', AttributeMDBA_MDB),
4771 self.MDBA_ROUTER: ('MDBA_ROUTER', AttributeMDBA_ROUTER),
4772 }
4773
4774 self.PACK = 'Bxxxi'
4775 self.LEN = calcsize(self.PACK)
4776
4777 def decode_service_header(self):
4778 # Nothing to do if the message did not contain a service header
4779 if self.length == self.header_LEN:
4780 return
4781
4782 (self.family,self.ifindex) = unpack(self.PACK, self.msg_data[:self.LEN])
4783 if self.debug:
4784 color = yellow if self.use_color else None
4785 color_start = "\033[%dm" % color if color else ""
4786 color_end = "\033[0m" if color else ""
4787 self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
4788 self.dump_buffer.append(self.msg_data)
4789 self.dump_buffer.append(data_to_color_text(1, color, bytearray(struct.pack('!I', self.family)),
4790 "Family %s (%d)" % (zfilled_hex(self.family, 2), self.family)))
4791 self.dump_buffer.append(data_to_color_text(2, color, bytearray(struct.pack('i', self.ifindex)),
4792 "Ifindex %s (%d)" % (zfilled_hex(self.ifindex, 8), self.ifindex)))
4793
4794 class Netconf(Link):
4795 """
4796 RTM_NEWNETCONF - Service Header
4797
4798 0 1
4799 0 1 2 3 4 5 6 7 8
4800 +-+-+-+-+-+-+-+-+
4801 | Family |
4802 +-+-+-+-+-+-+-+-+
4803
4804 RTM_GETNETCONF - Service Header
4805
4806 0 1 2 3
4807 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
4808 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4809 | Family | Reserved | Device Type |
4810 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4811 | Interface Index |
4812 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4813 | Device Flags |
4814 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4815 | Change Mask |
4816 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4817 """
4818 # Netconf attributes
4819 # /usr/include/linux/netconf.h
4820 NETCONFA_UNSPEC = 0
4821 NETCONFA_IFINDEX = 1
4822 NETCONFA_FORWARDING = 2
4823 NETCONFA_RP_FILTER = 3
4824 NETCONFA_MC_FORWARDING = 4
4825 NETCONFA_PROXY_NEIGH = 5
4826 NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN = 6
4827 NETCONFA_INPUT = 7
4828 NETCONFA_BC_FORWARDING = 8
4829 __NETCONFA_MAX = 9
4830
4831 NETCONFA_MAX = (__NETCONFA_MAX - 1)
4832
4833 NETCONFA_ALL = -1
4834 NETCONFA_IFINDEX_ALL = -1
4835 NETCONFA_IFINDEX_DEFAULT = -2
4836
4837 NETCONF_ATTR_FAMILY = 0x0001
4838 NETCONF_ATTR_IFINDEX = 0x0002
4839 NETCONF_ATTR_RP_FILTER = 0x0004
4840 NETCONF_ATTR_FWDING = 0x0008
4841 NETCONF_ATTR_MC_FWDING = 0x0010
4842 NETCONF_ATTR_PROXY_NEIGH = 0x0020
4843 NETCONF_ATTR_IGNORE_RT_LINKDWN = 0x0040
4844
4845 attribute_to_class = {
4846 NETCONFA_UNSPEC : ('NETCONFA_UNSPEC', AttributeGeneric),
4847 NETCONFA_IFINDEX : ('NETCONFA_IFINDEX', AttributeFourByteValue),
4848 NETCONFA_FORWARDING : ('NETCONFA_FORWARDING', AttributeFourByteValue),
4849 NETCONFA_RP_FILTER : ('NETCONFA_RP_FILTER', AttributeFourByteValue),
4850 NETCONFA_MC_FORWARDING : ('NETCONFA_MC_FORWARDING', AttributeFourByteValue),
4851 NETCONFA_PROXY_NEIGH : ('NETCONFA_PROXY_NEIGH', AttributeFourByteValue),
4852 NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN : ('NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN', AttributeFourByteValue),
4853 NETCONFA_INPUT : ('NETCONFA_INPUT', AttributeFourByteValue),
4854 NETCONFA_BC_FORWARDING : ('NETCONFA_BC_FORWARDING', AttributeFourByteValue),
4855 }
4856
4857 def __init__(self, msgtype, debug=False, logger=None, use_color=True):
4858 NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
4859 if msgtype == RTM_GETNETCONF: # same as RTM_GETLINK
4860 self.PACK = 'BxHiII'
4861 self.LEN = calcsize(self.PACK)
4862 else:
4863 # RTM_NEWNETCONF
4864 # RTM_DELNETCONF
4865 self.PACK = 'Bxxx'
4866 self.LEN = calcsize(self.PACK)
4867
4868 def decode_service_header(self):
4869 # Nothing to do if the message did not contain a service header
4870 if self.length == self.header_LEN:
4871 return
4872
4873 if self.msgtype == RTM_GETNETCONF:
4874 super(Netconf, self).decode_service_header()
4875
4876 else:
4877 # RTM_NEWNETCONF
4878 # RTM_DELNETCONF
4879 (self.family,) = unpack(self.PACK, self.msg_data[:self.LEN])
4880
4881 if self.debug:
4882 color = yellow if self.use_color else None
4883 color_start = "\033[%dm" % color if color else ""
4884 color_end = "\033[0m" if color else ""
4885 self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
4886 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)))
4887
4888
4889 class Neighbor(NetlinkPacket):
4890 """
4891 Service Header
4892
4893 0 1 2 3
4894 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
4895 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4896 | Family | Reserved1 | Reserved2 |
4897 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4898 | Interface Index |
4899 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4900 | State | Flags | Type |
4901 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4902 """
4903
4904 # Neighbor attributes
4905 # /usr/include/linux/neighbour.h
4906 NDA_UNSPEC = 0x00 # Unknown type
4907 NDA_DST = 0x01 # A neighbour cache network. layer destination address
4908 NDA_LLADDR = 0x02 # A neighbor cache link layer address.
4909 NDA_CACHEINFO = 0x03 # Cache statistics
4910 NDA_PROBES = 0x04
4911 NDA_VLAN = 0x05
4912 NDA_PORT = 0x06
4913 NDA_VNI = 0x07
4914 NDA_IFINDEX = 0x08
4915 NDA_MASTER = 0x09
4916 NDA_LINK_NETNSID = 0x0A
4917
4918 attribute_to_class = {
4919 NDA_UNSPEC : ('NDA_UNSPEC', AttributeGeneric),
4920 NDA_DST : ('NDA_DST', AttributeIPAddress),
4921 NDA_LLADDR : ('NDA_LLADDR', AttributeMACAddress),
4922 NDA_CACHEINFO : ('NDA_CACHEINFO', AttributeFourByteList),
4923 NDA_PROBES : ('NDA_PROBES', AttributeFourByteValue),
4924 NDA_VLAN : ('NDA_VLAN', AttributeTwoByteValue),
4925 NDA_PORT : ('NDA_PORT', AttributeGeneric),
4926 NDA_VNI : ('NDA_VNI', AttributeFourByteValue),
4927 NDA_IFINDEX : ('NDA_IFINDEX', AttributeFourByteValue),
4928 NDA_MASTER : ('NDA_MASTER', AttributeFourByteValue),
4929 NDA_LINK_NETNSID : ('NDA_LINK_NETNSID', AttributeGeneric)
4930 }
4931
4932 # Neighbor flags
4933 # /usr/include/linux/neighbour.h
4934 NTF_USE = 0x01
4935 NTF_SELF = 0x02
4936 NTF_MASTER = 0x04
4937 NTF_PROXY = 0x08 # A proxy ARP entry
4938 NTF_EXT_LEARNED = 0x10 # neigh entry installed by an external APP
4939 NTF_ROUTER = 0x80 # An IPv6 router
4940
4941 flag_to_string = {
4942 NTF_USE : 'NTF_USE',
4943 NTF_SELF : 'NTF_SELF',
4944 NTF_MASTER : 'NTF_MASTER',
4945 NTF_PROXY : 'NTF_PROXY',
4946 NTF_EXT_LEARNED : 'NTF_EXT_LEARNED',
4947 NTF_ROUTER : 'NTF_ROUTER'
4948 }
4949
4950 # Neighbor states
4951 # /usr/include/linux/neighbour.h
4952 NUD_NONE = 0x00
4953 NUD_INCOMPLETE = 0x01 # Still attempting to resolve
4954 NUD_REACHABLE = 0x02 # A confirmed working cache entry
4955 NUD_STALE = 0x04 # an expired cache entry
4956 NUD_DELAY = 0x08 # Neighbor no longer reachable. Traffic sent, waiting for confirmatio.
4957 NUD_PROBE = 0x10 # A cache entry that is currently being re-solicited
4958 NUD_FAILED = 0x20 # An invalid cache entry
4959 NUD_NOARP = 0x40 # A device which does not do neighbor discovery(ARP)
4960 NUD_PERMANENT = 0x80 # A static entry
4961
4962 state_to_string = {
4963 NUD_NONE : 'NUD_NONE',
4964 NUD_INCOMPLETE : 'NUD_INCOMPLETE',
4965 NUD_REACHABLE : 'NUD_REACHABLE',
4966 NUD_STALE : 'NUD_STALE',
4967 NUD_DELAY : 'NUD_DELAY',
4968 NUD_PROBE : 'NUD_PROBE',
4969 NUD_FAILED : 'NUD_FAILED',
4970 NUD_NOARP : 'NUD_NOARP',
4971 NUD_PERMANENT : 'NUD_PERMANENT'
4972 }
4973
4974 def __init__(self, msgtype, debug=False, logger=None, use_color=True):
4975 NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
4976 self.PACK = 'BxxxiHBB'
4977 self.LEN = calcsize(self.PACK)
4978
4979 def get_state_string(self, index):
4980 return self.get_string(self.state_to_string, index)
4981
4982 def get_states_string(self, states):
4983 for_string = []
4984
4985 if states & Neighbor.NUD_INCOMPLETE:
4986 for_string.append('NUD_INCOMPLETE')
4987
4988 if states & Neighbor.NUD_REACHABLE:
4989 for_string.append('NUD_REACHABLE')
4990
4991 if states & Neighbor.NUD_STALE:
4992 for_string.append('NUD_STALE')
4993
4994 if states & Neighbor.NUD_DELAY:
4995 for_string.append('NUD_DELAY')
4996
4997 if states & Neighbor.NUD_PROBE:
4998 for_string.append('NUD_PROBE')
4999
5000 if states & Neighbor.NUD_FAILED:
5001 for_string.append('NUD_FAILED')
5002
5003 if states & Neighbor.NUD_NOARP:
5004 for_string.append('NUD_NOARP')
5005
5006 if states & Neighbor.NUD_PERMANENT:
5007 for_string.append('NUD_PERMANENT')
5008
5009 return ', '.join(for_string)
5010
5011 def get_flags_string(self, flags):
5012 for_string = []
5013
5014 if flags & Neighbor.NTF_USE:
5015 for_string.append('NTF_USE')
5016
5017 if flags & Neighbor.NTF_SELF:
5018 for_string.append('NTF_SELF')
5019
5020 if flags & Neighbor.NTF_MASTER:
5021 for_string.append('NTF_MASTER')
5022
5023 if flags & Neighbor.NTF_PROXY:
5024 for_string.append('NTF_PROXY')
5025
5026 if flags & Neighbor.NTF_ROUTER:
5027 for_string.append('NTF_ROUTER')
5028
5029 return ', '.join(for_string)
5030
5031 def decode_service_header(self):
5032
5033 # Nothing to do if the message did not contain a service header
5034 if self.length == self.header_LEN:
5035 return
5036
5037 (self.family,
5038 self.ifindex,
5039 self.state, self.flags, self.neighbor_type) = \
5040 unpack(self.PACK, self.msg_data[:self.LEN])
5041
5042 if self.debug:
5043 color = yellow if self.use_color else None
5044 color_start = "\033[%dm" % color if color else ""
5045 color_end = "\033[0m" if color else ""
5046 self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
5047
5048 for x in range(0, self.LEN//4):
5049 if self.line_number == 5:
5050 extra = "Family %s (%s:%d)" % (zfilled_hex(self.family, 2), get_family_str(self.family), self.family)
5051 elif self.line_number == 6:
5052 extra = "Interface Index %s (%d)" % (zfilled_hex(self.ifindex, 8), self.ifindex)
5053 elif self.line_number == 7:
5054 extra = "State %s (%d) %s, Flags %s (%s) %s, Type %s (%d)" % \
5055 (zfilled_hex(self.state, 4), self.state, self.get_states_string(self.state),
5056 zfilled_hex(self.flags, 2), self.flags, self.get_flags_string(self.flags),
5057 zfilled_hex(self.neighbor_type, 4), self.neighbor_type)
5058 else:
5059 extra = "Unexpected line number %d" % self.line_number
5060
5061 start = x * 4
5062 end = start + 4
5063 self.dump_buffer.append(data_to_color_text(self.line_number, color, self.msg_data[start:end], extra))
5064 self.line_number += 1
5065
5066
5067 class Route(NetlinkPacket):
5068 """
5069 Service Header
5070
5071 0 1 2 3
5072 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
5073 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5074 | Family | Dest length | Src length | TOS |
5075 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5076 | Table ID | Protocol | Scope | Type |
5077 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5078 | Flags |
5079 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5080 """
5081
5082 # Route attributes
5083 # /usr/include/linux/rtnetlink.h
5084 RTA_UNSPEC = 0x00 # Ignored.
5085 RTA_DST = 0x01 # Protocol address for route destination address.
5086 RTA_SRC = 0x02 # Protocol address for route source address.
5087 RTA_IIF = 0x03 # Input interface index.
5088 RTA_OIF = 0x04 # Output interface index.
5089 RTA_GATEWAY = 0x05 # Protocol address for the gateway of the route
5090 RTA_PRIORITY = 0x06 # Priority of broker.
5091 RTA_PREFSRC = 0x07 # Preferred source address in cases where more than one source address could be used.
5092 RTA_METRICS = 0x08 # Route metrics attributed to route and associated protocols(e.g., RTT, initial TCP window, etc.).
5093 RTA_MULTIPATH = 0x09 # Multipath route next hop's attributes.
5094 RTA_PROTOINFO = 0x0A # Firewall based policy routing attribute.
5095 RTA_FLOW = 0x0B # Route realm.
5096 RTA_CACHEINFO = 0x0C # Cached route information.
5097 RTA_SESSION = 0x0D
5098 RTA_MP_ALGO = 0x0E
5099 RTA_TABLE = 0x0F
5100 RTA_MARK = 0x10
5101 RTA_MFC_STATS = 0x11
5102 RTA_VIA = 0x12
5103 RTA_NEWDST = 0x13
5104 RTA_PREF = 0x14
5105 RTA_ENCAP_TYPE= 0x15
5106 RTA_ENCAP = 0x16
5107
5108 attribute_to_class = {
5109 RTA_UNSPEC : ('RTA_UNSPEC', AttributeGeneric),
5110 RTA_DST : ('RTA_DST', AttributeIPAddress),
5111 RTA_SRC : ('RTA_SRC', AttributeIPAddress),
5112 RTA_IIF : ('RTA_IIF', AttributeFourByteValue),
5113 RTA_OIF : ('RTA_OIF', AttributeFourByteValue),
5114 RTA_GATEWAY : ('RTA_GATEWAY', AttributeIPAddress),
5115 RTA_PRIORITY : ('RTA_PRIORITY', AttributeFourByteValue),
5116 RTA_PREFSRC : ('RTA_PREFSRC', AttributeIPAddress),
5117 RTA_METRICS : ('RTA_METRICS', AttributeGeneric),
5118 RTA_MULTIPATH : ('RTA_MULTIPATH', AttributeRTA_MULTIPATH),
5119 RTA_PROTOINFO : ('RTA_PROTOINFO', AttributeGeneric),
5120 RTA_FLOW : ('RTA_FLOW', AttributeGeneric),
5121 RTA_CACHEINFO : ('RTA_CACHEINFO', AttributeGeneric),
5122 RTA_SESSION : ('RTA_SESSION', AttributeGeneric),
5123 RTA_MP_ALGO : ('RTA_MP_ALGO', AttributeGeneric),
5124 RTA_TABLE : ('RTA_TABLE', AttributeFourByteValue),
5125 RTA_MARK : ('RTA_MARK', AttributeGeneric),
5126 RTA_MFC_STATS : ('RTA_MFC_STATS', AttributeGeneric),
5127 RTA_VIA : ('RTA_VIA', AttributeGeneric),
5128 RTA_NEWDST : ('RTA_NEWDST', AttributeGeneric),
5129 RTA_PREF : ('RTA_PREF', AttributeGeneric),
5130 RTA_ENCAP_TYPE: ('RTA_ENCAP_TYPE', AttributeGeneric),
5131 RTA_ENCAP : ('RTA_ENCAP', AttributeGeneric)
5132 }
5133
5134 # Route tables
5135 # /usr/include/linux/rtnetlink.h
5136 RT_TABLE_UNSPEC = 0x00 # An unspecified routing table
5137 RT_TABLE_COMPAT = 0xFC
5138 RT_TABLE_DEFAULT = 0xFD # The default table
5139 RT_TABLE_MAIN = 0xFE # The main table
5140 RT_TABLE_LOCAL = 0xFF # The local table
5141
5142 table_to_string = {
5143 RT_TABLE_UNSPEC : 'RT_TABLE_UNSPEC',
5144 RT_TABLE_COMPAT : 'RT_TABLE_COMPAT',
5145 RT_TABLE_DEFAULT : 'RT_TABLE_DEFAULT',
5146 RT_TABLE_MAIN : 'RT_TABLE_MAIN',
5147 RT_TABLE_LOCAL : 'RT_TABLE_LOCAL'
5148 }
5149
5150 # Route scope
5151 # /usr/include/linux/rtnetlink.h
5152 RT_SCOPE_UNIVERSE = 0x00 # Global route
5153 RT_SCOPE_SITE = 0xC8 # Interior route in the local autonomous system
5154 RT_SCOPE_LINK = 0xFD # Route on this link
5155 RT_SCOPE_HOST = 0xFE # Route on the local host
5156 RT_SCOPE_NOWHERE = 0xFF # Destination does not exist
5157
5158 scope_to_string = {
5159 RT_SCOPE_UNIVERSE : 'RT_SCOPE_UNIVERSE',
5160 RT_SCOPE_SITE : 'RT_SCOPE_SITE',
5161 RT_SCOPE_LINK : 'RT_SCOPE_LINK',
5162 RT_SCOPE_HOST : 'RT_SCOPE_HOST',
5163 RT_SCOPE_NOWHERE : 'RT_SCOPE_NOWHERE'
5164 }
5165
5166 # Route scope to string
5167 # iproute2/lib/rt_names.c
5168 rtnl_rtscope_tab = {
5169 RT_SCOPE_UNIVERSE: 'global',
5170 RT_SCOPE_NOWHERE: 'nowhere',
5171 RT_SCOPE_HOST: 'host',
5172 RT_SCOPE_LINK: 'link',
5173 RT_SCOPE_SITE: 'site'
5174 }
5175
5176 # Routing stack
5177 # /usr/include/linux/rtnetlink.h
5178 RT_PROT_UNSPEC = 0x00 # Identifies what/who added the route
5179 RT_PROT_REDIRECT = 0x01 # By an ICMP redirect
5180 RT_PROT_KERNEL = 0x02 # By the kernel
5181 RT_PROT_BOOT = 0x03 # During bootup
5182 RT_PROT_STATIC = 0x04 # By the administrator
5183 RT_PROT_GATED = 0x08 # GateD
5184 RT_PROT_RA = 0x09 # RDISC/ND router advertissements
5185 RT_PROT_MRT = 0x0A # Merit MRT
5186 RT_PROT_ZEBRA = 0x0B # ZEBRA
5187 RT_PROT_BIRD = 0x0C # BIRD
5188 RT_PROT_DNROUTED = 0x0D # DECnet routing daemon
5189 RT_PROT_XORP = 0x0E # XORP
5190 RT_PROT_NTK = 0x0F # Netsukuku
5191 RT_PROT_DHCP = 0x10 # DHCP client
5192 RT_PROT_EXABGP = 0x11 # Exa Networks ExaBGP
5193
5194 prot_to_string = {
5195 RT_PROT_UNSPEC : 'RT_PROT_UNSPEC',
5196 RT_PROT_REDIRECT : 'RT_PROT_REDIRECT',
5197 RT_PROT_KERNEL : 'RT_PROT_KERNEL',
5198 RT_PROT_BOOT : 'RT_PROT_BOOT',
5199 RT_PROT_STATIC : 'RT_PROT_STATIC',
5200 RT_PROT_GATED : 'RT_PROT_GATED',
5201 RT_PROT_RA : 'RT_PROT_RA',
5202 RT_PROT_MRT : 'RT_PROT_MRT',
5203 RT_PROT_ZEBRA : 'RT_PROT_ZEBRA',
5204 RT_PROT_BIRD : 'RT_PROT_BIRD',
5205 RT_PROT_DNROUTED : 'RT_PROT_DNROUTED',
5206 RT_PROT_XORP : 'RT_PROT_XORP',
5207 RT_PROT_NTK : 'RT_PROT_NTK',
5208 RT_PROT_DHCP : 'RT_PROT_DHCP',
5209 RT_PROT_EXABGP : 'RT_PROT_EXABGP'
5210 }
5211
5212 # Route types
5213 # /usr/include/linux/rtnetlink.h
5214 RTN_UNSPEC = 0x00 # Unknown broker.
5215 RTN_UNICAST = 0x01 # A gateway or direct broker.
5216 RTN_LOCAL = 0x02 # A local interface broker.
5217 RTN_BROADCAST = 0x03 # A local broadcast route(sent as a broadcast).
5218 RTN_ANYCAST = 0x04 # An anycast broker.
5219 RTN_MULTICAST = 0x05 # A multicast broker.
5220 RTN_BLACKHOLE = 0x06 # A silent packet dropping broker.
5221 RTN_UNREACHABLE = 0x07 # An unreachable destination. Packets dropped and
5222 # host unreachable ICMPs are sent to the originator.
5223 RTN_PROHIBIT = 0x08 # A packet rejection broker. Packets are dropped and
5224 # communication prohibited ICMPs are sent to the originator.
5225 RTN_THROW = 0x09 # When used with policy routing, continue routing lookup
5226 # in another table. Under normal routing, packets are
5227 # dropped and net unreachable ICMPs are sent to the originator.
5228 RTN_NAT = 0x0A # A network address translation rule.
5229 RTN_XRESOLVE = 0x0B # Refer to an external resolver(not implemented).
5230
5231 rt_type_to_string = {
5232 RTN_UNSPEC : 'RTN_UNSPEC',
5233 RTN_UNICAST : 'RTN_UNICAST',
5234 RTN_LOCAL : 'RTN_LOCAL',
5235 RTN_BROADCAST : 'RTN_BROADCAST',
5236 RTN_ANYCAST : 'RTN_ANYCAST',
5237 RTN_MULTICAST : 'RTN_MULTICAST',
5238 RTN_BLACKHOLE : 'RTN_BLACKHOLE',
5239 RTN_UNREACHABLE : 'RTN_UNREACHABLE',
5240 RTN_PROHIBIT : 'RTN_PROHIBIT',
5241 RTN_THROW : 'RTN_THROW',
5242 RTN_NAT : 'RTN_NAT',
5243 RTN_XRESOLVE : 'RTN_XRESOLVE'
5244 }
5245
5246 # Route flags
5247 # /usr/include/linux/rtnetlink.h
5248 RTM_F_NOTIFY = 0x100 # If the route changes, notify the user
5249 RTM_F_CLONED = 0x200 # Route is cloned from another route
5250 RTM_F_EQUALIZE = 0x400 # Allow randomization of next hop path in multi-path routing(currently not implemented)
5251 RTM_F_PREFIX = 0x800 # Prefix Address
5252
5253 flag_to_string = {
5254 RTM_F_NOTIFY : 'RTM_F_NOTIFY',
5255 RTM_F_CLONED : 'RTM_F_CLONED',
5256 RTM_F_EQUALIZE : 'RTM_F_EQUALIZE',
5257 RTM_F_PREFIX : 'RTM_F_PREFIX'
5258 }
5259
5260 def __init__(self, msgtype, debug=False, logger=None, use_color=True):
5261 NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
5262 self.PACK = '=8BI' # or is it 8Bi ?
5263 self.LEN = calcsize(self.PACK)
5264
5265 def get_prefix_string(self):
5266 dst = self.get_attribute_value(self.RTA_DST)
5267
5268 if dst:
5269 return "%s/%d" % (dst, self.src_len)
5270 else:
5271 if self.family == AF_INET:
5272 return "0.0.0.0/0"
5273 elif self.family == AF_INET6:
5274 return "::/0"
5275
5276 def get_protocol_string(self, index=None):
5277 if index is None:
5278 index = self.protocol
5279 return self.get_string(self.prot_to_string, index)
5280
5281 def get_rt_type_string(self, index=None):
5282 if index is None:
5283 index = self.route_type
5284 return self.get_string(self.rt_type_to_string, index)
5285
5286 def get_scope_string(self, index=None):
5287 if index is None:
5288 index = self.scope
5289 return self.get_string(self.scope_to_string, index)
5290
5291 def get_table_id_string(self, index=None):
5292 if index is None:
5293 index = self.table_id
5294 return self.get_string(self.table_to_string, index)
5295
5296 def _get_ifname_from_index(self, ifindex, ifname_by_index):
5297 if ifindex:
5298 ifname = ifname_by_index.get(ifindex)
5299
5300 if ifname is None:
5301 ifname = str(ifindex)
5302 else:
5303 ifname = None
5304
5305 return ifname
5306
5307 def get_nexthops(self, ifname_by_index={}):
5308 nexthop = self.get_attribute_value(self.RTA_GATEWAY)
5309 multipath = self.get_attribute_value(self.RTA_MULTIPATH)
5310 nexthops = []
5311
5312 if nexthop:
5313 rta_oif = self.get_attribute_value(self.RTA_OIF)
5314 ifname = self._get_ifname_from_index(rta_oif, ifname_by_index)
5315 nexthops.append((nexthop, ifname))
5316
5317 elif multipath:
5318 for (nexthop, rtnh_ifindex, rtnh_flags, rtnh_hops) in multipath:
5319 ifname = self._get_ifname_from_index(rtnh_ifindex, ifname_by_index)
5320 nexthops.append((nexthop, ifname))
5321
5322 return nexthops
5323
5324 def get_nexthops_string(self, ifname_by_index={}):
5325 output = []
5326
5327 for (nexthop, ifname) in self.get_nexthops(ifname_by_index):
5328 output.append(" via %s on %s" % (nexthop, ifname))
5329
5330 return ",".join(output)
5331
5332 def decode_service_header(self):
5333
5334 # Nothing to do if the message did not contain a service header
5335 if self.length == self.header_LEN:
5336 return
5337
5338 (self.family, self.src_len, self.dst_len, self.tos,
5339 self.table_id, self.protocol, self.scope, self.route_type,
5340 self.flags) = \
5341 unpack(self.PACK, self.msg_data[:self.LEN])
5342
5343 if self.debug:
5344 color = yellow if self.use_color else None
5345 color_start = "\033[%dm" % color if color else ""
5346 color_end = "\033[0m" if color else ""
5347 self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
5348
5349 for x in range(0, self.LEN//4):
5350 if self.line_number == 5:
5351 extra = "Family %s (%s:%d), Source Length %s (%d), Destination Length %s (%d), TOS %s (%d)" % \
5352 (zfilled_hex(self.family, 2), get_family_str(self.family), self.family,
5353 zfilled_hex(self.src_len, 2), self.src_len,
5354 zfilled_hex(self.dst_len, 2), self.dst_len,
5355 zfilled_hex(self.tos, 2), self.tos)
5356 elif self.line_number == 6:
5357 extra = "Table ID %s (%d - %s), Protocol %s (%d - %s), Scope %s (%d - %s), Type %s (%d - %s)" % \
5358 (zfilled_hex(self.table_id, 2), self.table_id, self.get_table_id_string(),
5359 zfilled_hex(self.protocol, 2), self.protocol, self.get_protocol_string(),
5360 zfilled_hex(self.scope, 2), self.scope, self.get_scope_string(),
5361 zfilled_hex(self.route_type, 2), self.route_type, self.get_rt_type_string())
5362 elif self.line_number == 7:
5363 extra = "Flags %s" % zfilled_hex(self.flags, 8)
5364 else:
5365 extra = "Unexpected line number %d" % self.line_number
5366
5367 start = x * 4
5368 end = start + 4
5369 self.dump_buffer.append(data_to_color_text(self.line_number, color, self.msg_data[start:end], extra))
5370 self.line_number += 1
5371
5372
5373 class Done(NetlinkPacket):
5374 """
5375 NLMSG_DONE
5376
5377 Service Header
5378 0 1 2 3
5379 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
5380 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5381 | TBD |
5382 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5383 """
5384
5385 def __init__(self, msgtype, debug=False, logger=None, use_color=True):
5386 NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
5387 self.PACK = 'i'
5388 self.LEN = calcsize(self.PACK)
5389
5390 def decode_service_header(self):
5391 foo = unpack(self.PACK, self.msg_data[:self.LEN])
5392
5393 if self.debug:
5394 color = yellow if self.use_color else None
5395 color_start = "\033[%dm" % color if color else ""
5396 color_end = "\033[0m" if color else ""
5397 self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
5398
5399 for x in range(0, self.LEN//4):
5400 extra = ''
5401 start = x * 4
5402 end = start + 4
5403 self.dump_buffer.append(data_to_color_text(self.line_number, color, self.msg_data[start:end], extra))
5404 self.line_number += 1