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