3 # Copyright 2016-2017 Cumulus Networks, Inc. All rights reserved.
4 # Author: Julien Fortin, julien@cumulusnetworks.com
11 from collections
import OrderedDict
14 import ifupdown2
.nlmanager
.nlpacket
15 import ifupdown2
.ifupdown
.ifupdownflags
as ifupdownflags
17 from ifupdown2
.ifupdownaddons
.cache
import *
18 from ifupdown2
.ifupdownaddons
.utilsbase
import utilsBase
20 from ifupdown2
.nlmanager
.nlmanager
import Link
, Address
, Route
, NetlinkPacket
22 import nlmanager
.nlpacket
23 import ifupdown
.ifupdownflags
as ifupdownflags
25 from ifupdownaddons
.cache
import *
26 from ifupdownaddons
.utilsbase
import utilsBase
28 from nlmanager
.nlmanager
import Link
, Address
, Route
, NetlinkPacket
31 class Netlink(utilsBase
):
34 def __init__(self
, *args
, **kargs
):
35 utilsBase
.__init
__(self
, *args
, **kargs
)
37 sys
.path
.insert(0, '/usr/share/ifupdown2/')
39 from ifupdown2
.nlmanager
.nlmanager
import NetlinkManager
40 # Override the nlmanager's mac_int_to_str function to print the MACs
41 # like xx:xx:xx:xx:xx:xx instead of xxxx.xxxx.xxxx
42 ifupdown2
.nlmanager
.nlpacket
.mac_int_to_str
= self
.mac_int_to_str
44 from nlmanager
.nlmanager
import NetlinkManager
45 # Override the nlmanager's mac_int_to_str function to print the MACs
46 # like xx:xx:xx:xx:xx:xx instead of xxxx.xxxx.xxxx
47 nlmanager
.nlpacket
.mac_int_to_str
= self
.mac_int_to_str
49 # this should force the use of the local nlmanager
50 self
._nlmanager
_api
= NetlinkManager(log_level
=logging
.WARNING
)
52 self
.link_kind_handlers
= {
53 'vlan': self
._link
_dump
_info
_data
_vlan
,
54 'vrf': self
._link
_dump
_info
_data
_vrf
,
55 'vxlan': self
._link
_dump
_info
_data
_vxlan
,
56 'bond': self
._link
_dump
_info
_data
_bond
,
57 'bridge': self
._link
_dump
_info
_data
_bridge
60 except Exception as e
:
61 self
.logger
.error('cannot initialize ifupdown2\'s '
62 'netlink manager: %s' % str(e
))
68 /include/uapi/linux/in.h
70 #define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
71 #define IN_MULTICAST(a) IN_CLASSD(a)
73 return (int(a
) & 0xf0000000) == 0xe0000000
76 def mac_int_to_str(mac_int
):
78 Return an integer in MAC string format: xx:xx:xx:xx:xx:xx
80 return ':'.join(("%012x" % mac_int
)[i
:i
+ 2] for i
in range(0, 12, 2))
82 def get_iface_index(self
, ifacename
):
83 if ifupdownflags
.flags
.DRYRUN
: return
85 return self
._nlmanager
_api
.get_iface_index(ifacename
)
86 except Exception as e
:
87 raise Exception('%s: netlink: %s: cannot get ifindex: %s'
88 % (ifacename
, ifacename
, str(e
)))
90 def get_iface_name(self
, ifindex
):
91 if ifupdownflags
.flags
.DRYRUN
: return
93 return self
._nlmanager
_api
.get_iface_name(ifindex
)
94 except Exception as e
:
95 raise Exception('netlink: cannot get ifname for index %s: %s' % (ifindex
, str(e
)))
97 def get_bridge_vlan(self
, ifname
):
98 self
.logger
.info('%s: netlink: /sbin/bridge -d -c -json vlan show' % ifname
)
99 if ifupdownflags
.flags
.DRYRUN
: return
101 return self
._nlmanager
_api
.vlan_get()
102 except Exception as e
:
103 raise Exception('netlink: get bridge vlan: %s' % str(e
))
105 def bridge_set_vlan_filtering(self
, ifname
, vlan_filtering
):
106 self
.logger
.info('%s: netlink: ip link set dev %s type bridge vlan_filtering %s'
107 % (ifname
, ifname
, vlan_filtering
))
108 if ifupdownflags
.flags
.DRYRUN
: return
110 ifla_info_data
= {Link
.IFLA_BR_VLAN_FILTERING
: int(vlan_filtering
)}
111 return self
._nlmanager
_api
.link_set_attrs(ifname
, 'bridge', ifla_info_data
=ifla_info_data
)
112 except Exception as e
:
113 raise Exception('%s: cannot set %s vlan_filtering %s' % (ifname
, ifname
, vlan_filtering
))
115 def link_add_set(self
,
116 ifname
=None, ifindex
=0,
117 kind
=None, slave_kind
=None,
120 ifla_info_slave_data
={},
122 action
= 'set' if ifindex
or link_exists
else 'add'
125 self
.logger
.info('%s: netlink: ip link set dev %s: %s slave attributes' % (ifname
, ifname
, slave_kind
))
127 self
.logger
.info('%s: netlink: ip link %s %s type %s with attributes' % (ifname
, action
, ifname
, kind
))
129 self
.logger
.debug('%s: ifla attributes a %s' % (ifname
, ifla
))
131 self
.logger
.debug('%s: ifla_info_data %s' % (ifname
, ifla_info_data
))
132 if ifla_info_slave_data
:
133 self
.logger
.debug('%s: ifla_info_slave_data %s' % (ifname
, ifla_info_slave_data
))
135 if ifupdownflags
.flags
.DRYRUN
: return
137 self
._nlmanager
_api
.link_add_set(ifname
=ifname
,
140 slave_kind
=slave_kind
,
142 ifla_info_data
=ifla_info_data
,
143 ifla_info_slave_data
=ifla_info_slave_data
)
144 except Exception as e
:
145 if kind
and not slave_kind
:
147 elif kind
and slave_kind
:
148 kind_str
= '%s (%s slave)' % (kind
, slave_kind
)
150 kind_str
= '(%s slave)' % slave_kind
152 raise Exception('netlink: cannot %s %s %s with options: %s' % (action
, kind_str
, ifname
, str(e
)))
154 def link_del(self
, ifname
):
155 self
.logger
.info('%s: netlink: ip link del %s' % (ifname
, ifname
))
156 if ifupdownflags
.flags
.DRYRUN
: return
158 self
._nlmanager
_api
.link_del(ifname
=ifname
)
159 except Exception as e
:
160 raise Exception('netlink: cannot delete link %s: %s' % (ifname
, str(e
)))
162 def link_set_master(self
, ifacename
, master_dev
, state
=None):
163 self
.logger
.info('%s: netlink: ip link set dev %s master %s %s'
164 % (ifacename
, ifacename
, master_dev
,
165 state
if state
else ''))
166 if ifupdownflags
.flags
.DRYRUN
: return
168 master
= 0 if not master_dev
else self
.get_iface_index(master_dev
)
169 return self
._nlmanager
_api
.link_set_master(ifacename
,
170 master_ifindex
=master
,
172 except Exception as e
:
173 raise Exception('netlink: %s: cannot set %s master %s: %s'
174 % (ifacename
, ifacename
, master_dev
, str(e
)))
176 def link_set_nomaster(self
, ifacename
, state
=None):
177 self
.logger
.info('%s: netlink: ip link set dev %s nomaster %s'
178 % (ifacename
, ifacename
, state
if state
else ''))
179 if ifupdownflags
.flags
.DRYRUN
: return
181 return self
._nlmanager
_api
.link_set_master(ifacename
,
184 except Exception as e
:
185 raise Exception('netlink: %s: cannot set %s nomaster: %s'
186 % (ifacename
, ifacename
, str(e
)))
188 def link_add_vlan(self
, vlanrawdevice
, ifacename
, vlanid
, vlan_protocol
):
190 self
.logger
.info('%s: netlink: ip link add link %s name %s type vlan id %s protocol %s'
191 % (ifacename
, vlanrawdevice
, ifacename
, vlanid
, vlan_protocol
))
194 self
.logger
.info('%s: netlink: ip link add link %s name %s type vlan id %s'
195 % (ifacename
, vlanrawdevice
, ifacename
, vlanid
))
196 if ifupdownflags
.flags
.DRYRUN
: return
197 ifindex
= self
.get_iface_index(vlanrawdevice
)
199 return self
._nlmanager
_api
.link_add_vlan(ifindex
, ifacename
, vlanid
, vlan_protocol
)
200 except Exception as e
:
201 raise Exception('netlink: %s: cannot create vlan %s: %s'
202 % (vlanrawdevice
, vlanid
, str(e
)))
204 def link_add_macvlan(self
, ifacename
, macvlan_ifacename
):
205 self
.logger
.info('%s: netlink: ip link add link %s name %s type macvlan mode private'
206 % (ifacename
, ifacename
, macvlan_ifacename
))
207 if ifupdownflags
.flags
.DRYRUN
: return
208 ifindex
= self
.get_iface_index(ifacename
)
210 return self
._nlmanager
_api
.link_add_macvlan(ifindex
, macvlan_ifacename
)
211 except Exception as e
:
212 raise Exception('netlink: %s: cannot create macvlan %s: %s'
213 % (ifacename
, macvlan_ifacename
, str(e
)))
215 def link_set_updown(self
, ifacename
, state
):
216 self
.logger
.info('%s: netlink: ip link set dev %s %s'
217 % (ifacename
, ifacename
, state
))
218 if ifupdownflags
.flags
.DRYRUN
: return
220 return self
._nlmanager
_api
.link_set_updown(ifacename
, state
)
221 except Exception as e
:
222 raise Exception('netlink: cannot set link %s %s: %s'
223 % (ifacename
, state
, str(e
)))
225 def link_set_protodown(self
, ifacename
, state
):
226 self
.logger
.info('%s: netlink: set link %s protodown %s'
227 % (ifacename
, ifacename
, state
))
228 if ifupdownflags
.flags
.DRYRUN
: return
230 return self
._nlmanager
_api
.link_set_protodown(ifacename
, state
)
231 except Exception as e
:
232 raise Exception('netlink: cannot set link %s protodown %s: %s'
233 % (ifacename
, state
, str(e
)))
235 def link_add_bridge(self
, ifname
):
236 self
.logger
.info('%s: netlink: ip link add %s type bridge' % (ifname
, ifname
))
237 if ifupdownflags
.flags
.DRYRUN
: return
239 return self
._nlmanager
_api
.link_add_bridge(ifname
)
240 except Exception as e
:
241 raise Exception('netlink: cannot create bridge %s: %s' % (ifname
, str(e
)))
243 def link_add_bridge_vlan(self
, ifacename
, vlanid
):
244 self
.logger
.info('%s: netlink: bridge vlan add vid %s dev %s'
245 % (ifacename
, vlanid
, ifacename
))
246 if ifupdownflags
.flags
.DRYRUN
: return
247 ifindex
= self
.get_iface_index(ifacename
)
249 return self
._nlmanager
_api
.link_add_bridge_vlan(ifindex
, vlanid
)
250 except Exception as e
:
251 raise Exception('netlink: %s: cannot create bridge vlan %s: %s'
252 % (ifacename
, vlanid
, str(e
)))
254 def link_del_bridge_vlan(self
, ifacename
, vlanid
):
255 self
.logger
.info('%s: netlink: bridge vlan del vid %s dev %s'
256 % (ifacename
, vlanid
, ifacename
))
257 if ifupdownflags
.flags
.DRYRUN
: return
258 ifindex
= self
.get_iface_index(ifacename
)
260 return self
._nlmanager
_api
.link_del_bridge_vlan(ifindex
, vlanid
)
261 except Exception as e
:
262 raise Exception('netlink: %s: cannot remove bridge vlan %s: %s'
263 % (ifacename
, vlanid
, str(e
)))
265 def link_add_vxlan(self
, ifacename
, vxlanid
, local
=None, dstport
=VXLAN_UDP_PORT
,
266 group
=None, learning
=True, ageing
=None):
267 cmd
= 'ip link add %s type vxlan id %s dstport %s' % (ifacename
,
270 cmd
+= ' local %s' % local
if local
else ''
271 cmd
+= ' ageing %s' % ageing
if ageing
else ''
272 cmd
+= ' remote %s' % group
if group
else ' noremote'
273 cmd
+= ' nolearning' if not learning
else ''
274 self
.logger
.info('%s: netlink: %s' % (ifacename
, cmd
))
275 if ifupdownflags
.flags
.DRYRUN
: return
277 return self
._nlmanager
_api
.link_add_vxlan(ifacename
,
284 except Exception as e
:
285 raise Exception('netlink: %s: cannot create vxlan %s: %s'
286 % (ifacename
, vxlanid
, str(e
)))
289 def _link_dump_attr(link
, ifla_attributes
, dump
):
290 for obj
in ifla_attributes
:
291 attr
= link
.attributes
.get(obj
['attr'])
293 dump
[obj
['name']] = attr
.get_pretty_value(obj
=obj
.get('func'))
296 def _link_dump_linkdata_attr(linkdata
, ifla_linkdata_attr
, dump
):
297 for obj
in ifla_linkdata_attr
:
300 func
= obj
.get('func')
301 value
= linkdata
.get(attr
)
306 if value
or obj
['accept_none']:
307 dump
[obj
['name']] = value
311 'attr': Link
.IFLA_LINK
,
313 'func': lambda x
: netlink
.get_iface_name(x
) if x
> 0 else None
316 'attr': Link
.IFLA_MASTER
,
318 'func': lambda x
: netlink
.get_iface_name(x
) if x
> 0 else None
321 'attr': Link
.IFLA_IFNAME
,
326 'attr': Link
.IFLA_MTU
,
331 'attr': Link
.IFLA_OPERSTATE
,
333 'func': lambda x
: '0%x' % int(x
) if x
> len(Link
.oper_to_string
) else Link
.oper_to_string
[x
][8:]
337 ifla_address
= {'attr': Link
.IFLA_ADDRESS
, 'name': 'hwaddress', 'func': str}
339 ifla_vxlan_attributes
= [
341 'attr': Link
.IFLA_VXLAN_LOCAL
,
347 'attr': Link
.IFLA_VXLAN_LOCAL6
,
353 'attr': Link
.IFLA_VXLAN_GROUP
,
355 'func': lambda x
: str(x
) if not Netlink
.IN_MULTICAST(x
) else None,
359 'attr': Link
.IFLA_VXLAN_GROUP6
,
361 'func': lambda x
: str(x
) if not Netlink
.IN_MULTICAST(x
) else None,
365 'attr': Link
.IFLA_VXLAN_LEARNING
,
367 'func': lambda x
: 'on' if x
else 'off',
372 def _link_dump_info_data_vlan(self
, ifname
, linkdata
):
374 'vlanid': str(linkdata
.get(Link
.IFLA_VLAN_ID
, '')),
375 'vlan_protocol': linkdata
.get(Link
.IFLA_VLAN_PROTOCOL
)
378 def _link_dump_info_data_vrf(self
, ifname
, linkdata
):
379 vrf_info
= {'table': str(linkdata
.get(Link
.IFLA_VRF_TABLE
, ''))}
381 # to remove later when moved to a true netlink cache
382 linkCache
.vrfs
[ifname
] = vrf_info
385 def _link_dump_info_data_vxlan(self
, ifname
, linkdata
):
389 ('vxlanid', str(linkdata
.get(Link
.IFLA_VXLAN_ID
, ''))),
390 ('ageing', str(linkdata
.get(Link
.IFLA_VXLAN_AGEING
, ''))),
391 (Link
.IFLA_VXLAN_PORT
, linkdata
.get(Link
.IFLA_VXLAN_PORT
))
393 linkdata
[attr
] = value
394 self
._link
_dump
_linkdata
_attr
(linkdata
, self
.ifla_vxlan_attributes
, linkdata
)
397 ifla_bond_attributes
= (
399 Link
.IFLA_BOND_MIIMON
,
400 Link
.IFLA_BOND_USE_CARRIER
,
401 Link
.IFLA_BOND_AD_LACP_RATE
,
402 Link
.IFLA_BOND_XMIT_HASH_POLICY
,
403 Link
.IFLA_BOND_MIN_LINKS
,
404 Link
.IFLA_BOND_NUM_PEER_NOTIF
,
405 Link
.IFLA_BOND_AD_ACTOR_SYSTEM
,
406 Link
.IFLA_BOND_AD_ACTOR_SYS_PRIO
,
407 Link
.IFLA_BOND_AD_LACP_BYPASS
,
408 Link
.IFLA_BOND_UPDELAY
,
409 Link
.IFLA_BOND_DOWNDELAY
,
412 def _link_dump_info_data_bond(self
, ifname
, linkdata
):
414 for nl_attr
in self
.ifla_bond_attributes
:
416 linkinfo
[nl_attr
] = linkdata
.get(nl_attr
)
417 except Exception as e
:
418 self
.logger
.debug('%s: parsing bond IFLA_INFO_DATA (%s): %s'
419 % (ifname
, nl_attr
, str(e
)))
422 # this dict contains the netlink attribute, cache key,
423 # and a callable to translate the netlink value into
424 # whatever value we need to store in the old cache to
425 # make sure we don't break anything
426 ifla_bridge_attributes
= (
427 (Link
.IFLA_BR_UNSPEC
, Link
.IFLA_BR_UNSPEC
, None),
428 (Link
.IFLA_BR_FORWARD_DELAY
, "fd", lambda x
: str(x
/ 100)),
429 (Link
.IFLA_BR_HELLO_TIME
, "hello", lambda x
: str(x
/ 100)),
430 (Link
.IFLA_BR_MAX_AGE
, "maxage", lambda x
: str(x
/ 100)),
431 (Link
.IFLA_BR_AGEING_TIME
, "ageing", lambda x
: str(x
/ 100)),
432 (Link
.IFLA_BR_STP_STATE
, "stp", lambda x
: 'yes' if x
else 'no'),
433 (Link
.IFLA_BR_PRIORITY
, "bridgeprio", str),
434 (Link
.IFLA_BR_VLAN_FILTERING
, 'vlan_filtering', str),
435 (Link
.IFLA_BR_VLAN_PROTOCOL
, "vlan-protocol", str),
436 (Link
.IFLA_BR_GROUP_FWD_MASK
, Link
.IFLA_BR_GROUP_FWD_MASK
, None),
437 (Link
.IFLA_BR_ROOT_ID
, Link
.IFLA_BR_ROOT_ID
, None),
438 (Link
.IFLA_BR_BRIDGE_ID
, Link
.IFLA_BR_BRIDGE_ID
, None),
439 (Link
.IFLA_BR_ROOT_PORT
, Link
.IFLA_BR_ROOT_PORT
, None),
440 (Link
.IFLA_BR_ROOT_PATH_COST
, Link
.IFLA_BR_ROOT_PATH_COST
, None),
441 (Link
.IFLA_BR_TOPOLOGY_CHANGE
, Link
.IFLA_BR_TOPOLOGY_CHANGE
, None),
442 (Link
.IFLA_BR_TOPOLOGY_CHANGE_DETECTED
, Link
.IFLA_BR_TOPOLOGY_CHANGE_DETECTED
, None),
443 (Link
.IFLA_BR_HELLO_TIMER
, Link
.IFLA_BR_HELLO_TIMER
, None),
444 (Link
.IFLA_BR_TCN_TIMER
, Link
.IFLA_BR_TCN_TIMER
, None),
445 (Link
.IFLA_BR_TOPOLOGY_CHANGE_TIMER
, Link
.IFLA_BR_TOPOLOGY_CHANGE_TIMER
, None),
446 (Link
.IFLA_BR_GC_TIMER
, Link
.IFLA_BR_GC_TIMER
, None),
447 (Link
.IFLA_BR_GROUP_ADDR
, Link
.IFLA_BR_GROUP_ADDR
, None),
448 (Link
.IFLA_BR_FDB_FLUSH
, Link
.IFLA_BR_FDB_FLUSH
, None),
449 (Link
.IFLA_BR_MCAST_ROUTER
, "mcrouter", str),
450 (Link
.IFLA_BR_MCAST_SNOOPING
, "mcsnoop", str),
451 (Link
.IFLA_BR_MCAST_QUERY_USE_IFADDR
, "mcqifaddr", str),
452 (Link
.IFLA_BR_MCAST_QUERIER
, "mcquerier", str),
453 (Link
.IFLA_BR_MCAST_HASH_ELASTICITY
, "hashel", str),
454 (Link
.IFLA_BR_MCAST_HASH_MAX
, "hashmax", str),
455 (Link
.IFLA_BR_MCAST_LAST_MEMBER_CNT
, "mclmc", str),
456 (Link
.IFLA_BR_MCAST_STARTUP_QUERY_CNT
, "mcsqc", str),
457 (Link
.IFLA_BR_MCAST_LAST_MEMBER_INTVL
, "mclmi", lambda x
: str(x
/ 100)),
458 (Link
.IFLA_BR_MCAST_MEMBERSHIP_INTVL
, "mcmi", lambda x
: str(x
/ 100)),
459 (Link
.IFLA_BR_MCAST_QUERIER_INTVL
, "mcqpi", lambda x
: str(x
/ 100)),
460 (Link
.IFLA_BR_MCAST_QUERY_INTVL
, "mcqi", lambda x
: str(x
/ 100)),
461 (Link
.IFLA_BR_MCAST_QUERY_RESPONSE_INTVL
, "mcqri", lambda x
: str(x
/ 100)),
462 (Link
.IFLA_BR_MCAST_STARTUP_QUERY_INTVL
, "mcsqi", lambda x
: str(x
/ 100)),
463 (Link
.IFLA_BR_NF_CALL_IPTABLES
, Link
.IFLA_BR_NF_CALL_IPTABLES
, None),
464 (Link
.IFLA_BR_NF_CALL_IP6TABLES
, Link
.IFLA_BR_NF_CALL_IP6TABLES
, None),
465 (Link
.IFLA_BR_NF_CALL_ARPTABLES
, Link
.IFLA_BR_NF_CALL_ARPTABLES
, None),
466 (Link
.IFLA_BR_VLAN_DEFAULT_PVID
, Link
.IFLA_BR_VLAN_DEFAULT_PVID
, None),
467 (Link
.IFLA_BR_PAD
, Link
.IFLA_BR_PAD
, None),
468 (Link
.IFLA_BR_VLAN_STATS_ENABLED
, "vlan-stats", str),
469 (Link
.IFLA_BR_MCAST_STATS_ENABLED
, "mcstats", str),
470 (Link
.IFLA_BR_MCAST_IGMP_VERSION
, "igmp-version", str),
471 (Link
.IFLA_BR_MCAST_MLD_VERSION
, "mld-version", str)
474 def _link_dump_info_data_bridge(self
, ifname
, linkdata
):
476 for nl_attr
, cache_key
, func
in self
.ifla_bridge_attributes
:
479 linkinfo
[cache_key
] = func(linkdata
.get(nl_attr
))
481 linkinfo
[cache_key
] = linkdata
.get(nl_attr
)
483 # we also store the value in pure netlink,
484 # to make the transition easier in the future
485 linkinfo
[nl_attr
] = linkdata
.get(nl_attr
)
486 except Exception as e
:
487 self
.logger
.error('%s: parsing birdge IFLA_INFO_DATA %s: %s'
488 % (ifname
, nl_attr
, str(e
)))
491 def _link_dump_info_slave_data_bridge(self
, ifname
, info_slave_data
):
492 return info_slave_data
494 def _link_dump_linkinfo(self
, link
, dump
):
495 linkinfo
= link
.attributes
[Link
.IFLA_LINKINFO
].get_pretty_value(dict)
498 info_kind
= linkinfo
.get(Link
.IFLA_INFO_KIND
)
499 info_data
= linkinfo
.get(Link
.IFLA_INFO_DATA
)
501 info_slave_kind
= linkinfo
.get(Link
.IFLA_INFO_SLAVE_KIND
)
502 info_slave_data
= linkinfo
.get(Link
.IFLA_INFO_SLAVE_DATA
)
504 dump
['kind'] = info_kind
505 dump
['slave_kind'] = info_slave_kind
508 link_kind_handler
= self
.link_kind_handlers
.get(info_kind
)
509 if callable(link_kind_handler
):
510 dump
['linkinfo'] = link_kind_handler(dump
['ifname'], info_data
)
513 dump
['info_slave_data'] = info_slave_data
515 def link_dump(self
, ifname
=None):
517 self
.logger
.info('netlink: ip link show dev %s' % ifname
)
519 self
.logger
.info('netlink: ip link show')
521 if ifupdownflags
.flags
.DRYRUN
: return {}
526 links_dump
= self
._nlmanager
_api
.link_dump(ifname
)
527 except Exception as e
:
528 raise Exception('netlink: link dump failed: %s' % str(e
))
530 for link
in links_dump
:
535 for flag
, string
in Link
.flag_to_string
.items():
536 if link
.flags
& flag
:
537 flags
.append(string
[4:])
539 dump
['flags'] = flags
540 dump
['ifflag'] = 'UP' if 'UP' in flags
else 'DOWN'
541 dump
['ifindex'] = str(link
.ifindex
)
543 if link
.device_type
== Link
.ARPHRD_ETHER
:
544 self
._link
_dump
_attr
(link
, [self
.ifla_address
], dump
)
546 self
._link
_dump
_attr
(link
, self
.ifla_attributes
, dump
)
548 if Link
.IFLA_LINKINFO
in link
.attributes
:
549 self
._link
_dump
_linkinfo
(link
, dump
)
551 links
[dump
['ifname']] = dump
552 except Exception as e
:
553 self
.logger
.warning('netlink: ip link show: %s' % str(e
))
556 def _addr_dump_extract_ifname(self
, addr_packet
):
557 addr_ifname_attr
= addr_packet
.attributes
.get(Address
.IFA_LABEL
)
560 return addr_ifname_attr
.get_pretty_value(str)
562 return self
.get_iface_name(addr_packet
.ifindex
)
565 def _addr_filter(addr_ifname
, addr
):
566 return addr_ifname
== 'lo' and addr
in ['127.0.0.1/8', '::1/128', '0.0.0.0']
568 def _addr_dump_entry(self
, ifaces
, addr_packet
, addr_ifname
, ifa_attr
):
569 attribute
= addr_packet
.attributes
.get(ifa_attr
)
572 address
= attribute
.get_pretty_value(str)
574 if hasattr(addr_packet
, 'prefixlen'):
575 address
= '%s/%d' % (address
, addr_packet
.prefixlen
)
577 if self
._addr
_filter
(addr_ifname
, address
):
580 addr_family
= NetlinkPacket
.af_family_to_string
.get(addr_packet
.family
)
584 ifaces
[addr_ifname
]['addrs'][address
] = {
586 'scope': addr_packet
.scope
589 ifa_address_attributes
= [
592 Address
.IFA_BROADCAST
,
594 Address
.IFA_MULTICAST
597 def addr_dump(self
, ifname
=None):
599 self
.logger
.info('netlink: ip addr show dev %s' % ifname
)
601 self
.logger
.info('netlink: ip addr show')
604 addr_dump
= self
._nlmanager
_api
.addr_dump()
606 for addr_packet
in addr_dump
:
607 addr_ifname
= self
._addr
_dump
_extract
_ifname
(addr_packet
)
609 if addr_packet
.family
not in [socket
.AF_INET
, socket
.AF_INET6
]:
612 if ifname
and ifname
!= addr_ifname
:
615 if addr_ifname
not in ifaces
:
616 ifaces
[addr_ifname
] = {'addrs': OrderedDict({})}
618 for ifa_attr
in self
.ifa_address_attributes
:
619 self
._addr
_dump
_entry
(ifaces
, addr_packet
, addr_ifname
, ifa_attr
)
622 return {ifname
: ifaces
.get(ifname
, {})}