
    /I_/                       S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SKrS SKJ	r	J
r
  S SKJr   S SKJr  S SKJr  S SKJrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJ r J!r!J"r"J#r#  S SK$J%s  J&r&  S SKJ%s  J'r'  S SK(J%s  J)r)  S SK*J%s  J%r%  S SK+J,s  J-r-  \Rn                  " 5       r8 " S S\95      r: " S	 S
\95      r; " S S\95      r< " S S\<5      r= " S S\<5      r> " S S5      r? " S S\)R                  \5      rAg! \.\/4 aW    S SK0Jr  S SK1Jr  S SK2JrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJ r J!r!J"r"J#r#  S SK3J&r&  S SK2J'r'  S SK4J)r)  S SK5J%r%  S SK6J-r-   Nf = f)    N)DEBUGWARNING)OrderedDict)Sysfs)
BaseObject)AddressNetconfLinkRouteAF_MPLSNetlinkPacketNLM_F_REQUESTRTM_NEWLINKRTM_SETLINKRTM_DELLINKRTM_NEWADDRRTM_DELADDR
RTMGRP_ALL
NLMSG_DONEr   NLM_F_CREATE	NLM_F_ACK	RT_SCOPESINFINITY_LIFE_TIMEc                       \ rS rSrSrSrg)+NetlinkListenerWithCacheErrorNotInitializedi   zf
If NetlinkListenerWithCache fails on __init__() or / start()
we need to raise this custom exception.
 N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       #/usr/share/ifupdown2/lib/nlcache.pyr   r   i   s     	r$   r   c                   ,   ^  \ rS rSrSU 4S jjrSrU =r$ )NetlinkErrorq   c                    > S/nU(       a  UR                  U5        U(       a  UR                  U5        UR                  [        U5      5        [        [        U ]  SR                  U5      5        g )Nnetlink: )appendstrsuperr'   __init__join)self	exceptionprefixifnamenetlink_exception_message	__class__s        r%   r/   NetlinkError.__init__r   sX    %.K!%,,V4%,,V4!((Y8lD*4995N+OPr$   r   NN)r   r   r    r!   r/   r#   __classcell__r6   s   @r%   r'   r'   q   s    
