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