Q 
Qr$   r'   c                       \ rS rSrSrg)NetlinkCacheError   r   Nr   r   r    r!   r#   r   r$   r%   r<   r<          r$   r<   c                       \ rS rSrSrg)NetlinkCacheIfnameNotFoundError   r   Nr>   r   r$   r%   rA   rA      r?   r$   rA   c                       \ rS rSrSrg) NetlinkCacheIfindexNotFoundError   r   Nr>   r   r$   r%   rD   rD      r?   r$   rD   c                      \ rS rSrSr\R                  \R                  \R                  \R                  \R                  \R                  4rS rS rSbS jrS rS rS	 rS
 rS rS rS rS rS rS rScS jrS rS rS rS rS rS r S r!S r"S r#S r$S r%S r&S r'S r(S  r)S! r*SbS" jr+SbS# jr,S$ r-SbS% jr.S& r/SbS' jr0S( r1S) r2S* r3S+ r4S, r5S- r6S. r7S/ r8S0 r9S1 r:S2 r;S3 r<S4 r=S5 r>S6 r?S7 r@S8 rAS9 rBS: rCS; rDS< rES= rFS> rGS? rHS@ rISA rJSB rKSC rLSD rMSE rNSF rOSG rPSdSH jrQSI rR\SSJ 5       rTSK rUSL rVSM rWSN rXSO rYSP\ZSQ\[4SR jr\SS r]ST r^SU r_SV r`SW ra\SScSX\[SQ\[4SY jj5       rbScSP\ZSX\[SZ\c4S[ jjrdS\ reS] rfS^ rgS_ rhS` riSarjg)e_NetlinkCache   zNetlink Cache Class c                 n   [         U l        X R                  l        0 U l        0 U l        0 U l        0 U l        0 U l        0 U l        0 U l	        0 U l
        0 U l        0 U l        [        R                  0 [        R                  0 [         0 0U l        [$        R&                  " 5       U l        [$        R*                  " 5       U l        [/        5       U l        [$        R&                  " 5       U l        [/        5       U l        [$        R&                  " 5       U l        S U l        [$        R:                  " 5       U l        g N)r   _NetlinkCache__sysfscache_link_cache_addr_cache_bridge_vlan_cache_bridge_vlan_vni_cache_ifname_by_ifindex_ifindex_by_ifname_ifname_by_ifindex_sysfs_ifindex_by_ifname_sysfs_masters_and_slaves_slaves_mastersocketAF_INETAF_INET6r   _netconf_cache	threadingLock_netconf_cache_lockRLock_cache_locklist_ignore_rtm_newlinkq_ignore_rtm_newlinkq_lock_rtm_newlink_nomasterq_rtm_newlink_nomasterq_lock_wait_eventEvent_wait_event_alarmr1   s    r%   r/   _NetlinkCache.__init__   s    !"$&(#
 $&#%(*%(*% $&  ! NNBOORR
 $->>#3  %??,$ %)F!)2)9&  '+f#+4>>+;(,  !*!2r$   c           
      Z    [         R                  SU< SU< S[        U5      < 35        U$ )zO
TypeError shouldn't happen but if it does, we are prepared to log and recover
z	nlcache: r+   z: TypeError: )logdebugr-   )r1   	func_namedatar2   return_values        r%   __handle_type_error!_NetlinkCache.__handle_type_error  s!     			is9~VWr$   Nc                 :    U R                   U   R                  [        R                  	  U(       d  U R
                  U   nU R                  U   R                  U5         U R
                  U	  U R                  U	  U R                  U	 g! [         a     Nlf = f! [        [        4 a@    U R                  R                  5        H  u  p#X;   d  M  UR                  U5           M      Nf = f! [         a     Nf = f! [         a     Nf = f! [         a     gf = f)a[  
WARNING: LOCK SHOULD BE ACQUIRED BEFORE CALLING THIS FUNCTION

When unslaving a device we need to manually clear and update our internal
data structures to avoid keeping stale information before receiving a proper
netlink notification.

Dictionaries:
- master_and_slaves
- slaves_master
- bridge_vlan_cache

:param master:
:param slave:
:return:
N)rM   
attributesr
   IFLA_MASTER	ExceptionrV   rU   removeKeyError
ValueErroritemsrO   rP   )r1   slavemaster
slaves_sets       r%   __unslave_nolock_NetlinkCache.__unslave_nolock  s&   "	  '2243C3CD		,,U3$$V,33E:	##E*	''.	++E23  		 *% 	&*&>&>&D&D&F"&%%e, 'G	  		
  		
  		sd   (B
 4B  C- .C= <D 

BB2C*C*%C*)C*-
C:9C:=
D
	D

DDc                     U R                      U R                  R                  U5        SSS5        g! , (       d  f       g= f)z
Register device 'ifname' to the ignore_rtm_newlinkq list pending
RTM_DELLINK (see comments above _ignore_rtm_newlinkq declaration)
N)rb   ra   r,   r1   r4   s     r%   append_to_ignore_rtm_newlinkq+_NetlinkCache.append_to_ignore_rtm_newlinkq;  s-    
 ++%%,,V4 ,++	   2
A c                      U R                      U R                  R                  U5        SSS5        g! , (       d  f       g= f! [         a     gf = f)z,Unregister ifname from ignore_newlinkq list N)rb   ra   rv   rx   r   s     r%   remove_from_ignore_rtm_newlinkq-_NetlinkCache.remove_from_ignore_rtm_newlinkqC  sA    	//))008 0// 		*   A 3A 
AA A 
AAc                     U R                      U R                  R                  U5        SSS5        g! , (       d  f       g= f)z>Register device 'ifname' to the _ignore_rtm_newlink_nomasterq N)rd   rc   r,   r   s     r%   append_to_rtm_newlink_nomasterq-_NetlinkCache.append_to_rtm_newlink_nomasterqK  s+    --''..v6 .--r   c                      U R                      U R                  R                  U5        SSS5        g! , (       d  f       g= f! [         a     gf = f)z:Unregister ifname from _ignore_rtm_newlink_nomasterq list N)rd   rc   rv   rx   r   s     r%   !remove_from_rtm_newlink_nomasterq/_NetlinkCache.remove_from_rtm_newlink_nomasterqP  sA    	11++226: 211 		r   c                     U R                      U R                  (       a
   SSS5        gX4U l        SSS5        g! , (       d  f       g= f)a  
Register a cache "wait event" for device named 'ifname' and packet
type msgtype

We only one wait_event to be registered. Currently we don't support
multi-threaded application so we need to had a strict check. In the
future we could have a wait_event queue for multiple thread could
register wait event.
:param ifname: target device
:param msgtype: netlink message type (RTM_NEWLINK, RTM_DELLINK etc.)
:return: boolean: did we successfully register a wait_event?
NFT)r_   re   )r1   r4   msgtypes      r%   register_wait_event!_NetlinkCache.register_wait_eventX  sF       !'0D  	  s   ::
Ac                    U R                   R                  S5      (       dk  [        R                  SU R                  S   < S[
        R                  R                  U R                  S   [        U R                  S   5      5      < 35        U R                     SU l        U R                   R                  5         SSS5        g! , (       d  f       g= f)z
Sleep until cache event happened in netlinkq thread or timeout expired
:return: None

We set an arbitrary timeout at 1sec in case the kernel doesn't send
out a notification for the event we want to wait for.
   z6nlcache: wait event alarm timeout expired for device "r   z" and netlink packet type: N)rg   waitrk   rl   re   r   type_to_stringgetr-   r_   clearrh   s    r%   
wait_event_NetlinkCache.wait_eventk  s     %%**1--II))!,m.J.J.N.NtO_O_`aObdghlhxhxyzh{d|.} @#D""((* s   "C
Cc                     U R                      SU l        U R                  R                  5         SSS5        g! , (       d  f       g= f)zG
Clear current wait event (cache can only handle one at once)
:return:
N)r_   re   rg   r   rh   s    r%   unregister_wait_event#_NetlinkCache.unregister_wait_eventz  s3    
 #D""((* s	   "8
Ac                      U R                      X R                  U   l        S S S 5        g ! , (       d  f       g = f! [         a     g f = frJ   )r_   rM   flagsru   )r1   r4   r   s      r%   override_link_flag _NetlinkCache.override_link_flag  s>    	!!16  (. "!! 		s#   < +< 
9< < 
A	A	c                      U R                      X R                  U   R                  [        R                     l        SSS5        g! , (       d  f       g= f! [         a     gf = f)zX
Manually override link mtu and ignore any failures
:param ifname:
:param mtu:
:return:
N)r_   rM   rs   r
   IFLA_MTUvalueru   )r1   r4   mtus      r%   override_link_mtu_NetlinkCache.override_link_mtu  sM    	!!KN  (33DMMBH "!! 		s-   A /AA 
AA A 
A$#A$c                 r    U R                      U R                  X5        SSS5        g! , (       d  f       g= f)a  
Manually update the cache unslaving SLAVE from MASTER

When calling link_set_nomaster, we don't want to wait for the RTM_GETLINK
notification - if the operation return with NL_SUCCESS we can manually
update our cache and move on.

:param master:
:param slave:
:return:
N)r_   _NetlinkCache__unslave_nolockr1   rz   r{   s      r%   override_cache_unslave_link)_NetlinkCache.override_cache_unslave_link  s'     !!%0 s   (
6c                    SSK nUR                  " 5       nUR                  n UR                  [        5        UR
                   H  nUR                  [        5        M     [        R                  R                  [        5        [        R                  R                  [        5        [        R                  R                  [        5        U R                     U R                  U   nUR                  nSUl        UR                  5         Xl        SSS5        [        R                  R                  ["        5        [        R                  R                  ["        5        [        R                  R                  ["        5        UR                  U5        UR
                   H  nUR                  U5        M     g! , (       d  f       N= f! [         a    [        R                   " 5          Nf = f)zi
A very useful function to use while debugging, it dumps the netlink
packet with debug and color output.
r   NT)logging	getLoggerlevelsetLevelr   handlers
nllistenerrk   nlpacket	nlmanagerr_   rM   rl   dumpru   	traceback	print_excr   )	r1   r4   with_addressesr   rootr   handlerobj
save_debugs	            r%   DEBUG_IFNAME_NetlinkCache.DEBUG_IFNAME  sD   
 	  "

	"MM% ==  ' ) NN##E*LL!!%(MM""5)!!&&v. YY
 	
&	 "* 	(g&w'e}}GU# %5 "!$  	"!	"s0   B2G 9F5G 5
G?G G G('G(c                 l   SS K nUR                  " 5       nUR                  n UR                  [        5        UR
                   H  nUR                  [        5        M     [        R                  R                  [        5        [        R                  R                  [        5        [        R                  R                  [        5        UR                  nSUl
        UR                  5         Xal
        [        R                  R                  [        5        [        R                  R                  [        5        [        R                  R                  [        5        UR                  U5        UR
                   H  nUR                  U5        M     g ! [         a    [        R                  " 5          Nf = f)Nr   T)r   r   r   r   r   r   r   rk   r   r   rl   r   ru   r   r   r   )r1   msgr   r   r   r   r   s          r%   	DEBUG_MSG_NetlinkCache.DEBUG_MSG  s     "

	"MM% ==  ' ) NN##E*LL!!%(MM""5)JCIHHJ"I 	(g&w'e}}GU# %  	"!	"s   CF F32F3c                    0 n0 n [         R                  " S5       H<  n [        SU-  5       n[        UR	                  5       5      nX1U'   XRU'   S S S 5        M>     U R                     Xl	        X l
        S S S 5        g ! , (       d  f       Mq  = f! [
        [        4 a     M  f = f! [         a     NWf = f! , (       d  f       g = f)Nz/sys/class/net/z/sys/class/net/%s/ifindex)oslistdiropenintreadlineIOErrorrx   OSErrorr_   rS   rT   )r1   ifname_by_ifindex_dictifindex_by_ifname_dictdir_namefifindexs         r%   $_populate_sysfs_ifname_ifindex_dicts2_NetlinkCache._populate_sysfs_ifname_ifindex_dicts  s    !#!#
	JJ'899HDE"%ajjl"3:Bw7;Bx8 FE : ,B),B)  FE  ,  		sc   B' B"A>BB' (B7>
B	BB' BB$ B' #B$$B' '
B43B47
Cc                     U R                      U R                  U   sSSS5        $ ! , (       d  f       g= f! [         a    U R                      U R                  R	                  U5      nSSS5        O! , (       d  f       O= fW(       a  Us $ U R                  5          U R                  U   s $ ! [         a    [        SU-  5      ef = ff = f)z
Return device index or raise NetlinkCacheIfnameNotFoundError
:param ifname:
:return: int
:raise: NetlinkCacheIfnameNotFoundError(NetlinkCacheError)
Nzifname %s not present in cache)r_   rR   rw   rT   r   r   rA   r1   r4   r   s      r%   get_ifindex_NetlinkCache.get_ifindex  s    	a!!..v6 "!! 	a
 !!77;;FC "!! 557a44V<< a 66VY_6_``a	aS   8 '	8 
58 8 CA3*	C3
B	=CC B1.C1C

Cc                     U R                      U R                  U   sSSS5        $ ! , (       d  f       g= f! [         a    U R                      U R                  R	                  U5      nSSS5        O! , (       d  f       O= fW(       a  Us $ U R                  5          U R                  U   s $ ! [         a    [        SU-  5      ef = ff = f)z
Return device name or raise NetlinkCacheIfindexNotFoundError
:param ifindex:
:return: str
:raise: NetlinkCacheIfindexNotFoundError (NetlinkCacheError)
Nzifindex %s not present in cache)r_   rQ   rw   rS   r   r   rD   )r1   r   r4   s      r%   
get_ifname_NetlinkCache.get_ifname!  s    	d!!..w7 "!! 	d
 !!66::7C "!! 557d44W== d 77X[b7bccd	dr   c                 l    U R                      XR                  ;   sSSS5        $ ! , (       d  f       g= f)z`
Check if we have a cache entry for device 'ifname'
:param ifname: device name
:return: boolean
N)r_   rM   r   s     r%   link_exists_NetlinkCache.link_exists=  s%     --- s   %
3c                 z    U R                      U R                  U   R                  [        R                  -  sSSS5        $ ! , (       d  f       g= f! [
        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      SS9s SnA$ SnAff = f)zJ
Check if device 'ifname' has IFF_UP flag
:param ifname:
:return: boolean
NFro   r_   rM   r   r
   IFF_UPrw   	TypeError _NetlinkCache__handle_type_errorinspectcurrentframef_codeco_namer-   r1   r4   es      r%   
link_is_up_NetlinkCache.link_is_upF  s    	w!!''/55C "!!)$ 	 	w++G,@,@,B,I,I,Q,QSY[^_`[apu+vv	w@   A *A	A 
AA A B:%	B:.AB5/B:5B:c                 z    U R                      U R                  U   R                  [        R                  -  sSSS5        $ ! , (       d  f       g= f! [
        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      SS9s SnA$ SnAff = f)zG
Check if device has IFF_LOOPBACK flag
:param ifname:
:return: boolean
NFr   )r_   rM   r   r
   IFF_LOOPBACKrw   AttributeErrorr   r   r   r   r   r   r-   r   s      r%   link_is_loopback_NetlinkCache.link_is_loopbackU  s    	w!!''/558I8II "!! .) 	 	w++G,@,@,B,I,I,Q,QSY[^_`[apu+vv	wr   c                 r    U R                      SU R                  U   R                  [        R                  -  4sSSS5        $ ! , (       d  f       g= f! [
         a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      SS9s SnA$ SnAff = f)z~
Check if device exists and has IFF_UP flag set
:param ifname:
:return: tuple (boolean, boolean) -> (link_exists, link_is_up)
TN)FFr   r   r   s      r%   link_exists_and_up _NetlinkCache.link_exists_and_upe  s    	@!!T--f5;;dkkII "!! 	  	@++G,@,@,B,I,I,Q,QSY[^_`[ap~+	@s@   A ,A	A 
AA A 
B6!	B6*AB1+B61B6c                 *    U R                  U5      S:H  $ )Nbridge)get_link_kindr   s     r%   link_is_bridge_NetlinkCache.link_is_bridget  s    !!&)X55r$   c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     sSSS5        $ ! , (       d  f       g= f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      SS9s SnA$ SnAff = f)z;
Return link IFLA_INFO_KIND
:param ifname:
:return: string
Nr   r_   rM   rs   r
   IFLA_LINKINFOr   IFLA_INFO_KINDrw   r   r   r   r   r   r   r   r-   r   s      r%   r   _NetlinkCache.get_link_kindw  s    	v!!''/::4;M;MNTTUYUhUhi "!!.) 	 	v++G,@,@,B,I,I,Q,QSY[^_`[apt+uu	vB   A. AA	A. 
A+'A. +A. .C 	C	AC
CCc                 @    U R                  U[        R                  SS9$ )z2
Return link IFLA_MTU
:param ifname:
:return: int
r   default)get_link_attributer
   r   r   s     r%   get_link_mtu_NetlinkCache.get_link_mtu  s      &&vt}}a&HHr$   c                 6    [        U R                  U5      5      $ )z<
Return link IFLA_MTU as string
:param ifname:
:return: str
)r-   r  r   s     r%   get_link_mtu_str_NetlinkCache.get_link_mtu_str  s     4$$V,--r$   c                 6   SnSn U R                      U R                  U   nUR                  [        R                     R
                  R                  5       sSSS5        $ ! , (       d  f       g= f! [        [        4 aA    U(       a5  UR                  [        -  (       a  U R                  R                  U5      s $ Us $ [         aN  nU R                  [        R                   " 5       R"                  R$                  U['        U5      U5      s SnA$ SnAff = f)z6
Return link IFLA_ADDRESS
:param ifname:
:return: str
N )r_   rM   rs   r
   IFLA_ADDRESSr   lowerrw   r   
priv_flagsr   rK   get_link_addressr   r   r   r   r   r   r-   )r1   r4   packetdefault_valuer   s        r%   r  _NetlinkCache.get_link_address  s     	r!!))&1(():):;AAGGI "!! .) 
	% &++m;||44V<<$$ 	r++G,@,@,B,I,I,Q,QSY[^_`[acpqq	rsI   A1 AA 	A1  
A.*A1 .A1 1A
D=D	D
ADDDc                 @    U R                  U[        R                  SS9$ )zA
Return link IFLA_ADDRESS as integer
:param ifname:
:return: int
r   r   )get_link_attribute_rawr
   r
  r   s     r%   get_link_address_raw"_NetlinkCache.get_link_address_raw  s"     **643D3Da*PPr$   c                 B    U R                  U[        R                  5      $ )z6
Return link IFLA_IFALIAS
:param ifname:
:return: str
)r  r
   IFLA_IFALIASr   s     r%   get_link_alias_NetlinkCache.get_link_alias  s     &&vt/@/@AAr$   c                 B    U R                  U[        R                  5      $ )z9
Return link IFLA_PROTO_DOWN
:param ifname:
:return: int
)r  r
   IFLA_PROTO_DOWNr   s     r%   get_link_protodown _NetlinkCache.get_link_protodown  s     &&vt/C/CDDr$   c                 v    U R                      U R                  U   R                  U   R                  sSSS5        $ ! , (       d  f       g= f! [        [
        4 a    Us $ [         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      US9s SnA$ SnAff = f)zY
Return link attribute 'attr'.value
:param ifname:
:param attr:
:param default:
:return:
Nr   )r_   rM   rs   r   rw   r   r   r   r   r   r   r   r-   r1   r4   attrr  r   s        r%   r   _NetlinkCache.get_link_attribute  s    	y!!''/::4@FF "!!.) 	N 	y++G,@,@,B,I,I,Q,QSY[^_`[apw+xx	y>   A &>	A 
AA A B8#	B8,AB3-B83B8c                 v    U R                      U R                  U   R                  U   R                  sSSS5        $ ! , (       d  f       g= f! [        [
        4 a    Us $ [         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      US9s SnA$ SnAff = f)zW
Return link attribute 'attr'.raw
:param ifname:
:param attr:
:param default:
:return:
Nr   )r_   rM   rs   rawrw   r   r   r   r   r   r   r   r-   r  s        r%   r  $_NetlinkCache.get_link_attribute_raw  s    	y!!''/::4@DD "!!.) 	N 	y++G,@,@,B,I,I,Q,QSY[^_`[apw+xx	yr!  c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     sSSS5        $ ! , (       d  f       g= f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      SS9s SnA$ SnAff = f)z6
Return device slave kind
:param ifname:
:return: str
Nr   r_   rM   rs   r
   r   r   IFLA_INFO_SLAVE_KINDrw   r   r   r   r   r   r   r   r-   r   s      r%   get_link_slave_kind!_NetlinkCache.get_link_slave_kind  s    	v!!''/::4;M;MNTTUYUnUno "!!.) 	 	v++G,@,@,B,I,I,Q,QSY[^_`[apt+uu	vr   c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     U   sSSS5        $ ! , (       d  f       g= f! [        [        4 a    Us $ [         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      US9s SnA$ SnAff = fz
Return device linkinfo:info_data attribute or default value
:param ifname:
:param info_data_attribute:
:param default:
:return:
Nr   r_   rM   rs   r
   r   r   IFLA_INFO_DATArw   r   r   r   r   r   r   r   r-   )r1   r4   info_data_attributer  r   s        r%   get_link_info_data_attribute*_NetlinkCache.get_link_info_data_attribute  s    	y!!''/::4;M;MNTTUYUhUhij}~ "!!.) 	N 	y++G,@,@,B,I,I,Q,QSY[^_`[apw+xx	yB   A1 AA 	A1  
A.*A1 .A1 1C	CACCCc                     U R                      U R                  U   R                  [        R                     R
                  [        R                     sSSS5        $ ! , (       d  f       g= f! [        [        4 a    0 s $ [         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      0 S9s SnA$ SnAff = fr+  r,  r   s      r%   get_link_info_data _NetlinkCache.get_link_info_data  s    	t!!''/::4;M;MNTTUYUhUhi "!!.) 	I 	t++G,@,@,B,I,I,Q,QSY[^_`[apr+ss	tsB   A. AA	A. 
A+'A. +A. .C	CACCCc                     U R                      U R                  U   R                  [        R                     R
                  [        R                     U   sSSS5        $ ! , (       d  f       g= f! [        [        4 a    Us $ [         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      US9s SnA$ SnAff = f)z
Return device linkinfo:info_slave_data attribute or default value
:param ifname:
:param info_data_attribute:
:param default:
:return:
Nr   )r_   rM   rs   r
   r   r   IFLA_INFO_SLAVE_DATArw   r   r   r   r   r   r   r   r-   )r1   r4   info_slave_data_attributer  r   s        r%   "get_link_info_slave_data_attribute0_NetlinkCache.get_link_info_slave_data_attribute  s    	y!!''/::4;M;MNTTUYUnUno  qJ  K "!!.) 	N 	y++G,@,@,B,I,I,Q,QSY[^_`[apw+xx	yr1  c                 D    U R                      U R                  U   sSSS5        $ ! , (       d  f       g= f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      SS9s SnA$ SnAff = f)z;
Return device master's ifname
:param ifname:
:return: str
Nr   r_   rV   rw   r   r   r   r   r   r   r   r-   r   s      r%   
get_master_NetlinkCache.get_master(  s    	v!!**62 "!!.) 	 	v++G,@,@,B,I,I,Q,QSY[^_`[apt+uu	vs6   8 '	8 
58 8 B
	BABBBc                      U R                      [        U R                  U   5      sSSS5        $ ! , (       d  f       g= f! [         a    / s $ f = f)z\
Return all devices ifname enslaved to master device
:param master:
:return: list of string
N)r_   r`   rU   rw   )r1   r{   s     r%   
get_slaves_NetlinkCache.get_slaves6  sB    	!!D44V<= "!! 	I	s(   A 0	A 
>A A AAc                      U R                      U R                  U   U:H  sSSS5        $ ! , (       d  f       g= f! [         a     gf = f)zR
Return bool if SLAVE is enslaved to MASTER
:param slave:
:param master:
:return:
NF)r_   rV   rw   r   s      r%   is_link_enslaved_to!_NetlinkCache.is_link_enslaved_toB  s@    	!!**51V; "!! 		s#   ; *	; 
8; ; 
AAc                     U R                      U R                  U R                  U   R                  [        R
                     R                  5      sSSS5        $ ! , (       d  f       g= f! [        [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[!        U5      SS9s SnA$ SnAff = f)z[
Return the lower-device (IFLA_LINK) name or raise KeyError
:param ifname:
:return: string
Nr   )r_   r   rM   rs   r
   	IFLA_LINKr   rA   r   rw   r   r   r   r   r   r   r-   r   s      r%   get_lower_device_ifname%_NetlinkCache.get_lower_device_ifnameO  s    	v!!t'7'7'?'J'J4>>'Z'`'`a "!!/J 	 	v++G,@,@,B,I,I,Q,QSY[^_`[apt+uu	vsB   A, AA	A, 
A)%A, )A, ,C	CACCCc                 4   0 n U R                      U R                  R                  5        H  u  p#UR                  R	                  [
        R                  5      nU(       d  M7  UR                  R	                  [
        R                  5      S:X  d  Mf  X!UR                  [
        R                     [
        R                     '   M     S S S 5        U$ ! , (       d  f       U$ = f! [         a,  n[        R                  S[        U5      -  5         S nAU$ S nAff = f)Nvrfzget_vrf_table_map: %s)r_   rM   ry   rs   r   r
   r   r   r   r-  IFLA_VRF_TABLEru   rk   rl   r-   )r1   vrf_table_mapr4   r   linkinfor   s         r%   get_vrf_table_map_NetlinkCache.get_vrf_table_mapa  s    	8!!#'#3#3#9#9#;KF"~~11$2D2DEHxHNN$6$6t7J7J$Ku$TbhhnnT5H5H&I$J]J]&^_	 $< "  "!   	8II-A677	8sA   C! AC"+C4CC! 
CC! C! !
D+!DDc                 *    U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     gf = fNr   )
r_   rM   rs   r
   r   r   r-  rJ  rw   r   r   s     r%   get_vrf_table_NetlinkCache.get_vrf_tablen  so    	!!''/::4;M;MNTTUYUhUhijnj}j}~ "!!.) 		/   A? AA.$	A? .
A<8A? <A? ?BBc                     U R                      U R                  U   R                  [        R                  R
                     R                  [        R                  R                     S:H  sSSS5        $ ! , (       d  f       g= f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[!        U5      SS9s SnA$ SnAff = f)zI
Check if bond 'ifname' exists
:param ifname: bond name
:return: boolean
bondNFr   )r_   rM   rs   r   r
   r   r   r   rw   r   r   r   r   r   r   r   r-   r   s      r%   bond_exists_NetlinkCache.bond_existsy  s    	w!!''/::8==;V;VW]]^f^k^k^z^z{  @F  F "!!.) 	 	w++G,@,@,B,I,I,Q,QSY[^_`[apu+vv	wsB   B AA4*	B 4
B>B B C,	C, AC'!C,'C,c                    Sn U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sSSS5        $ ! , (       d  f       g= f! [        [        4 a    Us $ [         aL  nU R                  [        R                  " 5       R                  R                  U[!        U5      US9s SnA$ SnAff = f)zQ
Get bridge port multicast_router value - defaults to 1

:param ifname:
:return:
r   Nr   )r_   rM   rs   r
   r   r   r6  IFLA_BRPORT_MULTICAST_ROUTERrw   r   r   r   r   r   r   r   r-   r1   r4   r  r   s       r%    get_bridge_port_multicast_router._NetlinkCache.get_bridge_port_multicast_router  s     	!!''/::4;M;MNTTUYUnUnopt  qR  qR  S "!!.) 	! !  	++$$&--55A*	 ,  	B   B AA0&	B 0
A>:B >B C*	C*AC%C*%C*c                    Sn U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sSSS5        $ ! , (       d  f       g= f! [        [        4 a    Us $ [         aL  nU R                  [        R                  " 5       R                  R                  U[!        U5      US9s SnA$ SnAff = f)zN
Get bridge multicast_snooping value - defaults to 1

:param ifname:
:return:
r   Nr   )r_   rM   rs   r
   r   r   r-  IFLA_BR_MCAST_SNOOPINGrw   r   r   r   r   r   r   r   r-   rZ  s       r%   get_bridge_multicast_snooping+_NetlinkCache.get_bridge_multicast_snooping  s     	!!''/::4;M;MNTTUYUhUhijn  kF  kF  G "!!.) 	! !  	++G,@,@,B,I,I,Q,QSY[^_`[ap}+~~	r]  c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sSSS5        $ ! , (       d  f       g= f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[!        U5      SS9s SnA$ SnAff = f)z$
WARNING: ifname should be a bridge
Nr   r   )r_   rM   rs   r
   r   r   r-  IFLA_BR_STP_STATErw   r   r   r   r   r   r   r   r-   r   s      r%   get_bridge_stp_NetlinkCache.get_bridge_stp  s    	s!!''/::4;M;MNTTUYUhUhijn  kA  kA  B "!!.) 	 	s++G,@,@,B,I,I,Q,QSY[^_`[apq+rr	sB   A? AA.$	A? .
A<8A? <A? ?C&	C&AC!C&!C&c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     g [         aL  nU R                  [        R                  " 5       R                  R                  U[!        U5      S S9s S nA$ S nAff = fNr   )r_   rM   rs   r
   r   r   r-  IFLA_BRPORT_COSTrw   r   r   r   r   r   r   r   r-   r   s      r%   get_brport_cost_NetlinkCache.get_brport_cost  s    	v!!''/::4;M;MNTTUYUhUhijnjj  A "!!.) 	 	v++G,@,@,B,I,I,Q,QSY[^_`[apt+uu	vrf  c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     g [         aL  nU R                  [        R                  " 5       R                  R                  U[!        U5      S S9s S nA$ S nAff = frh  )r_   rM   rs   r
   r   r   r-  IFLA_BRPORT_PRIORITYrw   r   r   r   r   r   r   r   r-   r   s      r%   get_brport_priority!_NetlinkCache.get_brport_priority  s    	v!!''/::4;M;MNTTUYUhUhijn  kD  kD  E "!!.) 	 	v++G,@,@,B,I,I,Q,QSY[^_`[apt+uu	vrf  c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[!        U5      SS9s S nA$ S nAff = fNr   r   )r_   rM   rs   r
   r   r   r-  IFLA_BRPORT_UNICAST_FLOODrw   r   r   r   r   r   r   r   r-   r   s      r%   get_brport_unicast_flood&_NetlinkCache.get_brport_unicast_flood  s    	s!!''/::4;M;MNTTUYUhUhijn  kI  kI  J "!!.) 	 	s++G,@,@,B,I,I,Q,QSY[^_`[apq+rr	srf  c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[!        U5      SS9s S nA$ S nAff = frq  )r_   rM   rs   r
   r   r   r-  IFLA_BRPORT_MCAST_FLOODrw   r   r   r   r   r   r   r   r-   r   s      r%   get_brport_multicast_flood(_NetlinkCache.get_brport_multicast_flood      	s!!''/::4;M;MNTTUYUhUhijn  kG  kG  H "!!.) 	 	s++G,@,@,B,I,I,Q,QSY[^_`[apq+rr	srf  c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[!        U5      SS9s S nA$ S nAff = frq  )r_   rM   rs   r
   r   r   r-  IFLA_BRPORT_BCAST_FLOODrw   r   r   r   r   r   r   r   r-   r   s      r%   get_brport_broadcast_flood(_NetlinkCache.get_brport_broadcast_flood  ry  rf  c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[!        U5      SS9s S nA$ S nAff = frq  )r_   rM   rs   r
   r   r   r-  IFLA_BRPORT_NEIGH_SUPPRESSrw   r   r   r   r   r   r   r   r-   r   s      r%   get_brport_neigh_suppress'_NetlinkCache.get_brport_neigh_suppress  s    	s!!''/::4;M;MNTTUYUhUhijn  kJ  kJ  K "!!.) 	 	s++G,@,@,B,I,I,Q,QSY[^_`[apq+rr	srf  c                 *    U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     gf = frP  )
r_   rM   rs   r
   r   r   r6  IFLA_BRPORT_LEARNINGrw   r   r   s     r%   get_brport_learning!_NetlinkCache.get_brport_learning   sz    	!!''/::4;M;MNTTUYUnUnopt  qJ  qJ  K "!!.) 		rS  c                     U R                      U R                  R                  U5      sS S S 5        $ ! , (       d  f       g = frJ   )r_   rP   r   r   s     r%   get_vlan_vni_NetlinkCache.get_vlan_vni  s+    ..226: s	   2
A c                    Sn/ n SnSnU R                      U R                  R                  U5      nU(       a  [        U5       H  u  pxU[        R
                  -  (       a  UnU[        R                  -  (       a  UnUnM=  U[        R                  -  (       aQ  XX-  nU(       d  [        R                  SU-  5        Un[        XGS-   5       H  n	UR                  U	5        M     SnSnM  UR                  U5        M     SSS5        X#4$ ! , (       d  f       X#4$ = f! [         a    [        R                  S5         X#4$ f = f)a+  
vlan-identifiers are stored in:

self._bridge_vlan_cache = {
    ifname: [(vlan, flag), (vlan, flag), ...]
}

Those vlans are stored in compressed format (RTEXT_FILTER_BRVLAN_COMPRESSED)
We only uncompress the vlan when the user request it.

:param ifname:
:return tuple: pvid, vids = int, [int, ]
NzPBRIDGE_VLAN_INFO_RANGE_END is %d but we never saw a BRIDGE_VLAN_INFO_RANGE_BEGINr   get_bridge_vids)r_   rO   r   sortedr
   BRIDGE_VLAN_INFO_PVIDBRIDGE_VLAN_INFO_RANGE_BEGINBRIDGE_VLAN_INFO_RANGE_ENDrk   warningranger,   ru   r2   )
r1   r4   pvidvlansrange_begin_vlan_id
range_flagbridge_vlans_tuplesvlan_id	vlan_flagxs
             r%   get_pvid_and_vids_NetlinkCache.get_pvid_and_vids  s>    "	-"&J!!&*&=&=&A&A&&I#&067J0K,$t'A'AA#*D$t'H'HH29/)2J&)H)HH&3J#6 # -QSZ-[ !\6= 3%*+>!%L %Q &M 37/)-J "LL11 1L	 "> {? "!> {  	-MM+,{	-s/   D C)D
?D 

DD D E Ec                 \   Sn U R                      U R                  R                  U5      nU(       a9  [        U5       H*  u  pEU[        R
                  -  (       d  M  Us  sSSS5        $    SSS5        U$ ! , (       d  f       U$ = f! [         a    [        R                  S5         U$ f = f)z?
Get Port VLAN ID for device 'ifname'

:param ifname:
:return:
Nget_pvid)	r_   rO   r   r  r
   r  ru   rk   r2   )r1   r4   r  r  r  r  s         r%   r  _NetlinkCache.get_pvid@  s     	&!!&*&=&=&A&A&&I#&067J0K,$t'A'AAA#*N "!
 1L "  "!   	&MM*%	&sA   B A	A6A6 	B *A6,B 6
B B B B+*B+c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     S:H  sSSS5        $ ! , (       d  f       g= f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      SS9s SnA$ SnAff = f)z$
Check if cached device is a bridge
r   NFr   r   r   s      r%   bridge_exists_NetlinkCache.bridge_existsV  s    	w!!''/::4;M;MNTTUYUhUhimuu "!!.) 	 	w++G,@,@,B,I,I,Q,QSY[^_`[apu+vv	wB   A1 AA 	A1  
A.*A1 .A1 1C	CACCCc                     U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sSSS5        $ ! , (       d  f       g= f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[!        U5      SS9s SnA$ SnAff = f)zE
Return IFLA_BR_VLAN_FILTERING value
:param ifname:
:return: boolean
NFr   )r_   rM   rs   r
   r   r   r-  IFLA_BR_VLAN_FILTERINGrw   r   r   r   r   r   r   r   r-   r   s      r%   bridge_is_vlan_aware"_NetlinkCache.bridge_is_vlan_awareb  s    	w!!''/::4;M;MNTTUYUhUhijn  kF  kF  G "!!.) 	 	w++G,@,@,B,I,I,Q,QSY[^_`[apu+vv	wrf  c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     S:H  sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      SS9s S nA$ S nAff = f)Nr   Fr   r&  r   s      r%   link_is_bridge_port!_NetlinkCache.link_is_bridge_portp  s    	w!!''/::4;M;MNTTUYUnUnos{{ "!!.) 	 	w++G,@,@,B,I,I,Q,QSY[^_`[apu+vv	wr  c                 J    U R                      U R                  U   U:H  sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                  U[        U5      SS9s S nA$ S nAff = f)NFr   r;  )r1   bridge_namebrport_namer   s       r%   bridge_port_exists _NetlinkCache.bridge_port_existsy  s    	|!!**;7;F "!! .) 	 	|++G,@,@,B,I,I,Q,QS^`cde`fuz+{{	|s6   ; *	; 
8; ; B"	B"ABB"B"c                 X    U R                  U5      nU R                  U5      (       a  U$ S $ rJ   )r<  r   )r1   bridge_port_namer  s      r%   get_bridge_name_from_port'_NetlinkCache.get_bridge_name_from_port  s.    oo&67 #11+>>{HDHr$   c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     [        R                     sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     g[         aL  nU R                  [        R                  " 5       R                  R                   U[#        U5      SS9s S nA$ S nAff = frq  )r_   rM   rs   r
   IFLA_AF_SPECr   rW   rY   IFLA_INET6_ADDR_GEN_MODErw   r   r   r   r   r   r   r   r-   r   s      r%   get_link_ipv6_addrgen_mode(_NetlinkCache.get_link_ipv6_addrgen_mode  s    	s!!''/::4;L;LMSSTZTcTcdei  fC  fC  D "!!.) 	 	s++G,@,@,B,I,I,Q,QSY[^_`[apq+rr	srf  c                    UR                   n UR                  [        R                  5      R	                  5       nU R                     X0R                  ;   a
   SSS5        g SSS5        U R                     X0R                  ;   a   UR                  [        R                  	 SSS5        SnU R                     U R                  (       a0  U R                  U[         4:X  a  U R"                  R%                  5          U R&                  U   R                  R)                  [        R                  5      nU(       a  UR+                  5       nXR&                  U'   U(       aj  X R.                  U'   SnU R0                  R)                  U5      nU(       a  Xs:w  a  SnX0R0                  U'   U(       a   U R.                  U	  U R&                  U	 UR                  R)                  [        R                  5      nU(       a  UR+                  5       n	OSn	U(       a   XI:w  a   U R7                  US9  O
 SSS5        gU	(       d
   SSS5        gU R0                  R)                  U	5      n
U
(       de  SU-  n[:        R<                  R?                  U5      (       a<  [:        R<                  RA                  [:        R<                  RC                  U5      5      n
XRD                  ;   a  U RD                  U
   RG                  U5        O[%        U/5      U RD                  U
'   XRH                  U'   SSS5        g! [
         a#    UR                  [        R                  5      n GNf = f! , (       d  f       GN= f! [         a    U R                  R                  U5         GNf = f! , (       d  f       GN= f! [,         a     GNl[
         a     GNxf = f! [,         a!    [2        R5                  SU< SU< 35         GN5f = f! [,         a!    [2        R5                  SU< SU< 35         GNUf = f! [8         a     GNf = f! , (       d  f       g= f)	z0
Cache RTM_NEWLINK packet
:param link:
:return:
NFTz,update_helper_dicts: del _ifindex_by_ifname[z]: KeyError ifname: z%update_helper_dicts: del _link_cache[rz   z/sys/class/net/%s/master)%r   get_attribute_valuer
   IFLA_IFNAMEdecoder   rb   ra   rd   rc   rs   rt   ru   rv   r_   re   r   rg   setrM   r   get_pretty_valuerw   rR   rQ   rk   rl   r   rD   r   pathexistsbasenamerealpathrU   addrV   )r1   linkr   r4   old_ifla_masterifla_master_attrrename_detectedold_ifname_entry_for_ifindexlink_ifla_master_attrlink_ifla_mastermaster_ifnamemaster_device_paths               r%   add_link_NetlinkCache.add_link  s    ,,	@--d.>.>?FFHF ++222 ,+2 , --444?(8(89 .  D$4$48M$M&&**,#'#3#3F#;#F#F#J#J4K[K[#\ #&6&G&G&IO (,V$
  3:''/27262I2I2M2Mg2V,/4P4Z '+O39''0"b 334PQb ,,-IJ %)OO$7$78H8H$I!$#8#I#I#K #'  "6--F-; m p $s v !33778HIM  &@&%H"77>>"455 %'GG$4$4RWW5E5EFX5Y$ZM 8 88((7;;FC:=vh-((7*7'q 1  	@--d.>.>?F	@
 ,+ ! ?//66v>?	 .-.  ! 
 J $ b		%AC_#a bb
 $ b		%AC_#a bb2 < c s   -L' M6NM)8AP1;AN'A#P1,O:O2AP1P &P11P1CP1')MM
M&)%NNNN
N$'
O1P14	O=P1 OP1'O/+P1.O//P12'PP1PP1 
P.*P1-P..P11
P?c                     U R                      U R                  U   R                  [        R                     R
                  [        R                     R                  U5        SSS5        g! , (       d  f       g= f! [         a     gf = f)zZ
Update specific IFLA_INFO_DATA attributes of an existing cached device
ignore all errors
N)	r_   rM   rs   r
   r   r   r-  updateru   r1   r4   ifla_info_datas      r%   update_link_info_data#_NetlinkCache.update_link_info_data>  si    
	!!  (33D4F4FGMMdNaNabiijxy "!! 		s/   A= AA,#A= ,
A:6A= :A= =
B
	B
c                    / nU R                      UR                  [        R                  5      nUR                  [        R                  5      nU(       d
   SSS5        g UR                  [        R
                  5      nU(       a  XPR                  ;  a
   SSS5        g UR                  5        Hj  u  pgU[        R                  :X  a  U H  u  pUR                  X45        M     M8  U[        R                  :X  d  MN  U R                  R                  XG05        Ml     U R                  R                  XB05        SSS5        g! [         a     Nf = f! , (       d  f       g= f)z
Process AF_BRIDGE family packets (AF_BRIDGE family should be check
before calling this function).

Extract VLAN_INFO (vlan id and flag) and store it in cache.

:param link:
:return:
N)r_   r  r
   r  r  rt   rQ   ru   ry   IFLA_BRIDGE_VLAN_INFOr,   IFLA_BRIDGE_VLAN_TUNNEL_INFOrP   r  rO   )
r1   r   
vlans_listifla_af_specr4   ifla_masterx_typex_valuer  r  s
             r%   add_bridge_vlan_NetlinkCache.add_bridge_vlanI  s5    
 2243D3DEL,,T-=-=>F 	 "55d6F6FG"+9P9P*P  +Q $0#5#5#7T777.5*	 #))7*>? /6
 t@@@//667HI $8 ##**F+?@I    s7   AE 5EAE><E
EEEE
E!c                     U R                      U R                  R                  U5      nU(       d  U1U R                  U'   OUR                  U5        U R                  R                  U5      nU(       a1  XA:w  a,   U R                  R                  U/ 5      R                  U5        XR                  U'   SSS5        g! [         a     N#f = f! , (       d  f       g= f! [         a     gf = fz
When calling link_set_master, we don't want to wait for the RTM_GETLINK
notification - if the operation return with NL_SUCCESS we can manually
update our cache and move on
:param master:
:param slave:
:return:
N)r_   rU   r   r  rV   rv   ru   )r1   r{   rz   master_slaves
old_masters        r%   force_add_slave_NetlinkCache.force_add_slave|  s    	!! $ 8 8 < <V D$8=wD,,V4!%%e,
 "0044U;
*"60044ZDKKER .4##E*' "!  % ! "!(  		sS   C A,C;+B=&C4C =
C
C	C

C
CC C 
C+*C+c                 8    U R                      U R                  R                  U5      nU(       d  [        U5      U R                  U'   OUR	                  U5        U H  nXR
                  U'   M     SSS5        g! , (       d  f       g= f! [         a     gf = fr  )r_   rU   r   r  r  rV   ru   )r1   r{   
slave_listr  rz   s        r%   force_add_slave_list"_NetlinkCache.force_add_slave_list  s    	!! $ 8 8 < <V D$7::D,,V4!((4'E17''. ( "!!  		s/   B A$A;2B ;
B	B 	B 
BBc                 x     U R                  U5      nU R                  SXS9  g! [        [        4 a    Sn N%f = f)z
When calling link_del (RTM_DELLINK) we need to manually remove the
associated cache entry - the RTM_DELLINK notification isn't received
instantaneously - we don't want to keep stale value in our cache
:param ifname:
:return:
N)link_ifnamelink_ifindex)r   rw   rA   remove_linkr   s      r%   force_remove_link_NetlinkCache.force_remove_link  sH    	&&v.G 	6H 9: 	G	s   $ 99c           
         U(       a]  UR                   nUR                  [        R                  5      n U R                     U R
                  R                  U5        SSS5        OUnUnSnU R                       U R                  U   R                  R                  [        R                  5      nU(       a  UR                  5       nU R                  U	  [%        U R&                  U   5       H  nU R)                  XS9  M      U R,                  U	  U R.                  U	  U R0                  U	  U R2                  U	  U R4                  U	  U R&                  U	 U(       a  US:  a   U R)                  US	9  SSS5        g! , (       d  f       GN#= f! [         a     GN3f = f! [         a     N[         a     Nf = f! U R                  U	 f = f! [         a    [         R#                  SU-  5         GNf = f! [*         a     Nf = f! [*         a     GNf = f! [*         a     GNf = f! [         a    [         R#                  SU-  5         GN f = f! [         a    [         R#                  SU-  5         GN;f = f! [         a    [         R#                  SU-  5         GNVf = f! [         a    [         R#                  SU-  5         GNqf = f! [6         a1  n	[         R#                  S
U< S[9        U	5      < 35         Sn	A	GNSn	A	f[         a"    [         R#                  SU< SU< S35         GNf = f! , (       d  f       g= f)z;Process RTM_DELLINK packet and purge the cache accordingly Nz$del _link_cache: KeyError ifname: %s)r{   z,del _ifname_by_ifindex: KeyError ifindex: %sz+del _ifindex_by_ifname: KeyError ifname: %sz$del _addr_cache: KeyError ifname: %sz,del _masters_and_slaves: KeyError ifname: %sr   r  zcache: remove_link: r+   z_masters_and_slaves[ifz	].remove(z): KeyError)r   r  r
   r  rb   ra   rv   rx   r_   rM   rs   r   rt   r  rw   r   rk   rl   r`   rU   r   ru   rO   rP   rQ   rR   rN   rD   r-   )
r1   r  r  r  r   r4   r  r  rz   r   s
             r%   r  _NetlinkCache.remove_link  s   llG--d.>.>?F 33--44V< 43
 !F"G K1'+'7'7'?'J'J'N'NtO_O_'`$'+;+L+L+N( ((0
 "$":":6"BCE))%)? D
++F3//7T++G4R++F3K$$V,S,,V4  $4q$8m)))7  43 $   % 
  ((0 K		@6IJK  
  
  
  T		H7RST
  R		G&PQR
  K		@6IJK
  S		H6QRS 8 OIIfc!fMNN mIIRbdjklmE s  F  E=F 7L4:AF G.G6HH H(.I<I:
J#L4%K=
FF F 
FF 
F8*F;,	F85F;7F88F;;G

G"G3/L42G33L46
H L4HL4
HL4HL4
H%!L4$H%%L4("I
L4IL4"I73L46I77L4:"J L4J  L4#"K	L4K		L4
L1&L<L4+L1-L40L11L44
Mc                     UR                   nUR                  [        R                  5      nU(       d   U R	                  U5      n[        U[        5      (       a  UR                  5       nX24$ ! [
         a     N4f = frJ   )	r   r  r   	IFA_LABELr   rD   
isinstancebytesr  )r1   addrr   labels       r%   _address_get_ifname_and_ifindex-_NetlinkCache._address_get_ifname_and_ifindex   sm    ,,(():):;0 eU##LLNE~ 4 s   A- -
A:9A:c                     UR                  [        R                  5      n[        U 5       H.  u  p4UR                  [        R                  5      U:X  d  M*  XU'     g   g)z
Check if new_addr is in address_list, if found we replace the occurrence
with the new and update object "new_addr"

address_list should be a valid list (check before calling to improve perf)
:param address_list:
:param new_addr:
:return:
TF)r  r   IFA_ADDRESS	enumerate)address_listnew_addrip_with_prefixindexr  s        r%   __check_and_replace_address)_NetlinkCache.__check_and_replace_address/  sT     "55g6I6IJ$\2KE''(;(;<N&.U# 3
 r$   c                    U R                  U5      u  p#U(       d  [        R                  SU-  5        g UR                  [        R
                  5      R                  nU R                     X R                  ;   aA  U R                  U   U   nU(       a  U R                  XQ5      (       d  UR                  U5        OS/ S/ XA/0U R                  U'   S S S 5        g ! , (       d  f       g = f)Nz6nlcache: add_address: cannot cache addr for ifindex %s      )r  rk   rl   r  r   r  versionr_   rN   (_NetlinkCache__check_and_replace_addressr,   )r1   r  r4   r   
ip_versionr  s         r%   add_address_NetlinkCache.add_addressC  s    >>tDIINQXXY--g.A.ABJJ
)))#//7
C $4+K+KL+_+_ ''- rr,  ( s   )A&C
C&c                      U R                      / U R                  U   U'   S S S 5        g ! , (       d  f       g = f! [         a     g f = frJ   r_   rN   ru   )r1   r4   familys      r%   force_address_flush_family(_NetlinkCache.force_address_flush_family[  sB    	!!35  (0 "!! 		#   ; *; 
8; ; 
AAc                      U R                      / / S.U R                  U'   SSS5        g! , (       d  f       g= f! [         a     gf = f)z?
Flush address cache for link 'ifname'
:param ifname:
:return:
r  r  Nr
  r   s     r%   address_flush_link _NetlinkCache.address_flush_linkb  sA    	!!/1b>  ( "!! 		r  c                 8    U R                      SnU R                  U   UR                      H3  n UR                  [        R
                     R                  U:X  a  UnM3  M5     U(       a+  U R                  U   UR                     R                  U5        SSS5        g! [         aO     UR                  [        R                     R                  U:X  a  Un M   M  ! [         a        SSS5        gf = ff = f! , (       d  f       g= f! [         a     gf = f)z
When calling addr_del (RTM_DELADDR) we need to manually remove the
associated cache entry - the RTM_DELADDR notification isn't received
instantaneously - we don't want to keep stale value in our cache
:param ifname:
:param addr:
N)
r_   rN   r  rs   r   r  r   ru   	IFA_LOCALrv   )r1   r4   r  obj_to_remove
cache_addrs        r%   force_remove_addr_NetlinkCache.force_remove_addrn  s   	!! !%"&"2"26":4<<"HJ#%001D1DEKKtS,6M T #I !$$V,T\\:AA-P! "! % ##)44W5F5FGMMQUU0:  V( #" "!#	# "!"  		su   D "C;-B8C;D 
C8*-CC;
C4	'C8(C;*D 3C4	4C88C;;
D	D 	D 
DDc                 F   U R                  U5      u  p#U R                      UR                  [        R                  5      R
                  nU R                  R                  U0 5      R                  U5      nU(       d
   S S S 5        g / nU H\  nSnU R                   H-  n	UR                  U	5      UR                  U	5      :w  a  Sn  OSnM/     U(       d  MK  UR                  U5        M^     U H  n UR                  U5        M     S S S 5        g ! [         aF     UR                  [        R                  5      R
                  n N! [         a      S S S 5        g f = ff = f! [         a#  n
[        R                  SU
-  5         S n
A
M  S n
A
ff = f! , (       d  f       g = f)NFTz&nlcache: remove_address: exception: %s)r  r_   r  r   r  r  ru   r  rN   r   _ifa_attributesr,   rv   rx   rk   rl   )r1   addr_to_remover4   _r  addrs_for_interfacelist_addr_to_remover  
addr_matchifa_attrr   s              r%   remove_address_NetlinkCache.remove_address  s   88H	+??@S@ST\\
 #'"2"2"6"6vr"B"F"Fz"R& " #%+"
 $ 4 4H//9^=_=_`h=ii%*
!%J	 !5 :'..t4 , ,L'..t4 ,C 
  !/!C!CGDUDU!V!^!^J   > " LIIFJKKLI s   F)D3FAFF1E"F
E)EF
EEFEEF"
F,F
F
FF
F r4   returnc                    / n U R                      U R                  U   nUR                  S/ 5       H9  nUR                  UR                  [
        R                     R                  5        M;     UR                  S/ 5       H9  nUR                  UR                  [
        R                     R                  5        M;     UsS S S 5        $ ! , (       d  f       g = f! [        [        4 a    Us $ f = f)Nr  r  )
r_   rN   r   r,   rs   r   r  r   rw   r   )r1   r4   	addressesintf_addressesr  s        r%   get_ip_addresses_NetlinkCache.get_ip_addresses  s    		!!!%!1!1&!9*..q"5D$$T__W5H5H%I%O%OP 6 +..q"5D$$T__W5H5H%I%O%OP 6 ! "!! .) 		s/   C B/C	?	C 	
CC C C/.C/c                      U R                      U R                  U   n[        UR                  SS 5      =(       d    UR                  SS 5      5      sS S S 5        $ ! , (       d  f       g = f! [         a     gf = f)Nr  r  F)r_   rN   boolr   ru   )r1   r4   r&  s      r%   link_has_ip_NetlinkCache.link_has_ip  sg    	!!!%!1!1&!9N..q$7V>;M;MaQU;VW "!!  		s/   A, AA	A, 
A)%A, )A, ,
A98A9c                      U R                      XR                  UR                     UR                  UR                  5      '   SSS5        g! , (       d  f       g= f! [
         a     gf = f)z
cache RTM_NEWNETCONF objects
{
    family: {
        ifindex: RTM_NEWNETCONF
    }
}
we currently only support AF_INET, AF_INET6 and AF_MPLS family.
Nr]   rZ   r  r  NETCONFA_IFINDEXru   r1   r   s     r%   add_netconf_NetlinkCache.add_netconf  sU    	))ad##CJJ/0G0GH\H\0]^ *)) 		s.   A 5AA 
AA A 
A*)A*c                      U R                      U R                  UR                     UR                  UR                  5      	 SSS5        g! , (       d  f       g= f! [
         a     gf = f)zG
Process RTM_DELNETCONF, remove associated entry in our _netconf_cache
Nr.  r0  s     r%   remove_netconf_NetlinkCache.remove_netconf  sU    	))''

3C4K4KCL`L`4ab *)) 		s.   A 4AA 
AA A 
A)(A)c                      U R                      U R                  U   U R                  U5         R                  [        R
                  5      sSSS5        $ ! , (       d  f       g= f! [         a     gf = f)z(
Return netconf device forwarding value
N)r]   rZ   r   r  r	   NETCONFA_FORWARDINGru   )r1   r  r4   s      r%   get_netconf_forwarding$_NetlinkCache.get_netconf_forwarding  s]    	))**6243C3CF3KL``aha|a|} *)) 		s.   A' >A	A' 
A$ A' $A' '
A43A4c                      U R                      U R                  [           U R                  U5         R	                  [
        R                  5      sSSS5        $ ! , (       d  f       g= f! [         a     gf = f)z(
Return netconf device MPLS input value
N)r]   rZ   r   r   r  r	   NETCONFA_INPUTru   r   s     r%   get_netconf_mpls_input$_NetlinkCache.get_netconf_mpls_input  s]    	))**73D4D4DV4LMaabibxbxy *)) 		s/   A+ AA	A+ 
A($A+ (A+ +
A87A8ifaceobj_listc           	         / n/ nU  GHP  nUR                  S5      nU(       a  [        U5       H|  u  pgSU;   a  [        R                  " U5      nO&[        R                  " XtR	                  SU5      5      nUR
                  S:X  a  UR                  U5        Mk  UR                  U5        M~     U(       d  M  UR                  S5      n	UR                  S5      n
X4 Hw  nU=(       d    /  He  nUR                  5        HN  n [        R                  " U5      nUR
                  S:X  a  UR                  U5        M=  UR                  U5        MP     Mg     My     GMS     X#-   $ ! [         a     Mp  f = f)Naddress/netmaskr  zaddress-virtualvrrp)	get_attr_valuer  	ipnetwork	IPNetworkget_attr_value_nr  r,   splitru   )r>  with_address_virtualip4ip6ifaceobjr%  
addr_indexr  ip_network_objaddresses_virtualrC  attr_configaddr_virtual_entrys                r%   get_user_configured_addresses+_NetlinkCache.get_user_configured_addresses  sR   %H //	:I(1)(<$Jd{)2)<)<T)B
 *3)<)<TC\C\]fhrCs)t%--2

>2

>2 )= ( !) 7 78I J ( 7 7 ?D 18*5*;*;& 2 8 8 :%-6-@-@-FN-55: #

> : #

> : !; +<  95 &P y	  ) %$%s   7E :E  
E.-E.rI  c                    [        U R                  UUS95      n[        R                  R	                  U5      nU(       a(  U R                  UUS9 H  nUR                  U5        M     / nU R                  U5       HP  nX;   a  UR                  U5        M  UR                  [        R                  -  (       a  M?  UR                  U5        MR     U$ )a}  
Get all ip addresses managed by ifupdown2. As a network manager we need
to be able to detect manually added ip addresses (with iproute2 for
example).
We only addressed added by the kernel (scope: link).

Args:
    ifname: str
    ifaceobj_list: list of ifaceobj
    with_address_virtual: boolean (to include vrrp and address-virtual)

Returns: List of ipnetwork.IPNetwork objects
)rI  )r  rR  statemanagerstatemanager_apiget_ifaceobjsr  r'  r,   scoper   RT_SCOPE_LINK)	r1   r4   r>  rI  config_addrsprevious_state_ifaceobjsprevious_state_addrmanaged_addressesr  s	            r%   get_managed_ip_addresses&_NetlinkCache.get_managed_ip_addresses3  s     ..%9 / 
 $0#@#@#N#Nv#V #'+'I'I(%9 (J (#   !45	( ))&1D#!((.ZZ%"5"555!((. 2 ! r$   c                     U R                      U R                  U   UR                      Hk  n UR                  [        R
                     R                  nUR                  UR                  :X  a&  UR                  UR                  :X  a
    SSS5        gMk  Mm     SSS5        g! [         a     UR                  [        R                     R                  nUR                  UR                  :H  =(       a    UR                  UR                  :H  s s  sSSS5        $ ! [         a      M  f = ff = f! , (       d  f       g= f! [        [        4 a     gf = f)z
return True if addr is in cache

We might need to check if metric/peer and other attribute are also correctly cached.
We might also need to add a "force" attribute to skip the cache check
:param ifname:
:param ifindex:
:return:
NTF)r_   rN   r  rs   r   r  r   ip	prefixlenru   r  rw   r   )r1   r4   r  r  ifa_address	ifa_locals         r%   addr_is_cached_NetlinkCache.addr_is_cached`  s3   	!!"&"2"26":4<<"HJ	!&0&;&;G<O<O&P&V&V&>>TWW49N9NRVR`R`9`#' "! :a4 #I "  % !!(2(=(=g>O>O(P(V(VI#,<<477#:#dy?R?RVZVdVd?dd "!  ) ! !	! "!  .) 		s   E  D1AB#
D1E D1E #
D..ADD.D1	E 
D*	%D.&D1)D*	*D..D11
D?;E ?E EEc                      U R                      U R                  U   sS S S 5        $ ! , (       d  f       g = f! [         a     g f = frJ   )r_   rM   rw   r   s     r%   get_link_obj_NetlinkCache.get_link_obj}  s;    	!!''/ "!! 		s#   8 '	8 
58 8 
AAc                     U R                      U R                  U   R                  [        R                     R
                  [        R                     sS S S 5        $ ! , (       d  f       g = f! [        [        4 a    0 s $ f = frJ   )	r_   rM   rs   r
   r   r   r6  rw   r   r   s     r%   get_link_info_slave_data&_NetlinkCache.get_link_info_slave_data  se    	!!''/::4;M;MNTTUYUnUno "!!.) 	I	s/   A. AA	A. 
A+'A. +A. .BBc                     U R                      U R                  U   R                  [        R                     R
                  [        R                     U:H  sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     gf = fNF)	r_   rM   rs   r
   r   r   r   rw   r   r1   r4   _types      r%   is_link_kind_NetlinkCache.is_link_kind  si    	!!''/::4;M;MNTTUYUhUhimrr "!!.) 		/   A1 AA 	A1  
A.*A1 .A1 1BBc                     U R                      U R                  U   R                  [        R                     R
                  [        R                     U:H  sS S S 5        $ ! , (       d  f       g = f! [        [        4 a     gf = frn  )	r_   rM   rs   r
   r   r   r'  rw   r   ro  s      r%   is_link_slave_kind _NetlinkCache.is_link_slave_kind  si    	!!''/::4;M;MNTTUYUnUnosxx "!!.) 		rs  )__sysfsrN   rO   rP   r_   rR   rT   rQ   rS   ra   rb   rM   rU   rZ   r]   rc   rd   rV   re   rg   rJ   )Fr8   )kr   r   r    r!   r"   r   r  r  r  IFA_BROADCASTIFA_ANYCASTIFA_MULTICASTr  r/   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  r(  r/  r3  r8  r<  r?  rB  rF  rM  rQ  rV  r[  r`  rd  rj  rn  rs  rw  r|  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  staticmethodr  r  r  r  r  r!  r-   r`   r'  r+  r1  r4  r8  r<  rR  r*  r^  re  rh  rk  rq  ru  r#   r   r$   r%   rG   rG      s    		Of3P.`57
&++1-$^$:C$a8d8.ww @6vI.r4QBEy y vy t y&v
v$w$<*
svvssss;3j,
www|Is Z8x	1Af D0IZmx  &0
:(LTs t   	 ,T ,Z^ , ,\'!s '!4 '!_c '!Z:r$   rG   c                     ^  \ rS rSrSrSr\S 5       r\S 5       r\S 5       r	S r
S rS	 rS
 rS rS rU 4S jrU 4S jrU 4S jrU 4S jrU 4S jrU 4S jrS rS rS rS rS rS rSPS jrS rS rS rS r S r!S r"S  r#S! r$S" r%S# r&S$ r'S% r(S& r)S' r*S( r+S) r,S* r-S+ r.SQS, jr/S- r0S. r1S/ r2S0 r3S1 r4S2 r5\6Rn                  \6Rp                  \6Rr                  \6Rt                  \6Rv                  S3.r<SQS4 jr=SQS5 jr>S6 r?S7 r@SQS8 jrAS9 rBS: rCS; rDS< rES= rFS> rGS? rHSQS@ jrISQSA jrJSB rKSC rLSD rMSE rNSF rOSG rPSRSH jrQSRSI jrRSJ rSSK rTSL rUSM rVSN rWSOrXU =rY$ )SNetlinkListenerWithCachei  Ni  c                     [         R                  (       d   [        U S9[         l        gg! [         a7  n[        R	                  SU-  5        [
        R                  " 5          SnAgSnAff = f)zr
Create the singleton via this init function
Following calls should use get_instance()
:param log_level:
:return:
)	log_levelz"NetlinkListenerWithCache: init: %sN)r}  #_NetlinkListenerWithCache__instanceru   rk   errorr   r   )r  r   s     r%   initNetlinkListenerWithCache.init  sY     (22&6NYb6c(3 3  &		>BC##%%&s   + 
A,-A''A,c                  b    [         R                  (       d  [        S5      e[         R                  $ )z
Use this function to retrieve the active reference to the
NetlinkListenerWithCache, make sure you called .init() first
:return:
z(NetlinkListenerWithCache not initialized)r}  r  r   r   r$   r%   get_instance%NetlinkListenerWithCache.get_instance  s%     (22=>hii'222r$   c                  4    [        [        R                  5      $ rJ   )r*  r}  r  r   r$   r%   is_init NetlinkListenerWithCache.is_init  s    ,7788r$   c                 n   [         R                  (       a  [        S5      eU [         l        [        R                  R                  U [        R                  [        R                  -  [        R                  -  [        R                  -  [        R                  -  [        R                  -  SSS9  [        R
                  " U 5        [        R                  " [        R                  U R                   5        [        R                  " [        R"                  U R$                  5        ['        5       U l        [        R*                  R-                  U5        [        R*                  R-                  U5        [.        R*                  R-                  U5        [0        R2                  [0        R4                  S.U l        S [        l        U R:                  U R<                  0U l        [A        5       U l!        [D        RF                  " 5       U l$        SU l%        SU l&        [D        RN                  " 5       U l(        SU l)        g)z

:param log_level:
z[NetlinkListenerWithCache: invalid access. Please use NetlinkListenerWithCache.getInstance()FT)groupsstart_listenererror_notificationr  c                 P   ^  SR                  U 4S j[        SSS5       5       5      $ )N:c              3   8   >#    U  H  nS T-  XS-    v   M     g7f)z%012x   Nr   ).0imac_ints     r%   	<genexpr>FNetlinkListenerWithCache.__init__.<locals>.<lambda>.<locals>.<genexpr>  s$     :qap\]Gg<MqUVQV;Waps   r      r  )r0   r  )r  s   `r%   <lambda>3NetlinkListenerWithCache.__init__.<locals>.<lambda>  s!    #((:qafghjlnoap:q2qr$   N)*r}  r  RuntimeErrorr   NetlinkManagerWithListenerr/   r   RTMGRP_LINKRTMGRP_IPV4_IFADDRRTMGRP_IPV6_IFADDRRTNLGRP_IPV4_NETCONFRTNLGRP_IPV6_NETCONFRTNLGRP_MPLS_NETCONFr   signalSIGTERMsignal_term_handlerSIGINTsignal_int_handlerrG   rL   rk   r   r   rW   rX   rY   IPNetwork_version_to_familymac_int_to_strWORKQ_SERVICE_NETLINK_QUEUEservice_netlinkqworkq_handlerr`   errorqr[   r\   errorq_lockerrorq_enablednetlinkq_notify_eventrf   is_readyworker)r1   r  s     r%   r/   !NetlinkListenerWithCache.__init__  s   
 $..|}}26$/--66$$--.--. //0 //	0
 //0 !# 	7 	
 	D!fnnd&>&>?fmmT%<%<="_
 		*i(y)/5~~&//+R("q
 ,,d.C.C
( f$>>+" &*" ")r$   c                     g)Nr}  r   rh   s    r%   __str__ NetlinkListenerWithCache.__str__
  s    )r$   c                    U R                  5         [        R                  [        R                  [        R                  [        R
                  [        R                  [        R                  4U R                  l	        [        R                  [        R                  [        R                  [        R                  [        R                  [        R                  [        R                   [        R"                  [        R$                  [        R                  [        R&                  [        R(                  [        R                  [        R*                  [        R,                  4U R                  l        U R1                  5         U R3                  5         U R5                  5         [6        R8                  " U R:                  SS9U l        U R<                  R?                  5         U R@                  RC                  5         g)zS
Start NetlinkListener -
cache all links, bridges, addresses and netconfs
:return:
r}  )targetnameN)"restart_listenerr   r   r   r   r   RTM_NEWNETCONFRTM_DELNETCONFlistenersupported_messagesRTM_GETLINKRTM_GETADDRRTM_GETNEIGHRTM_GETROUTERTM_GETQDISCRTM_NEWNEIGHRTM_DELNEIGHRTM_NEWROUTERTM_DELROUTERTM_NEWQDISCRTM_DELQDISCNLMSG_ERRORr   ignore_messagesget_all_links_wait_netlinkqget_all_addresses_wait_netlinkqget_all_netconf_wait_netlinkqr[   Threadmainr  startr  r   rh   s    r%   r  NetlinkListenerWithCache.start  sR    	         ####,
(     !!!!!!!!!!!!!!##!!!!!!  )
%& 	((* 	,,. 	**,  &&dii>XYr$   c                     U R                   (       d  g U R                  SS5        U R                  (       a  U R                  R                  5         g g rP  )r  r  r  r0   rh   s    r%   cleanup NetlinkListenerWithCache.cleanupF  s:     	  A&;;KK r$   c                    U R                   R                  5           U R                  R                  S5        U R                  R	                  5         U R
                  R                  5       (       a  OU R                  R                  5       (       d  U R                  R                  5       u  pXR                  :X  a  U R                  U R                  5        O9XR                  :X  a  U R                  R                  S5        O[!        SU-  5      eU R                  R                  5       (       d  M  GM  U R"                  R
                  R                  5         U R"                  R%                  5         g ! [          a    e f = f! U R"                  R
                  R                  5         U R"                  R%                  5         f = f)Ng?z-NetlinkListenerWithCache: WORKQ_SERVICE_ERRORzUnsupported workq event %s)r  r  alarmr   r   shutdown_eventis_setworkqemptyr   r  r  r  WORKQ_SERVICE_ERRORloggerr  ru   r  r0   )r1   eventoptionss      r%   r  NetlinkListenerWithCache.mainP  sK   
 	! 

$ 

  "&&--//****,,'+zz~~'7$U @ @@--d.H.HI":"::))*YZ'(Du(LMM ****,,! < MM((,,.MM   		
 MM((,,.MM s,   AE4 1F 2B>E4 2E4 4F  F A Gc                     U R                      U R                  R                  S5        / U l        S S S 5        g ! , (       d  f       g = f)Nznlcache: reset errorq)r  r  rl   r  rh   s    r%   reset_errorq%NetlinkListenerWithCache.reset_errorqx  s1    KK56DK s	   #9
Ac                 b   > [         [        U ]  U5        U R                  R	                  U5        g rJ   )r.   r}  rx_rtm_newaddrrL   r  )r1   rxed_addr_packetr6   s     r%   r  'NetlinkListenerWithCache.rx_rtm_newaddr}  s'    &<=MN

/0r$   c                    > UR                   [        R                  :w  a  g [        [        U ]  U5        U R                  R                  U5        g rJ   )r  rW   	AF_UNSPECr.   r}  rx_rtm_dellinkrL   r  )r1   r  r6   s     r%   r  'NetlinkListenerWithCache.rx_rtm_dellink  s:    ;;&***&<TB

t$r$   c                 b   > [         [        U ]  U5        U R                  R	                  U5        g rJ   )r.   r}  rx_rtm_deladdrrL   r!  )r1   r  r6   s     r%   r  'NetlinkListenerWithCache.rx_rtm_deladdr  s%    &<TB

!!$'r$   c                   > UR                   [        R                  :w  a:  UR                   [        R                  :X  a  U R                  R                  U5        g [        [        U ]#  U5        U R                  R                  U5        g rJ   )
r  rW   r  	AF_BRIDGErL   r  r.   r}  rx_rtm_newlinkr  )r1   rxed_link_packetr6   s     r%   r  'NetlinkListenerWithCache.rx_rtm_newlink  sg     ""f&6&66&&&*:*::

**+;<&<=MN

,-r$   c                 b   > [         [        U ]  U5        U R                  R	                  U5        g rJ   )r.   r}  rx_rtm_newnetconfrL   r1  r1   r   r6   s     r%   r  *NetlinkListenerWithCache.rx_rtm_newnetconf  s%    &?D

s#r$   c                 b   > [         [        U ]  U5        U R                  R	                  U5        g rJ   )r.   r}  rx_rtm_delnetconfrL   r4  r  s     r%   r  *NetlinkListenerWithCache.rx_rtm_delnetconf  s%    &?D

!!#&r$   c                    U R                  U5        SnSnU R                     U R                   H@  nUR                  UR                  :X  a  UR                  UR                  :X  a  Un  O	US-  nMB     U(       a  U R                  U	 SSS5        U(       d  g[        UR                  5      nUR                  [        :X  d  U(       d  gU R                  (       a  UR                  5          [        R                  " U5      nU(       a  SU< SU< S3nOSU-  n [        U5      e! , (       d  f       N= f! [         a    SU-  n N-f = f)	a@  
    After getting an ACK we need to check if this ACK was in fact an
    error (NLMSG_ERROR). This function go through the .errorq list to
    find the error packet associated with our request.
    If found, we process it and raise an exception with the appropriate
    information/message.

:param nl_packet:
:return:
Nr   r   Tzoperation failed with 'z' ()zoperation failed with code %s)tx_nlpacket_get_responser  r  seqpidabsnegative_errnor   r   rl   r   r   strerrorrx   ru   )r1   	nl_packeterror_packetr  r  
error_coder  	error_strs           r%   #tx_nlpacket_get_response_with_error<NetlinkListenerWithCache.tx_nlpacket_get_response_with_error  s    	%%i099	-%))y}}2L#(L
	 % KK&  445
:-Z::
	E{{:.HAI:V	;jH	
 	""E >  	E7*DI	Es$   A%D$*(D5 D5 $
D25EEc                     U R                  U5        U=R                  [        -  sl         UR                  5         U R
                  R                  U5        g! [         a     N(f = f)z)
TX packet and manually cache the object
N)r  r  r   decode_service_headerru   rL   r  )r1   r  s     r%   4tx_nlpacket_get_response_with_error_and_cache_on_ackMNetlinkListenerWithCache.tx_nlpacket_get_response_with_error_and_cache_on_ack  s`     	008 	]*	
 ((* 	

F#  		s   A 
A%$A%c                    U R                   R                  XR                  5      n U R                  U5      nU(       a  U R                   R                  5         U$ ! [         a    U R                   R                  5         e f = f)a  
The netlink request are asynchronus, but sometimes the main thread/user
 would like to wait until the result of the request is cached. To do so
 a cache event for ifname and nl_packet.msgtype is registered. Then the
 netlink packet is TXed, errors are checked then we sleep until the
 cache event is set (or we reach the timeout). This allows us to reliably
 make sure is up to date with newly created/removed devices or addresses.
:param nl_packet:
:return:
)rL   r   r   r  ru   r   r   )r1   r4   r  wait_event_registeredresults        r%   6tx_nlpacket_get_response_with_error_and_wait_for_cacheONetlinkListenerWithCache.tx_nlpacket_get_response_with_error_and_wait_for_cache  sr     !%

 > >vGXGX Y	==iHF !JJ!!#  	JJ,,.	s   A &Bc                 J   U R                   R                  S5        [        R                  " 5       U l        U R                  5         U R                  SS9  U R                  U R                  5        U R                  R                  5         U R                  R                  5         g )Nzrequesting link dumpT)compress_vlans)
r  infor[   rf   r  get_all_linksget_all_br_linksr  r   r   rh   s    r%   r  4NetlinkListenerWithCache.get_all_links_wait_netlinkq	  sy    /0%.__%6"T2d889""'')""((*r$   c                 :   U R                   R                  S5        [        R                  " 5       U l        U R                  5         U R                  U R                  5        U R                  R                  5         U R                  R                  5         SU l        g )Nzrequesting address dumpF)	r  r  r[   rf   r  get_all_addressesr  r   r   rh   s    r%   r  8NetlinkListenerWithCache.get_all_addresses_wait_netlinkq	  sp    23%.__%6" d889""'')""((*%*"r$   c                 :   U R                   R                  S5        [        R                  " 5       U l        U R                  5         U R                  U R                  5        U R                  R                  5         U R                  R                  5         SU l        g )Nzrequesting netconf dumpF)	r  r  r[   rf   r  netconf_dumpr  r   r   rh   s    r%   r  6NetlinkListenerWithCache.get_all_netconf_wait_netlinkq%	  sp    23%.__%6"d889""'')""((*%*"r$   c	                    U[         [        4;   d
   SU-  5       eUS:  a  US::  d
   SU-  5       eUc  UnUS:  a  US::  d
   SU-  5       eX4::  d   SU< SU< S35       eXR                  ;   n	S	n
S	n[        XU R                  S
9n[
        [        -  Ul        [        R                  " S[        R                  US	S	5      Ul        U(       a  U
[        R                  -  n
U(       a  U
[        R                  -  n
U(       a  U[        R                  -  nU(       a  U[        R                   -  n[#        5       nU
(       a  X[        R$                  '   X4:X  a  X4/U[        R&                  '   O;U[        R(                  -  U4U[        R*                  -  U4/U[        R&                  '   UR-                  [        R.                  U5        UR1                  [3        U R4                  5      U R6                  5        U R9                  U5      $ )z&
iproute2 bridge/vlan.c vlan_modify()
z6Invalid msgtype %s, must be RTM_SETLINK or RTM_DELLINKr   i   zInvalid VLAN start %szInvalid VLAN end %szInvalid VLAN range -z, start must be <= endr   	use_colorBxxxiii)r   r   rl   r
   r   r   r   r   structpackrW   r  bodyBRIDGE_FLAGS_SELFBRIDGE_FLAGS_MASTERr  BRIDGE_VLAN_INFO_UNTAGGEDr   IFLA_BRIDGE_FLAGSr  r  r  add_attributer  build_messagenextsequencer  r  )r1   r   r   vlanid_start
vlanid_endbridge_selfbridge_masterr  untaggedrl   bridge_flagsvlan_info_flagsr  r  s                 r%   vlan_modify$NetlinkListenerWithCache.vlan_modify/	  s    ;44x6nqx6xx4q \T%9a;RUa;aa9%JQ:#5Y7Lz7YY5)x_kmw+xx)::%Gdnn="Y.
KK	6+;+;WaK	D222LD444Lt999Ot===O"}3?//0 %9H8W7ZL334
 !4#D#DDlS 4#B#BBJO8L334
 	4,,l;4.977==r$   c                 (    U R                  X0 5        g rJ   )link_add_with_attributes)r1   r4   kinds      r%   link_add!NetlinkListenerWithCache.link_addh	  s    %%fB7r$   c                    U(       aF  U R                   R                  U< SU< SU< S35        U R                   R                  SU-  5        O&U R                   R                  U< SU< SU< 35         [        U R                  ;   n[	        [        X@R
                  S9n[        [        -  [        -  Ul	        [        R                  " S[        R                  SSS5      Ul        [        UR!                  5       5       H  u  pgUR#                  Xg5        M     UR#                  [        R$                  U5        UR#                  [        R&                  [        R(                  U05        UR+                  [-        U R.                  5      U R0                  5        U R3                  U5      $ ! [4         a  n[5        U< SU< SU< 35      eS	nAff = f)
A
Build and TX a RTM_NEWLINK message to add the desired interface
: netlink: ip link add dev  type  (with attributes)attributes: %sr  r!  r   z: cannot create link N)r  r  rl   r   r
   r   r   r   r   r   r"  r#  rW   r  r$  r`   ry   r)  r  r   r   r*  r+  r,  r  r
  ru   )	r1   r4   r8  iflarl   r  nl_attrr   r   s	            r%   r7  1NetlinkListenerWithCache.link_add_with_attributesk	  sa    KK\bdjlpqrKK.56KK&RXZ^_`	Z4::-EUnnED%5	ADJIv/?/?AqIDI"&tzz|"4""72 #5 t//8t11##T4  tDMM2DHH=LLTRR 	Z66SWXYY	Zs   5D3F) )
G3G		Gc                 t    U R                  USU< SU< 35        U R                  R                  SU-  5        g )Nnetlink: ip link add dev r>  r@  log_info_ifname_dry_runr  rl   )r1   r4   r8  rA  s       r%    link_add_with_attributes_dry_run9NetlinkListenerWithCache.link_add_with_attributes_dry_run	  s1    $$VV\^b-cd*T12r$   c           	      b    [        [        [        U R                  ;   U R                  S9n[        [
        -  Ul        [        R                  " S[        R                  SU[         R                  5      Ul        UR                  [         R                  U5        UR                  [!        U R"                  5      U R$                  5        U R'                  U5      nU R(                  R+                  X5        U$ ! [,         a.  n[/        USU< SU[         R                  :X  a  SOS< 3US9eS	nAff = f)
zG
Bring interface 'ifname' up (raises on error)
:param ifname:
:return:
r  =BxxxiLLr   zip link set dev  updownr4   N)r
   r   rl   r   r   r   r   r"  r#  rW   r  r   r$  r)  r  r*  r+  r,  r  r  rL   r   ru   r'   )r1   r4   r   r  r  r   s         r%   __link_set_flag(NetlinkListenerWithCache.__link_set_flag	  s    	[DJJ%>$..YD&2DJJ0@0@!UDKKXDIt//8tDMM2DHH===dCF JJ))&8M 	qVUVZVaVaMaTgmEm"nw}~~	s   C3C6 6
D. )D))D.c                     U R                   R                  U5      (       dB  U R                  R                  U< SU< S35        U R	                  U[
        R                  S9  g g N: netlink: ip link set dev z upr   )rL   r   r  r  (_NetlinkListenerWithCache__link_set_flagr
   r   r   s     r%   link_up NetlinkListenerWithCache.link_up	  sJ    zz$$V,,KKVVTU  t{{ ; -r$   c                     U R                   R                  U< SU< S35        U R                  U[        R                  S9  g rS  )r  r  rV  r
   r   r   s     r%   link_up_force&NetlinkListenerWithCache.link_up_force	  s0    PQV4;;7r$   c                     U R                   R                  U5      (       a4  U R                  R                  U< SU< S35        U R	                  USS9  g g NrT  z downr   rU  )rL   r   r  r  rV  r   s     r%   	link_down"NetlinkListenerWithCache.link_down	  sF    ::  ((KKvvVW  q 1 )r$   c                 j    U R                   R                  U< SU< S35        U R                  USS9  g r]  )r  r  rV  r   s     r%   link_down_force(NetlinkListenerWithCache.link_down_force	  s,    66RSV1-r$   c                 .    U R                  USU-  5        g )Nznetlink: ip link set dev %s uprG  r   s     r%   link_up_dry_run(NetlinkListenerWithCache.link_up_dry_run	  s    $$V-MPV-VWr$   c                 .    U R                  USU-  5        g )Nz netlink: ip link set dev %s downrd  r   s     r%   link_down_dry_run*NetlinkListenerWithCache.link_down_dry_run	  s    $$V-ORX-XYr$   c                 &    U R                  U5        g rJ   )rh  r   s     r%   link_down_force_dry_run0NetlinkListenerWithCache.link_down_force_dry_run	  s    v&r$   c                    [         U R                  ;   n[        [         X0R                  S9n[        [
        -  Ul        [        R                  " S[        R                  SSS5      Ul        UR                  [        R                  U5        UR                  [        R                  U5        UR                  [!        U R"                  5      U R$                  5        U R'                  U5      $ )Nr  rK  r   )r   rl   r
   r   r   r   r   r"  r#  rW   r  r$  r)  r  r  r*  r+  r,  r  r  )r1   r4   staterl   r  s        r%   __link_set_protodown-NetlinkListenerWithCache.__link_set_protodown	  s    tzz)K..A"Y.
KK
F,<,<aAF	4++V44//74.977==r$   c                     U R                   R                  U5      S:X  a  gU R                  R                  U< SU< S35         U R	                  US5        g! [
         a  n[        USU-  US9eSnAff = f)z/
Bring ifname up by setting IFLA_PROTO_DOWN on
r   T: netlink: set link z protodown onzcannot set link %s protodown onrO  NrL   r  r  r  -_NetlinkListenerWithCache__link_set_protodownru   r'   r   s      r%   link_set_protodown_on.NetlinkListenerWithCache.link_set_protodown_on	  ss     ::((0A5FFST	]%%fa0 	]q"Cf"LU[\\	]   A 
A5"A00A5c                     U R                   R                  U5      S:X  a  gU R                  R                  U< SU< S35         U R	                  US5        g! [
         a  n[        USU-  US9eSnAff = f)z1
Take ifname down by setting IFLA_PROTO_DOWN off
r   Trr  z protodown offz cannot set link %s protodown offrO  Nrs  r   s      r%   link_set_protodown_off/NetlinkListenerWithCache.link_set_protodown_off	  ss     ::((0A5VVTU	^%%fa0 	^q"Dv"MV\]]	^rw  c                 .    U R                  USU-  5        g )Nz!netlink: set link %s protodown onrd  r   s     r%   link_set_protodown_on_dry_run6NetlinkListenerWithCache.link_set_protodown_on_dry_run	  s    $$V-PSY-YZr$   c                 .    U R                  USU-  5        g )Nz"netlink: set link %s protodown offrd  r   s     r%   link_set_protodown_off_dry_run7NetlinkListenerWithCache.link_set_protodown_off_dry_run	  s    $$V-QTZ-Z[r$   c                     U R                   R                  U5      nU R                  R                  U< SU< 35        [        U R
                  ;   n[        [        X0R                  S9n[        [        -  Ul
        [        R                  " S[        R                  USS5      Ul        UR!                  [#        U R$                  5      U R&                  5         U R                   R)                  U5        U R+                  U5      nU R                   R-                  U5        U$ ! [.         a    U R                   R1                  U5        e f = f! [.         a  n[3        USU-  US9eSnAff = f)z2
Send RTM_DELLINK request
:param ifname:
:return:
z: netlink: ip link del r  r!  r   zcannot delete link %srO  N)rL   r   r  r  r   rl   r
   r   r   r   r   r"  r#  rW   r  r$  r*  r+  r,  r  r   r  r  ru   r   r'   )r1   r4   r   rl   r  r  r   s          r%   link_del!NetlinkListenerWithCache.link_del	  s(   	Sjj,,V4GKKffMN4::-EUnnED&2DJIv/?/?!QODItDMM2DHH= 

88@AA$G 

,,V4  

::6B	
  	Sq"9F"B6RR	Ss+   CE AD" "'E		E 
E)E$$E)c                 .    U R                  USU-  5        g )Nznetlink: ip link del %srd  r   s     r%   link_del_dry_run)NetlinkListenerWithCache.link_del_dry_run
  s    $$V-F-OPr$   c                 T   [         U R                  ;   n[        [         X@R                  S9n[        [
        -  Ul        [        R                  " S[        R                  SSS5      Ul        UR                  [        R                  U5        UR                  [        R                  U5        UR                  [!        U R"                  5      U R$                  5        U R'                  U5      nU(       a  U R(                  R+                  X15        U$ U R(                  R-                  XS9  U$ )Nr  rK  r   )rz   r{   )r   rl   r
   r   r   r   r   r"  r#  rW   r  r$  r)  r  rt   r*  r+  r,  r  r  rL   r  r   )r1   r4   master_ifindexr  rl   r  r  s          r%   __link_set_master*NetlinkListenerWithCache.__link_set_master!
  s    tzz)K..A"Y.
KK
F,<,<aAF	4++V44++^<4.999$?
 JJ&&}=  JJ222Vr$   c                     U R                   R                  U< SU< SU< 35         U R                  XR                  R	                  U5      US9  g ! [
         a  n[        USU< SU< 3US9eS nAff = f)NrT   master )r  zcannot enslave link z to rO  )r  r  *_NetlinkListenerWithCache__link_set_masterrL   r   ru   r'   )r1   r4   r  r   s       r%   link_set_master(NetlinkListenerWithCache.link_set_master4
  sm    PVXefg	k""6::+A+A-+P`m"n 	kqFM"Zcijj	ks   )A 
A4A//A4c                    U R                   R                  U< SU< S35         U R                  R                  U5        U R	                  US5        g ! [
         a.  nU R                  R                  U5        [        USU-  US9eS nAff = f)NrT  z	 nomasterr   zcannot un-enslave link %srO  )r  r  rL   r   r  ru   r   r'   r   s      r%   link_set_nomaster*NetlinkListenerWithCache.link_set_nomaster;
  sz    vvVW	WJJ66v>""61- 	WJJ88@q"="FvVV	Ws   -A 
B)BBc                 8    U R                  USU< SU< 35        g )Nnetlink: ip link set dev r  rd  )r1   r4   
master_devs      r%   link_set_master_dry_run0NetlinkListenerWithCache.link_set_master_dry_runD
  s    $$VX^`j-klr$   c                 .    U R                  USU-  5        g )Nz$netlink: ip link set dev %s nomasterrd  r   s     r%   link_set_nomaster_dry_run2NetlinkListenerWithCache.link_set_nomaster_dry_runG
  s    $$V-SV\-\]r$   c                 8    U R                  USU< SU< 35        g )Nr  	 address rd  )r1   r4   
hw_addresss      r%   link_set_address_dry_run1NetlinkListenerWithCache.link_set_address_dry_runL
  s    $$VY_ak-lmr$   c                 B   U R                   R                  U5      n U(       a  U R                  U5        U R                  R	                  U< SU< SU< 35        [
        U R                  ;   n[        [
        X@R                  S9n[        [        -  Ul        [        R                  " S[        R                  SSS5      Ul        UR#                  [        R$                  U5        UR#                  [        R&                  U5        UR)                  [+        U R,                  5      U R.                  5        U R1                  U5      U(       a  U R3                  U5        $ $ ! [4         a  n[7        USU< SU< 3US9eS nAff = f! U(       a  U R3                  U5        f f = f)NrT  r  r  r!  r   zcannot set dev rO  )rL   r   ra  r  r  r   rl   r
   r   r   r   r   r"  r#  rW   r  r$  r)  r  r
  r*  r+  r,  r  r  rZ  ru   r'   )r1   r4   r  
is_link_uprl   r  r   s          r%   link_set_address)NetlinkListenerWithCache.link_set_addressO
  s@   ZZ**62
	+$$V,KKVU[]ghi4::-EUnnED&2DJIv/?/?AqIDIt//8t00*=tDMM2DHH=;;DA ""6*   	hqFJ"W`fgg	h ""6* s$   D'E 
F (E;;F  F F)privatevepar   passthrusourcec                    U R                   R                  U< SU< SU< SU(       a  UOS< 35         U R                  R                  U5      n[        U R
                  ;   n[        [        XPR                  S9n[        [        -  [        -  Ul        [        R                  " S[        R                  SSS5      Ul        UR#                  [        R$                  U5        U(       a   UR#                  [        R&                  U5        UR#                  [        R(                  [        R*                  S[        R,                  [        R.                  U R0                  R3                  U[        R4                  5      005        UR7                  [9        U R:                  5      U R<                  5        U R?                  U5      $ ! [@         a%  n[A        S	U< S
U< S[C        U5      < 35      eS nAff = f)N: netlink: ip link add link  name  type macvlan mode r  r  r!  r   macvlan	netlink: z: cannot create macvlan r+   )"r  r  rL   r   r   rl   r
   r   r   r   r   r   r"  r#  rW   r  r$  r)  r  rE  r   r   r-  IFLA_MACVLAN_MODE'_NetlinkListenerWithCache__macvlan_moder   MACVLAN_MODE_PRIVATEr*  r+  r,  r  r
  ru   r-   )r1   r4   macvlan_ifnamemacvlan_moder   rl   r  r   s           r%   link_add_macvlan)NetlinkListenerWithCache.link_add_macvlanr
  sw   v~||QZ/Z\	
	jj,,V4G4::-EUnnED%5	ADJIv/?/?AqIDIt//8""4>>7;t11##Y##**D,?,?,C,C$11-&4  tDMM2DHH=LLTRR 	>3q63 	s   F
G   
G/
 G**G/c           	      R    U R                  USU< SU< SU(       a  UOS< 35        g)Nnetlink: ip link add link r  r  r  Trd  )r1   r4   macvlan_ifamer  s       r%   link_add_macvlan_dry_run1NetlinkListenerWithCache.link_add_macvlan_dry_run
  s,    $$}ll	&QS	

 r$   c           
         U R                   R                  U< SU< SU< 35        [        U R                  ;   n[	        [        X0R
                  S9n[        [        -  [        -  Ul	        [        R                  " S[        R                  SSS5      Ul        UR                  [        R                   U5        UR                  [        R"                  [        R$                  S[        R&                  [        R(                  [+        U5      005        UR-                  [/        U R0                  5      U R2                  5        U R5                  U5      $ )Nr=   type vrf table r  r!  r   rI  )r  r  r   rl   r
   r   r   r   r   r   r"  r#  rW   r  r$  r)  r  r   r   r-  rJ  r   r*  r+  r,  r  r
  )r1   r4   	vrf_tablerl   r  s        r%   link_add_vrf%NetlinkListenerWithCache.link_add_vrf
  s    PVX^`ijktzz)K..A!M1I=
KK	6+;+;Q1E	4++V44--##S^"0
 	 	4.9HHNNr$   c                 8    U R                  USU< SU< 35        g)NrE  r  Trd  )r1   r4   r  s      r%   link_add_vrf_dry_run-NetlinkListenerWithCache.link_add_vrf_dry_run
  s    $$V`fhq-rsr$   c                    U R                   R                  U< SU< S35        [        U R                  ;   n[	        [        X0R
                  S9n[        [        -  [        -  Ul	        [        R                  " S[        R                  SSS5      Ul        UR                  [        R                   U5        U(       aB  U R                   R                  U< SU< 35        UR                  [        R"                  U5        UR                  [        R$                  [        R&                  S05        UR)                  [+        U R,                  5      U R.                  5        U R1                  U5      $ )Nr=  z type bridger  r!  r   z: netlink: set bridge mtu r   )r  r  r   rl   r
   r   r   r   r   r   r"  r#  rW   r  r$  r)  r  r   r   r   r*  r+  r,  r  r
  )r1   r4   r   rl   r  s        r%   link_add_bridge(NetlinkListenerWithCache.link_add_bridge
  s   &RXYZtzz)K..A!M1I=
KK	6+;+;Q1E	4++V4KKMNt}}c24--0
 	 	4.9HHNNr$   c                 .    U R                  USU-  5        g)Nz'netlink: ip link add dev %s type bridgeTrd  r   s     r%   link_add_bridge_dry_run0NetlinkListenerWithCache.link_add_bridge_dry_run
  s    $$V-VY_-_`r$   c                 <   U R                   R                  U< SU< S35        U R                   R                  SU-  5         [        U R                  ;   n[	        [        X0R
                  S9n[        [        -  [        -  Ul	        [        R                  " S[        R                  SSS5      Ul        UR                  [        R                   U5        UR                  [        R"                  [        R$                  S[        R&                  U05        UR)                  [+        U R,                  5      U R.                  5        U R1                  U5      nU R2                  R5                  X5        U$ ! [6         a   n[7        U< S[9        U5      < 35      eS nAff = f)	NrT  z type bridge (with attributes)r@  r  r!  r   r   z3: netlink: cannot create bridge or set attributes: )r  r  rl   r   r
   r   r   r   r   r   r"  r#  rW   r  r$  r)  r  r   r   r-  r*  r+  r,  r  r  rL   r  ru   r-   )r1   r4   r  rl   r  r  r   s          r%   link_set_bridge_info_data2NetlinkListenerWithCache.link_set_bridge_info_data
  sB   v	
 	*^;<	j4::-EUnnED%5	ADJIv/?/?AqIDIt//8t11##X##^4  tDMM2DHH===dCFJJ,,VDM 	jY_adefaghii	js   D-E1 1
F;FFc                 j    U R                  USU-  5        U R                  R                  SU-  5        g )Nz9netlink: ip link add dev %s type bridge (with attributes)r@  rF  )r1   r4   r  link_just_createds       r%   !link_set_bridge_info_data_dry_run:NetlinkListenerWithCache.link_set_bridge_info_data_dry_run
  s1    $$V-hkq-qr*^;<r$   c                     U R                   R                  U< SU< SU< 35         U R                  R                  U5      nU R	                  [
        X2SS9  g! [         a  n[        USU-  US9eSnAff = f)z#
Add VLAN(s) to a bridge interface
z: netlink: bridge vlan add vid  dev Tr/  zcannot add bridge vlan %srO  N)r  r  rL   r   r4  r   ru   r'   r1   r4   r  r   r   s        r%   link_add_bridge_vlan-NetlinkListenerWithCache.link_add_bridge_vlan
  sv     	QXZ`ab	Xjj,,V4G['M 	Xq"="GPVWW	X   0A 
A6#A11A6c                     U R                   R                  U< SU< SU< 35         U R                  R                  U5      nU R	                  [
        X2SS9  g! [         a  n[        USU-  US9eSnAff = f)z(
Delete VLAN(s) from a bridge interface
z: netlink: bridge vlan del vid r  Tr  zcannot remove bridge vlan %srO  N)r  r  rL   r   r4  r   ru   r'   r  s        r%   link_del_bridge_vlan-NetlinkListenerWithCache.link_del_bridge_vlan
  sv     	QXZ`ab	[jj,,V4G['M 	[q"@7"JSYZZ	[r  c                 8    U R                  USU< SU< 35        g )Nznetlink: bridge vlan add vid r  rd  r1   r4   r  s      r%   link_add_bridge_vlan_dry_run5NetlinkListenerWithCache.link_add_bridge_vlan_dry_run      $$VY`bh-ijr$   c                 8    U R                  USU< SU< 35        g )Nznetlink: bridge vlan del vid r  rd  r  s      r%   link_del_bridge_vlan_dry_run5NetlinkListenerWithCache.link_del_bridge_vlan_dry_run
  r  r$   c                 l    U(       a/  U R                   R                  U< SU< SU< SU< SU< 3	5        O*U R                   R                  U< SU< SU< SU< 35        SU;   a2  [        UR                  S5      S   5      nXS:w  a  [	        SX%U4-  5      eU R
                  R                  U5      n[        R                  U0nU(       a  XG[        R                  '   [        U R                  ;   n[        [        XR                  S9n	[        [        -  [        -  U	l        ["        R$                  " S	[&        R(                  S
S
S
5      U	l        U	R-                  [        R.                  U5        U	R-                  [        R0                  U5        U	R-                  [        R2                  [        R4                  S[        R6                  U05        U	R9                  [;        U R<                  5      U R>                  5        U RA                  U	5      $ ! [         a  n
[C        U
SU< SU< 3US9eSn
A
ff = f)L  
ifindex is the index of the parent interface that this sub-interface
is being added to

If you name an interface swp2.17 but assign it to vlan 12, the kernel
will return a very misleading NLE_MSG_OVERFLOW error.  It only does
this check if the ifname uses dot notation.

Do this check here so we can provide a more intuitive error
r  r   type vlan id 
 protocol .z;Interface %s must belong to VLAN %d (VLAN %d was requested)r  r!  r   vlanzcannot create vlan rL  rO  N)"r  r  r   rH  ru   rL   r   r
   IFLA_VLAN_IDIFLA_VLAN_PROTOCOLr   rl   r   r   r   r   r   r"  r#  rW   r  r$  r)  r  rE  r   r   r-  r*  r+  r,  r  r
  r'   )r1   vlan_raw_devicer4   r  vlan_protocolifname_vlanidr   r  rl   r  r   s              r%   link_add_vlan&NetlinkListenerWithCache.link_add_vlan  s   (	a  $*OVWm"] ^   $*OVW"N O f} #FLL$5b$9 : +#U!':; 
 jj,,_=G"//9N:Gt6674::-EUnnED%5	ADJIv/?/?AqIDIt//8t~~w7t11##V##^4  tDMM2DHH=LLTRR 	aq"PY_``	as   HH 
H3H..H3c                     U(       a#  U R                  USU< SU< SU< SU< 35        gU R                  USU< SU< SU< 35        g)r  r  r  r  r  Nrd  )r1   r  r4   r  r  s        r%   link_add_vlan_dry_run.NetlinkListenerWithCache.link_add_vlan_dry_runD  sF     (("FG]D (("FG5r$   c           	         U R                   R                  U< SU< SUR                  [        R                  5      < S35        U R                   R                  SU-  5        [        U R
                  ;   n[        [        X0R                  S9n[        [        -  [        -  Ul        [        R                  " S[        R                  SSS5      Ul        UR#                  [        R$                  U5        UR#                  [        R&                  [        R(                  S[        R*                  U05        UR-                  [/        U R0                  5      U R2                  5        U R5                  U5      $ )	a  
        cmd = ["ip link add %s type vxlan id %s" % (ifname, id)]

        if port:
            cmd.append("dstport %s" % port)
            info_data[nlpacket.Link.IFLA_VXLAN_PORT] = int(port)

        if local:
            cmd.append("local %s" % local)
            info_data[nlpacket.Link.IFLA_VXLAN_LOCAL] = local

        if ageing:
            cmd.append("ageing %s" % ageing)
            info_data[nlpacket.Link.IFLA_VXLAN_AGEING] = int(ageing)

        if group:
            if group.ip.is_multicast:
                cmd.append("group %s" % group)
            else:
                cmd.append("remote %s" % group)
            info_data[nlpacket.Link.IFLA_VXLAN_GROUP] = group
        else:
            cmd.append("noremote")

        if not learning:
            cmd.append("nolearning")
        info_data[nlpacket.Link.IFLA_VXLAN_LEARNING] = int(learning)

        if physdev:
            cmd.append("dev %s" % physdev)
            info_data[nlpacket.Link.IFLA_VXLAN_LINK] = self.cache.get_ifindex(physdev)

        if ttl:
            cmd.append("ttl %s" % ttl)
            info_data[nlpacket.Link.IFLA_VXLAN_TTL] = ttl

        self.logger.info('%s: netlink: %s' % (ifname, " ".join(cmd)))

:param ifname:
:param info_data:
:return:
r=   type vxlan id r?  r@  r  r!  r   vxlan)r  r  r   r
   IFLA_VXLAN_IDrl   r   r   r   r   r   r   r"  r#  rW   r  r$  r)  r  r   r   r-  r*  r+  r,  r  r
  )r1   r4   	info_datarl   r  s        r%   link_add_vxlan_with_info_data6NetlinkListenerWithCache.link_add_vxlan_with_info_data_  s   V 	vy}}T-?-?@B	
 	*Y67tzz)K..A!M1I=
KK	6+;+;Q1E	4++V44--0
 	 	4.9HHNNr$   c           	          U R                  USU< SUR                  [        R                  5      < S35        U R                  R                  SU-  5        g)NrE  r  r?  r@  T)rG  r   r
   r  r  rl   )r1   r4   r  s      r%   %link_add_vxlan_with_info_data_dry_run>NetlinkListenerWithCache.link_add_vxlan_with_info_data_dry_run  sI    $$y}}T%7%78:	

 	*Y67r$   c                    U R                   R                  U< SU< S35        U R                   R                  SU-  5         [        U R                  ;   n[	        [        X0R
                  S9n[        [        -  [        -  Ul	        [        R                  " S[        R                  SSS5      Ul        UR                  [        R                   U5        UR                  [        R"                  [        R$                  S[        R&                  U05        UR)                  [+        U R,                  5      U R.                  5        U R1                  U5      $ ! [2         a   n[3        U< S[5        U5      < 35      eS nAff = f)	Nr=  z type bond (with attributes)r@  r  r!  r   rU  z/: netlink: cannot create bond with attributes: )r  r  rl   r   r
   r   r   r   r   r   r"  r#  rW   r  r$  r)  r  r   r   r-  r*  r+  r,  r  r
  ru   r-   )r1   r4   r  rl   r  r   s         r%   link_add_bond_with_info_data5NetlinkListenerWithCache.link_add_bond_with_info_data  s,   v	
 	*^;<	f4::-EUnnED%5	ADJIv/?/?AqIDIt//8t11##V##^4  tDMM2DHH=LLTRR 	fU[]`ab]cdee	fs   DE 
E>E99E>c                 j    U R                  USU-  5        U R                  R                  SU-  5        g )Nz7netlink: ip link add dev %s type bond (with attributes)r@  rF  r  s      r%   $link_add_bond_with_info_data_dry_run=NetlinkListenerWithCache.link_add_bond_with_info_data_dry_run  s1    $$V-fio-op*^;<r$   c                    U R                   R                  U< SU< S35        U R                   R                  SU-  5         [        U R                  ;   n[	        [        XPR
                  S9n[        [        -  [        -  Ul	        [        R                  " S[        R                  SSS5      Ul        U(       a   UR                  [        R                   U5        [#        5       nU(       a$  X'[        R$                  '   X7[        R&                  '   SU[        R(                  '   XG[        R*                  '   UR                  [        R,                  U5        UR/                  [1        U R2                  5      U R4                  5        U R7                  U5      $ ! [8         a%  n[9        SU< S	U< S
[;        U5      < 35      eSnAff = f)r<  rT  z: bridge port attributesr@  r  r!  r   r   r  z: cannot set z (bridge slave) with options: N)r  r  rl   r   r
   r   r   r   r   r   r"  r#  rW   r  r$  r)  r  dictr   r-  r'  r6  r   r*  r+  r,  r  r  ru   r-   )	r1   r4   r8  r  ifla_info_slave_datarl   r  rL  r   s	            r%   $link_set_brport_with_info_slave_data=NetlinkListenerWithCache.link_set_brport_with_info_slave_data  sY    	V\^def*-AAB	s4::-EUnnED%5	ADJIv/?/?AqIDI""4#3#3V<vH04,,-0>,,-2:HT../2FT../t118<tDMM2DHH=
 ;;DAA 	s\`bhjmnojpqrr	ss   EF 
G F??Gc                 j    U R                  USU-  5        U R                  R                  SU-  5        g )Nz3netlink: ip link set dev %s: bridge port attributesr@  rF  )r1   r4   r8  r  r  s        r%   ,link_set_brport_with_info_slave_data_dry_runENetlinkListenerWithCache.link_set_brport_with_info_slave_data_dry_run  s2    $$V-bek-kl*-AABr$   c                 j   SU< SU< 3/nU(       a  UR                  SU-  5        U(       a  UR                  SU-  5        U(       a  UR                  SU-  5        U(       a  UR                  SU-  5        U(       a  UR                  SU-  5        U R                  USR                  U5      5        g )	Nznetlink: ip addr add r  scope %sbroadcast %spreferred_lft %speer %s	metric %srL  )r,   rG  r0   )	r1   r4   r  	broadcastpeerrX  preferred_lifetimemetriclog_msgs	            r%   addr_add_dry_run)NetlinkListenerWithCache.addr_add_dry_run  s    7;VDENN:-.NN>I56NN-0BBCNN9t+,NN;/0$$VSXXg->?r$   c           
         U< SU< SU< 3/nSn	 U R                   R                  X5      (       a  g U(       a,  UR                  SU-  5        [        R                  " US5      n
OSn
[
        U R                  ;   n[        [
        XR                  S9n[        [        -  [        -  Ul        U R                  R	                  UR                  5      Ul        UR!                  [        R"                  U5        UR!                  [        R$                  U5        U(       a4  UR                  SU-  5        UR!                  [        R&                  U5        U(       a_  UR                  SU-  5        UR)                  5       S	:X  a  [*        nUR!                  [        R,                  [/        U5      [*        SS45        U(       a=  UR                  S
U-  5        UR!                  [        R0                  [/        U5      5        U(       aA  UR                  SU-  5        UR!                  [        R"                  U5        UR2                  nOUR2                  nU R4                  R7                  SR9                  U5      5        Sn	[:        R<                  " SUR                  USXR                   R?                  U5      5      Ul         URC                  [E        U RF                  5      U RH                  5        U RK                  U5      $ ! [L         aC  nU	(       d$  [N        R7                  SR9                  U5      5        [Q        USU< SU< 3US9eS nAff = f)Nz: netlink: ip addr add r  Fr  r   r  r  r  foreverr  r  rL  T=4Bizcannot add address rO  ))rL   re  r,   r   r   r   rl   r   r   r   r   r   r   r  r  r  r)  r  r  rx  r  r   IFA_CACHEINFOr   IFA_RT_PRIORITYrb  r  r  r0   r"  r#  r   r$  r*  r+  r,  r  r  ru   rk   r'   )r1   r4   r  r  r  rX  r  r  r  log_msg_displayedscope_valuerl   r  packet_prefixlenr   s                  r%   addr_add!NetlinkListenerWithCache.addr_add  s   ;A4PQ!>	b zz((66zE12'mmE154::-E[%>>JF'-7)CFL <<@@NFM  !4!4d;  !2!2D9~	9:$$W%:%:IF! 14FFG%++-:);&$$W%:%:SAS=TVhjkmn<op{V34$$W%<%<c&kJy4/0$$W%8%8$?#'>> #'>> KKSXXg./ $ ++ffmm=MqR]_i_i_u_uv|_}~FK  dmm!4dhh?;;FCC 	b$ '*+qD&"QZ`aa	bs    K= K	K= =
M
>MM
c                 8    U R                  USU< SU< 35        g )Nznetlink: ip addr del r  rd  r1   r4   r  s      r%   addr_del_dry_run)NetlinkListenerWithCache.addr_del_dry_runH  s    $$VQUW]-^_r$   c           
      >   U R                   R                  X5      (       d  g U R                  R                  U< SU< SU< 35         [        U R
                  ;   n[        [        X0R                  S9n[        [        -  Ul
        U R                  R                  UR                  5      Ul        [        R                   " SUR                  UR"                  SSU R                   R%                  U5      5      Ul        UR)                  [        R*                  U5        UR-                  [/        U R0                  5      U R2                  5        U R5                  U5      nU R                   R7                  X5        U$ ! [8         a  n[;        USU< SU< 3US9eS nAff = f)Nz: netlink: ip addr del r  r  r  r   zcannot delete address rO  )rL   re  r  r  r   rl   r   r   r   r   r   r  r   r  r  r"  r#  rb  r   r$  r)  r  r*  r+  r,  r  r  r  ru   r'   )r1   r4   r  rl   r  r  r   s          r%   addr_del!NetlinkListenerWithCache.addr_delK  s8   zz((66vVW	e4::-E[%>>JF(94FL <<@@NFM ++ffmmT^^QPQSWS]S]SiSijpSqrFK  !2!2D9  dmm!4dhh?==fEF JJ((6M 	eqtV"T]cdd	es   	D0E: :
FFFc                     U R                   R                  U5       H  n U R                  X5        M     g! [         a     M'  f = f)a  
From iproute2/ip/ipaddress.c
    /*
     * Note that the kernel may delete multiple addresses for one
     * delete request (e.g. if ipv4 address promotion is disabled).
     * Since a flush operation is really a series of delete requests
     * its possible that we may request an address delete that has
     * already been done by the kernel. Therefore, ignore EADDRNOTAVAIL
     * errors returned from a flush request
     */
N)rL   r'  r&  ru   r"  s      r%   
addr_flush#NetlinkListenerWithCache.addr_flushd  sB     JJ//7Df+ 8  s   6
AAc                    U R                  S5        U R                  S5        [        R                  R	                  [
        5        [        R                  R	                  [
        5        [        R                  R	                  [
        5        g )NT)
debug_linkdebug_addressr   rk   r   r   r   r   rh   s    r%   DEBUG_ON!NetlinkListenerWithCache.DEBUG_ONz  sR    4 &e$u%r$   c                    U R                  S5        U R                  S5        [        R                  R	                  [
        5        [        R                  R	                  [
        5        [        R                  R	                  [
        5        g rn  )r-  r,  r   rk   r   r   r   r   rh   s    r%   	DEBUG_OFF"NetlinkListenerWithCache.DEBUG_OFF  sR    5!(g&w'r$   )	r  rL   r  r  r  r  r  r  r  )NFFFFrJ   )NNNNN)Zr   r   r    r!   r  VXLAN_UDP_PORTr{  r  r  r  r/   r  r  r  r  r  r  r  r  r  r  r  r  r
  r  r  r  r  r4  r9  r7  rH  rV  rW  rZ  r^  ra  re  rh  rk  rt  ru  ry  r|  r  r  r  r  r  r  r  r  r  r  r
   r  MACVLAN_MODE_VEPAMACVLAN_MODE_BRIDGEMACVLAN_MODE_PASSTHRUMACVLAN_MODE_SOURCEr  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r#  r&  r)  r.  r1  r#   r9   r:   s   @r%   r}  r}    s   JN& & 3 3 9 9KZ*7r&!P
1%(.$$'2#h$82
+++3>r8Z83@<
82
.XZ'
>]^[\
$SLQ
&kWm^
n+8 ,,&&**..**N"HO$O(j4=
X	[kk
3aj6;Ozf,="sHC@(AbJ`e2,&( (r$   r}  )Br   rW   r"  r  r   r   	ipaddressr[   r   r   r   collectionsr   ifupdown2.lib.sysfsr   ifupdown2.lib.base_objectsr   ifupdown2.nlmanager.nlpacketr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ifupdown2.nlmanager.ipnetworkr   rE  r   ifupdown2.nlmanager.nllistenerr   ifupdown2.nlmanager.nlmanagerifupdown2.ifupdown.statemanagerifupdownrU  ImportErrorModuleNotFoundError	lib.sysfslib.base_objectsnlmanager.nlpacketnlmanager.ipnetworknlmanager.nllistenernlmanager.nlmanagerifupdown.statemanagerr   rk   ru   r   r'   r<   rA   rD   rG   r  r}  r   r$   r%   <module>rK     s2  6 
         " #;1)5     * 65337755::B 	) 	Q9 Q		 		&7 		'8 	L L^8l(zDDj l(i: 	() 1+     * ,)-+0;1s   A#D   AEE