
    x[h                        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J	r	J
r
Jr  S SKJrJr  S SKJr  \R"                  " \5      rSrSr/ SQr/ SQr\R0                  " S	5      4S
 jrS rSdS jr    SeS jrSfS jrS rS rS r S r!S r"S r#S r$S r%\RL                  " SS9S\'4S j5       r(\RL                  " SS9S\)4S j5       r*S\+S\'4S jr,SfS jr-S r.S r/SfS\'4S  jjr0SfS! jr1SfS" jr2S# r3S$ r4S% r5S& r6S' r7 " S( S)\85      r9S* r:S\	\+   4S+ jr;S\
\+   4S, jr<S\	\+   4S- jr=S\
\+   4S. jr>S\	\+   4S/ jr?S\
\+   4S0 jr@S\	\+   4S1 jrAS\
\+   4S2 jrBSfS\
\C   4S3 jjrDS4 rESgS5 jrFShS6 jrG SiS7 jrHS8 rIS9 rJS\C4S: jrKS;\+S\
\+   4S< jrLS\C4S= jrMS\C4S> jrNS\C4S? jrOS\C4S@ jrP       SjSA\'SB\'SC\'SD\'SE\'SF\'SG\'S\)4SH jjrQSI\SJ   SK\	\\+\+\+\+4      SS4SL jrRSM rSSN\SO\+4SP jrTSO\+S\'4SQ jrUSO\+S\'4SR jrVSO\+S\'4SS jrWSO\+S\'4ST jrXSO\+S\'4SU jrYSO\+S\'4SV jrZSO\+SW\+S\'4SX jr[SY\+SW\+S\'4SZ jr\S\'4S[ jr]S\+4S\ jr^S\_4S] jr`S\_4S^ jraS_\+S`\+S\+4Sa jrb " Sb Sc\c5      rdg)k    N)CallableDictListOptionalTuple)subputil)Iproute2z/sys/class/net/eth0)dhcp6
ipv6_slaaczipv6_dhcpv6-statelesszipv6_dhcpv6-stateful)	ovs-vsctlz--formatcsvz--no-headingsz	--timeout10z	--columnsnamefind	interfaceztype=internalz([0-9]+)c                     [         R                  " X5       Vs/ s H3  nUR                  5       (       a  [        U5      OUR	                  5       PM5     sn$ s  snf )a0  Sorting for Humans: natural sort order. Can be use as the key to sort
functions.
This will sort ['eth0', 'ens3', 'ens10', 'ens12', 'ens8', 'ens0'] as
['ens0', 'ens3', 'ens8', 'ens10', 'ens12', 'eth0'] instead of the simple
python way which will produce ['ens0', 'ens10', 'ens12', 'ens3', 'ens8',
'eth0'].)resplitisdigitintlower)s_nsretexts      8/usr/lib/python3/dist-packages/cloudinit/net/__init__.pynatural_sort_keyr   +   sK     HHU&&D \\^^D	5&  s   :Ac                      [         $ )z3Simple function to return the global SYS_CLASS_NET.)SYS_CLASS_NET     r   get_sys_class_pathr#   8   s    r"   c                 (    [        5       U -   S-   U-   $ )N/)r#   devnamepaths     r   sys_dev_pathr)   =   s    ')C/$66r"   c                    [        X5      n [        R                  " U5      nUR                  5       nUc  U$  X'   $ ! [        [        4 al  n[        USS 5      n	U	[        R                  [        R                  4;   a  Ub  U" U5      s S nA$ U	[        R                  4;   a  Ub  U" U5      s S nA$ e S nAff = f! [         a-  nUb  U" U5      s S nA$ [        R                  SUU5        e S nAff = f)Nerrnoz5Found unexpected (not translatable) value '%s' in '%s)r)   r	   load_text_fileOSErrorIOErrorgetattrr+   ENOENTENOTDIREINVALstripKeyErrorLOGdebug)
r'   r(   	translate	on_enoenton_keyerror	on_einvaldev_pathcontentsee_errnos
             r   read_sys_netr?   A   s     G*H
&&x0 ~~H"" W !Wd+u||U]]33$ |#u||o%$ |#  	"q>!IIG
 	sP   = B< B9;B4B9B4-B93B44B9<
C3
C.C3C..C3c           	      $    S n[        U UUUUUS9$ )Nc                     gNFr!   )r=   s    r   on_excp_false(read_sys_net_safe.<locals>.on_excp_falseg   s    r"   )r9   r8   r:   r7   )r?   )ifacefieldr7   rC   s       r   read_sys_net_saferG   f   s(     ! r"   c                 \    [        X5      nUSL a  g  [        U5      $ ! [         a     g f = frB   )rG   r   
ValueError)rE   rF   vals      r   read_sys_net_intrK   t   s6    
E
)C
e|3x s   
 
++c                 $    SSSS.n[        U SUS9$ )NTF)upunknowndown	operstate)r7   rG   )r'   r7   s     r   is_uprR   ~   s     e<IWkYGGr"   c                 T    [         R                  R                  [        U S5      5      $ )Nbridgeosr(   existsr)   r'   s    r   	is_bridgerY      s    77>>,w9::r"   c                 T    [         R                  R                  [        U S5      5      $ )NbondingrU   rX   s    r   is_bondr\      s    77>>,w	:;;r"   c                 d    [        U SS9n[        R                  R                  U5      (       a  U$ g)z8Return the master path for devname, or None if no mastermasterr(   N)r)   rV   r(   rW   r&   s     r   
get_masterr`      s)    h/D	ww~~dr"   c                 *   [        U 5      nUc  g[        R                  R                  US5      n[        R                  R                  US5      n[        R                  R	                  U5      =(       d    [        R                  R	                  U5      $ )z@Return a bool indicating if devname's master is a bridge or bondFr[   rT   )r`   rV   r(   joinrW   )r'   master_pathbonding_pathbridge_paths       r   master_is_bridge_or_bondrf      sb    W%K77<<Y7L'',,{H5K77>>,'F277>>++FFr"   c                 r    [        U 5      nUc  g[        U SS9n[        R                  R	                  U5      $ )z;Return a bool indicating if devname's master is openvswitchFzupper_ovs-systemr_   )r`   r)   rV   r(   rW   )r'   rc   ovs_paths      r   master_is_openvswitchri      s5    W%KG*<=H77>>(##r"   c                      [        U S5      S:H  $ )Ntype32rQ   rX   s    r   is_ib_interfacerm      s    Wf-55r"   )maxsizereturnc                  |    [        [        R                  " S5      5      n U (       d  [        R	                  S5        U $ )zDReturn a bool indicating if Open vSwitch is installed in the system.r   z<ovs-vsctl not in PATH; not detecting Open vSwitch interfaces)boolr   whichr5   r6   )rets    r   openvswitch_is_installedrt      s0     tzz+&
'C		J	
 Jr"   c                       [         R                   " [        5      u  pU R                  5       $ ! [         R                   a2  nSUR                  ;   a  [
        R                  S5        / s SnA$ e SnAff = f)zReturn a list of the names of OVS internal interfaces on the system.

These will all be strings, and are used to exclude OVS-specific interface
from cloud-init's network configuration handling.
zdatabase connection failedzJOpen vSwitch is not yet up; no interfaces will be detected as OVS-internalN)r   !OVS_INTERNAL_INTERFACE_LOOKUP_CMD
splitlinesProcessExecutionErrorstderrr5   info)out_errexcs      r   get_ovs_internal_interfacesr~      sf     II?@	 ~~ %% '3::5HH  Is!   . A4&A/(A4.A//A4r'   c                 p    [        5       (       d  g[        5       nX;   a  [        R                  SU 5        gg)zxReturns True if this is an OVS internal interface.

If OVS is not installed or not yet running, this will return False.
FzDetected %s as an OVS interfaceT)rt   r~   r5   r6   )r'   ovs_bridgess     r   !is_openvswitch_internal_interfacer      s3    
 $%%-/K		3W=r"   c                 b    Uc  [        U 5      n[        X5      (       d  [        X5      (       a  gg)znetfailover driver uses 3 nics, master, primary and standby.
this returns True if the device is either the primary or standby
as these devices are to be ignored.
TF)device_driveris_netfail_primaryis_netfail_standbyr'   drivers     r   is_netfailoverr      s6    
 ~w''**.@/ / r"   c                 F    Sn [        U S5      nU$ ! [         a     U$ f = f)zDReturns a str from reading /sys/class/net/<devname>/device/features. zdevice/features)r?   	Exceptionr'   featuress     r   get_dev_featuresr      s9    H):; O  Os    
  c                 V    [        U 5      nU(       a  [        U5      S:  a  gUS   S:H  $ )zReturn True if VIRTIO_NET_F_STANDBY bit (62) is set.

https://github.com/torvalds/linux/blob/         089cf7f6ecb266b6a4164919a2e69bd2f938374a/         include/uapi/linux/virtio_net.h#L60
@   F>   1)r   lenr   s     r   has_netfail_standby_featurer      s.      (Hs8}r)B<3r"   c                 j    [        U 5      b  gUc  [        U 5      nUS:w  a  g[        U 5      (       d  gg)zA device is a "netfail master" device if:

- The device does NOT have the 'master' sysfs attribute
- The device driver is 'virtio_net'
- The device has the standby feature bit set

Return True if all of the above is True.
F
virtio_netTr`   r   r   r   s     r   is_netfail_masterr      s=     '&~w'&w//r"   c                 N   [        U SS9n[        R                  R                  U5      (       d  gUc  [	        U 5      nUS:X  a  g[        R                  R                  [        R                  R                  U5      5      n[	        U5      nUS:w  a  g[        U5      nU(       d  gg)a  A device is a "netfail primary" device if:

- the device has a 'master' sysfs file
- the device driver is not 'virtio_net'
- the 'master' sysfs file points to device with virtio_net driver
- the 'master' device has the 'standby' feature bit set

Return True if all of the above is True.
r^   r_   Fr   T)r)   rV   r(   rW   r   basenamerealpathr   )r'   r   master_sysfs_pathmaster_devnamemaster_drivermaster_has_standbys         r   r   r     s     %W8<77>>+,,~w'WW%%bgg&6&67H&IJN!.1M$4^Dr"   c                 j    [        U 5      c  gUc  [        U 5      nUS:w  a  g[        U 5      (       d  gg)zA device is a "netfail standby" device if:

- The device has a 'master' sysfs attribute
- The device driver is 'virtio_net'
- The device has the standby feature bit set

Return True if all of the above is True.
Fr   Tr   r   s     r   r   r   9  s=     '"~w'&w//r"   c                 8    [        U S5      nU(       a  US;   a  gg)a  
/* interface name assignment types (sysfs name_assign_type attribute) */
#define NET_NAME_UNKNOWN      0  /* unknown origin (not exposed to user) */
#define NET_NAME_ENUM         1  /* enumerated by kernel */
#define NET_NAME_PREDICTABLE  2  /* predictably named by the kernel */
#define NET_NAME_USER         3  /* provided by user-space */
#define NET_NAME_RENAMED      4  /* renamed by user-space */
name_assign_type)34TFrQ   )r'   r   s     r   
is_renamedr   Q  s#     )2DE,
:r"   c                 R    [        [        U S5      5      nSUR                  5       ;   $ )NueventzDEVTYPE=vlan)strrG   rw   )r'   r   s     r   is_vlanr   `  s(    "7H56FV..000r"   c                     Sn[        U S5      n[        R                  R                  U5      (       a3  [        R                  R	                  [        R
                  " U5      5      nU$ )z8Return the device driver for net device named 'devname'.Nzdevice/driver)r)   rV   r(   islinkr   readlink)r'   r   driver_paths      r   r   r   e  sH    Fw8K	ww~~k""!!"++k":;Mr"   c                 *    [        U S5      nUSL a  gU$ )z;Return the device id string for net device named 'devname'.zdevice/deviceFNrQ   )r'   dev_ids     r   device_devidr   p  s    w8FMr"   c                  `   [         R                  " 5       (       d  [         R                  " 5       (       a!  [        [	        5       R                  5       5      $  [        R                  " [        5       5      n U $ ! [         a,  nUR                  [        R                  :X  a  / n  S nAU $ e S nAff = fN)r	   
is_FreeBSDis_DragonFlyBSDlistget_interfaces_by_macvaluesrV   listdirr#   r-   r+   r0   )devsr=   s     r   get_devicelistr   y  s    D0022)+22455zz,./ K  77ell"D K 	s   A7 7
B- B('B((B-c                       \ rS rSrSrSrg)ParserErrori  z6Raised when a parser has issue parsing a file/content.r!   N)__name__
__module____qualname____firstlineno____doc____static_attributes__r!   r"   r   r   r     s    @r"   r   c                 d    U (       a  [        U [        5      (       d  gU R                  S5      S:H  $ )NFconfigdisabled)
isinstancedictget)cfgs    r   is_disabled_cfgr     s(    jd++778
**r"   c                     [         R                  " 5       (       d  [         R                  " 5       (       a
  [        5       $ [         R                  " 5       (       d  [         R
                  " 5       (       a
  [        5       $ [        5       $ )ziGet the list of network interfaces viable for networking.

@return List of interfaces, sorted naturally.
)r	   r   r   find_candidate_nics_on_freebsd	is_NetBSD
is_OpenBSD(find_candidate_nics_on_netbsd_or_openbsdfind_candidate_nics_on_linuxr!   r"   r   find_candidate_nicsr     sS    
 D0022-//			T__..799+--r"   c                     [         R                  " 5       (       d  [         R                  " 5       (       a
  [        5       $ [         R                  " 5       (       d  [         R
                  " 5       (       a
  [        5       $ [        5       $ )z.Get the name of the 'fallback' network device.)r	   r   r   find_fallback_nic_on_freebsdr   r   &find_fallback_nic_on_netbsd_or_openbsdfind_fallback_nic_on_linuxr!   r"   r   find_fallback_nicr     sQ    D0022+--			T__..577)++r"   c                  J    [        [        5       R                  5       [        S9$ )zeGet the names of the candidate network devices on NetBSD/OpenBSD.

@return list of sorted interfaces
key)sortedr   r   r   r!   r"   r   r   r     s    
 ')0028HIIr"   c                  0    [        5       n U (       a  U S   $ g)z^Get the 'fallback' network device name on NetBSD/OpenBSD.

@return default interface, or None
r   N)r   namess    r   r   r     s    
 56EQxr"   c                      [         R                   " / SQ5      u  pU R                  5       nU(       a  U$ [        [        5       R	                  5       [
        S9$ )z_Get the names of the candidate network devices on FreeBSD.

@return List of sorted interfaces.
)ifconfigz-lz-uetherr   )r   r   r   r   r   r   )stdout_stderrr   s      r   r   r     sE    
 ii ABOF\\^F ')0028HIIr"   c                  0    [        5       n U (       a  U S   $ g)zWGet the 'fallback' network device name on FreeBSD.

@return List of sorted interfaces.
r   N)r   r   s    r   r   r     s    
 +,EQxr"   c            	         S[         R                  " 5       ;   a  [        R                  S5        Oo[	        5        V s/ s H  n U S:w  d  M  [        U 5      (       a  M  U PM!     nn [        U5      (       a+  [        R                  SU5        [         R                  " 5         / n/ n[        SSSSSSS9 H  u  n    nUS:X  a  M  UR                  S5      (       a  [        R                  S	U5        M>  [        US
5      nU(       a  UR                  U5        Md  [        R                  SU5        [        US5      nU(       a  UR                  U5        M  [        US5      nUS;   a  UR                  U5        M  [        R                  SU5        M     / n	X#4 HJ  n
[        U
[        S9n
[        U
;   a+  U
R!                  [        5        U
R#                  S[        5        X-  n	ML     U	$ s  sn f )z]Get the names of the candidate network devices on Linux.

@return List of sorted interfaces.
znet.ifnames=0z9Stable ifnames disabled by net.ifnames=0 in /proc/cmdlineloz4Found unstable nic names: %s; calling udevadm settleFT)filter_openvswitch_internal2filter_slave_if_master_not_bridge_bond_openvswitchfilter_vlanfilter_without_own_macfilter_zero_maclog_filtered_reasonsvethzIgnoring veth interface: %scarrierzInterface has no carrier: %sdormantrP   )r   rO   lowerlayerdownrN   zInterface ignored: %sr   r   )r	   get_cmdliner5   r6   r   r   r   udevadm_settleget_interfaces
startswithrK   appendrG   r   r   DEFAULT_PRIMARY_INTERFACEremoveinsert)deviceunstable	connectedpossibly_connectedr   _r   r   rP   sorted_interfaces
interfacess              r   r   r     s   
 $**,,		MN )*
*~ &0&8 * 	 

 x==IIF ! I,$);@$!	1a ''II3Y?"9i8Y'		0)< #9i8%%i0%i=	HH%%i0		)95=J  5
J,<=
$
278a!:;' 6 {
s   
G%
G%G%c                  0    [        5       n U (       a  U S   $ g)zUGet the 'fallback' network device name on Linux.

@return List of sorted interfaces.
r   N)r   r   s    r   r   r     s    
 )*EQxr"   c                     [        5       nU(       d  g[        U5      (       a  SU0nOS[        US5      R                  5       0nU (       a  [	        U5      nU(       a  X2S'   SSUUS.nX0SS	.nU$ )
zBGenerate network cfg v2 for dhcp on the NIC most likely connected.Nr   
macaddressaddressr   T)dhcp4r   set-namematch   )	ethernetsversion)r   r   rG   r   r   )config_drivertarget_namer  r   r   nconfs         r   generate_fallback_configr  +  s     $%K %%% +KCIIK
 {+$(O	C ',;ELr"   c                     S nS nU R                  S5      nUS:X  a  U" U 5      $ US:X  a  U" U 5      $ [        SU-  5      e)Nc                    / nU R                  S0 5       H  nUR                  S5      S:w  a  M  UR                  S5      nU(       d  M4  UR                  S5      nUR                  S0 5      R                  S5      nUR                  S0 5      R                  S5      nU(       d  [        U5      nU(       d  [        U5      nUR                  X4XV/5        M     U$ )	Nr   rk   physicalmac_addressr   paramsr   	device_id)r   r   r   r   )netcfgphysdevsentmacr   r   r  s          r   
_version_1$extract_physdevs.<locals>._version_1I  s    ::h+Cwwv*,''-(C776?DWWXr*..x8F"-11+>I&t,(.	OOS:; , r"   c                    / nU R                  S0 5      R                  5        H  nUR                  S5      nU(       d  M  UR                  S0 5      R                  S5      nU(       d  MG  UR                  S0 5      R                  S5      nUR                  S0 5      R                  S5      nU(       d  [        U5      nU(       d  [        U5      nUR	                  XCXV/5        M     U$ )Nr  r  r  r  r   r  )r   r   r   r   r   )r  r  r  r   r  r   r  s          r   
_version_2$extract_physdevs.<locals>._version_2[  s    ::k2.557C77:&D'''2&**<8CWWWb)--h7F,00=I&t,(.	OOS:; 8  r"   r     r  z"Unknown network config version: %s)r   RuntimeError)r  r  r  r  s       r   extract_physdevsr  H  sQ    $( jj#G!|&!!	A&!!
;gE
FFr"   c                 P    [        U S5      nUc  U(       a  [        S5      egUS;   $ )a  return True if the provided interface has its own address.

Based on addr_assign_type in /sys.  Return true for any interface
that does not have a 'stolen' address. Examples of such devices
are bonds or vlans that inherit their mac from another device.
Possible values are:
  0: permanent address    2: stolen from another device
1: randomly generated   3: set using dev_set_mac_addressaddr_assign_typez%s had no addr_assign_type.T)r   r     )rK   rI   )ifnamestrictassign_types      r   interface_has_own_macr%  x  s6     #6+=>K :;;)##r"   c           	         0 n[        5        H(  u  p#pESUUUR                  5       U[        U5      S.X'   M*     U (       a  [        R                  " S5      n[
        R
                  " / SQSS9u  px[
        R
                  " / SQSS9u  p[        5       n
Xy4 H#  nU
R                  UR                  U5      5        M%     UR                  5        H  nUS   S	L =(       d    US
   U
;  US'   M     U$ )a  Collect information necessary for rename_interfaces.

returns a dictionary by mac address like:
   {name:
     {
      'downable': None or boolean indicating that the
                  device has only automatically assigned ip addrs.
      'device_id': Device id value (if it has one)
      'driver': Device driver (if it has one)
      'mac': mac address (in lower case)
      'name': name
      'up': boolean: is_up(name)
     }}
N)downabler  r   r  r   rM   z[0-9]+:\s+(\w+)[@:])ipz-6addrshow	permanentscopeglobalT)capture)r(  z-4r)  r*  rM   Fr   r'  )
r   r   rR   r   compiler   setupdatefindallr   )check_downablecur_infor   r  r   r  nmatchipv6r|   ipv4nics_with_addresses	bytes_outds                r   _get_current_rename_infor;    s     H(6(8$6"99;+
 )9 23YYH

 YY;TJ
!eI&&v~~i'@A & "A$5 HAfI5H$H jM #
 Or"   c                   ^^ [        U 5      (       d  [        R                  S5        g Uc
  [        5       n0 mUR	                  5        HJ  u  pEUR                  5       nUR                  S5      (       a  US   R                  5       US'   XFS'   UTU'   ML     [        R                  ST5        S n/ n/ n	/ n
U" T5      nSnSnS mUU4S	 jnU  GH  u  nnnnU(       a  UR                  5       n/ nU" UUU5      nU(       d#  U(       a  U	R                  S
U< SU< S35        MV  UR                  S5      nUU:X  a  Mo  U(       d#  U(       a  U	R                  S
U< SU< S35        M  US   (       a]  SnUS   (       d   U(       a  U	R                  UUUU4-  5        M  SUS'   UR                  SUUU445        U
R                  SUUU445        UU;   a  UU   nUS   (       aC  SnUS   (       d!  U(       a  U	R                  UUUU4-  5        GMB  UR                  SUUU445        S nUb  UU;   a  US-  nX-  nUc  M  UU;   a  M  UR                  SUUUU445        UUS'   U" T5      nUS   (       a  U
R                  SUUU445        UR                  SUUUS   U445        UUS'   U" T5      nUU-  nGM     [        R                  [        R                  [        R                  S.nU(       dF  U
(       d?  [        U	5      (       a  [        R                  SU U	5        OI[        R                  SU 5        O2[        R                  SXU
-   5        X-    H  u  nnnn UU   " U6   M     [        U	5      (       a  [        SR!                  U	5      5      eg ! [         a/  nU	R                  SU< U< SU< SU< SU< 3	5         S nAMt  S nAff = f)Nzno interfaces to renamer  r   zDetected interfaces %sc                 B    [        S U R                  5        5       5      $ )Nc              3   .   #    U  H  oS    U4v   M     g7f)r   Nr!   ).0datas     r   	<genexpr><_rename_interfaces.<locals>.update_byname.<locals>.<genexpr>  s     D^T&\4(^s   )r   r   )bymacs    r   update_byname)_rename_interfaces.<locals>.update_byname  s    DU\\^DDDr"   z
cirename%dc                     U(       a4  U(       a-  U(       a&  U S   U:H  =(       a    U S   U:H  =(       a    U S   U:H  $ U(       a  U(       a  U S   U:H  =(       a    U S   U:H  $ U(       a  U S   U:H  $ g)zmatch if set and in datar  r   r  Fr!   )r@  r  r   r  s       r   entry_match'_rename_interfaces.<locals>.entry_match  sv    6iUs" 3Nf,3%2
 V;#%B$x.F*BB;#%%r"   c           	         > TR                  5        Vs/ s H  nT" X0X5      (       d  M  UPM     nn[        U5      (       a2  [        U5      S:  a  SU< SU < SU< SU< S3	n[        U5      eUS   $ g s  snf )Nr  z2Failed to match a single device. Matched devices "z" with search values "(mac:z driver:z device_id:z)"r   )r   r   rI   )r  r   r  r@  r  msgr4  rH  s         r   
find_entry&_rename_interfaces.<locals>.find_entry  s~     !)
)4f8 ) 	 

 u::5zA~ c696 
 !o%8O
s
   A5A5z$[nic not present] Cannot rename mac=z to z, not available.rM   z*[busy] Error renaming mac=%s from %s to %sr'  FrO   z2[busy-target] Error renaming mac=%s from %s to %s.r  rename)rN  rO   rM   z1Unable to rename interfaces: %s due to errors: %sz$no work necessary for renaming of %szRenamed %s with ops %sz[unknown] Error performing z for z, z: 
)r   r5   r6   r;  itemscopyr   r   r   r
   link_rename	link_downlink_upwarningr   r  rb   )renamesstrict_presentstrict_busycurrent_infor   r@  currD  opserrorsups
cur_bynametmpname_fmttmpirL  r  new_namer   r  cur_opscur_namerK  targettmp_nameopmapopr  r=   r4  rH  s                               @@r   _rename_interfacesrh    s    w<<		+,/1H"((*
iik775>>U))+CJF + II&1E CF
Cx(JKD$ -4(Xvy))+Cfi0*-x9 776?x*-x9 t9>Cz?MM#h(A"ABCINNFCH;?@JJc8h[9:z!)Fd|Jj)"cS(H,E&EFNNFCH;#GH&*H"h*&<	&- "h*&< NNHc8h5IJK%F6N&x0Jd|

D#x(=>#x#f+x1HIJF"8,
w{ -4@ &&"""E #v;;KKC II<gF		*G3Y?),%BXvb	6" *3 6{{499V,--   63!5 s   N
O$O		Oc                 |    Sn[         R                  R                  [        U S5      5      (       a  Sn[	        X5      $ )z6Returns the string value of an interface's MAC Addressr  bonding_slavezbonding_slave/perm_hwaddr)rV   r(   isdirr)   rG   )r"  r(   s     r   get_interface_macrl  X  s3    D	ww}}\&/:;; +V**r"   c                 p    [        U S5      S:X  a&  [        U 5      nU(       a  U(       a  USS USS -   nU$ g)zReturns the string value of an Infiniband interface's hardware
address. If ethernet_format is True, an Ethernet MAC-style 6 byte
representation of the address will be returned.
rk   rl   $   i3   N)rG   rl  )r"  ethernet_formatr  s      r   get_ib_interface_hwaddrrq  b  sB     (D0'?b+BC(C
 1r"   c                  "   [         R                  " 5       (       d  [         R                  " 5       (       a
  [        5       $ [         R                  " 5       (       a
  [        5       $ [         R                  " 5       (       a
  [        5       $ [        5       $ r   )	r	   r   r    get_interfaces_by_mac_on_freebsdr   get_interfaces_by_mac_on_netbsdr    get_interfaces_by_mac_on_openbsdget_interfaces_by_mac_on_linuxr!   r"   r   r   r   p  s[    D0022/11			.00			/11-//r"   r  c                     [        5       R                  5        H+  u  pU R                  5       UR                  5       :X  d  M)  Us  $    g r   )r   rP  r   )r  interface_macinterface_names      r   find_interface_name_from_macrz  {  s>    )>)@)F)F)H%99;---//!! *I r"   c                      [         R                   " / SQ5      u  pS nS nU" U" U 5      5       VVs0 s H  u  pEXE_M	     nnnU$ s  snnf )N)r   -ar   c              3      #    SnU R                  S5       H,  nUR                  S5      (       a  X-  nM  U(       a  Uv   UnM.     Uv   g 7f)Nr   rO  	)r   r   )r{   
curr_blocklines      r   flatten1get_interfaces_by_mac_on_freebsd.<locals>.flatten  sI     
IIdODt$$"
$$!
 $ s   A	Ac              3      #    U  HG  n[         R                  " SU5      nU(       d  M#  UR                  S5      UR                  S5      4v   MI     g 7f)Nz2^(?P<ifname>\S*): .*ether\s(?P<mac>[\da-f:]{17}).*r  r"  )r   searchgroup)	flat_listblockms      r   find_mac2get_interfaces_by_mac_on_freebsd.<locals>.find_mac  sE     E		EuA qwwu~qwwx'899 s
   "A)A)r   )r{   r   r  r  r  r"  resultss          r   rs  rs    sM    yy45HS	: /7ws|.DE.D{ss{.DGEN Fs   Ac                     0 n Sn[         R                   " SS/5      u  p#[        R                  " SSU5      R                  5       nU H<  n[        R                  " X5      nU(       d  M"  UR                  5       nUS   XS   '   M>     U $ )NzE(?P<ifname>\w+).*address:\s(?P<mac>([\da-f]{2}[:-]){5}([\da-f]{2})).*r   r|  \n\s+ r"  r  r   r   subrw   r  	groupdictrs   re_field_matchr{   r   if_linesr  r  fieldss           r   rt  rt        
C	6  yy*d+,HSvvhS)446HHH^*1[[]F!'!1Cu	 
 Jr"   c                     0 n Sn[         R                   " SS/5      u  p#[        R                  " SSU5      R                  5       nU H<  n[        R                  " X5      nU(       d  M"  UR                  5       nUS   XS   '   M>     U $ )NzC(?P<ifname>\w+).*lladdr\s(?P<mac>([\da-f]{2}[:-]){5}([\da-f]{2})).*r   r|  r  r  r"  r  r  r  s           r   ru  ru    r  r"   c                  4   0 n [        5        H  u  pp4X ;   a>  US;   a  [        R                  SUX   U5        M-  SU< SX   < SU< S3n[        U5      eXU'   [	        US5      nU(       d  Mb  X`;  a  XU'   Mm  [        R                  SUX   U5        M     U $ )	ziBuild a dictionary of tuples {mac: name}.

Bridges and any devices that have a 'stolen' mac are excluded.)	fsl_enetc
mscc_felixqmi_wwanz>Ignoring duplicate macs from '%s' and '%s' due to driver '%s'.duplicate mac found! both '' and '' have mac 'z'.Tz^Ethernet and InfiniBand interfaces have the same address both '%s' and '%s' have address '%s'.)r   r5   r6   r  rq  rU  )rs   r   r  r   _devidrK  ib_macs          r   rv  rv    s     C%3%5!6: @@		#H  A C
 s##C
 )t46*  "F=Ko &6| Jr"   filter_hyperv_vf_with_syntheticr   r   r   r   r   r   c           	         U(       a  [         R                  OS n/ n[        5       n	SR                  S5      n
U	 GH;  nU(       a  [	        U5      (       d  M  [        U5      (       a  U" SU5        M8  U(       a  [        U5      (       a  MQ  [        U5      (       a  U" SU5        Ml  U(       a.  [        U5      b"  [        U5      (       d  [        U5      (       d  M  [        U5      (       a  U" SU5        M  [        U5      nU(       d  U" SU5        M  U(       a  US	:w  a  XS[        U5       :X  a  M  U(       a  [        U5      (       a  GM  [        U5      nUR!                  XU[#        U5      45        GM>     U (       a  [%        Xx5        U$ )
z~Return list of interface tuples (name, mac, driver, device_id)

Bridges and any devices that have a 'stolen' mac are excluded.c                      g r   r!   )argss    r   <lambda> get_interfaces.<locals>.<lambda>  s    4r"   :)00r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  zIgnoring bridge interface: %szIgnoring bond interface: %sNzIgnoring failover interface: %sz"Ignoring interface without mac: %sr   )r5   r6   r   rb   r%  rY   r   r\   r`   rf   ri   r   rl  r   r   r   r   r   )filter_hyperv_vf_with_synthetic_interface)r  r   r   r   r   r   r   filtered_loggerrs   r   zero_macr   r  r   s                 r   r   r     sI    $8cii=OO
CDxx%H!*?*E*ET??;TB74==4==94@>4 ,,T22)$//$=tD%@$Gtt|
#c(7K0K&+L,
 ,
 t$

Dv|D'9:;E J '1/GJr"   r  ).Nr   c                    U Vs0 s H  o"S   S:X  d  M  US   US   _M     nnU Vs/ s H  nUS   U;   d  M  US   S:w  d  M  UPM     nnU H'  nUu  pgpU " SUUX7   U5        UR                  U5        M)     gs  snf s  snf )ai  Filter Hyper-V SR-IOV/VFs when used with synthetic hv_netvsc.

Hyper-V's netvsc driver may register an SR-IOV/VF interface with a mac
that matches the synthetic (hv_netvsc) interface.  This VF will be
enslaved to the synthetic interface, but cloud-init may be racing this
process.  The [perhaps-yet-to-be-enslaved] VF should never be directly
configured, so we filter interfaces that duplicate any hv_netvsc mac
address, as this the most reliable indicator that it is meant to be
subordinate to the synthetic interface.

VF drivers will be mlx4_core, mlx5_core, or mana.  However, given that
this list of drivers has changed over time and mana's dependency on
hv_netvsc is expected to be removed in the future, we no longer rely
on these names. Note that this will not affect mlx4/5 instances outside
of Hyper-V, as it only affects environments where hv_netvsc is present.
r  	hv_netvscr  r   zdIgnoring %r VF interface with driver %r due to synthetic hv_netvsc interface %r with mac address %r.N)r   )
r  r   ihv_netvsc_mac_to_nameinterfaces_to_remover   r   r  r   r   s
             r   r  r  A  s    * '&qA$+*=
!ad
J  
 AQ4(( 	
-.qT[-@ 	
   *	(6D!&	
 	)$ *s   A:A:A?A?A?c            
          0 n [        5        H@  u  n    n[        US5      nU(       d  M  X0;   a  [        SU< SX   < SU< S35      eX0U'   MB     U $ )zPBuild a dictionary mapping Infiniband interface names to their hardware
address.Fr  r  r  ')r   rq  r  )rs   r   r   r  s       r   get_ib_hwaddrs_by_interfacer  k  s_     C')aA(u56}"S[&2  I * Jr"   convert_to_addressr  c                 6     U " U40 UD6$ ! [          a     gf = f)zUse a function to return an address. If conversion throws a ValueError
exception return False.

:param check_cb:
    Test function, must return a truthy value
:param address:
    The string to test.

:return:
    Address or False

F)rI   )r  r  kwargss      r   maybe_get_addressr  {  s)    !'4V44 s    
c                 H    [        [        [        R                  U 5      5      $ )zReturns a bool indicating if ``s`` is an IP address.

:param address:
    The string to test.

:return:
    A bool indicating if the string is an IP address or not.
)rq   r  	ipaddress
ip_addressr  s    r   is_ip_addressr    s     !)"6"6@AAr"   c                 H    [        [        [        R                  U 5      5      $ )zReturns a bool indicating if ``s`` is an IPv4 address.

:param address:
    The string to test.

:return:
    A bool indicating if the string is an IPv4 address or not.
)rq   r  r  IPv4Addressr  s    r   is_ipv4_addressr         !)"7"7ABBr"   c                 H    [        [        [        R                  U 5      5      $ )zReturns a bool indicating if ``s`` is an IPv6 address.

:param address:
    The string to test.

:return:
    A bool indicating if the string is an IPv4 address or not.
)rq   r  r  IPv6Addressr  s    r   is_ipv6_addressr    r  r"   c                 F    [        [        [        R                  U SS95      $ )zReturns a bool indicating if ``s`` is an IPv4 or IPv6 network.

:param address:
    The string to test.

:return:
    A bool indicating if the string is an IPv4 address or not.
Fr#  )rq   r  r  
ip_networkr  s    r   is_ip_networkr    s     !)"6"6NOOr"   c                 F    [        [        [        R                  U SS95      $ )zReturns a bool indicating if ``s`` is an IPv4 network.

:param address:
    The string to test.

:return:
    A bool indicating if the string is an IPv4 address or not.
Fr  )rq   r  r  IPv4Networkr  s    r   is_ipv4_networkr    #     )//G r"   c                 F    [        [        [        R                  U SS95      $ )zReturns a bool indicating if ``s`` is an IPv6 network.

:param address:
    The string to test.

:return:
    A bool indicating if the string is an IPv4 address or not.
Fr  )rq   r  r  IPv6Networkr  s    r   is_ipv6_networkr    r  r"   subnetc                 `    [         R                  " U 5      n[         R                  " USS9nX#;   $ )zReturns a bool indicating if ``s`` is in subnet.

:param address:
    The string of IP address.

:param subnet:
    The string of subnet.

:return:
    A bool indicating if the string is in subnet.
Fr  )r  r  r  )r  r  r  subnet_networks       r   is_ip_in_subnetr    s/     %%g.J))&?N''r"   gatewayc                      [        X5      (       + $ ! [         a"  n[        R                  SU UU5         SnAgSnAff = f)zReturns a bool indicating if should add gateway onlink flag.

:param gateway:
    The string of gateway address.

:param subnet:
    The string of subnet.

:return:
    A bool indicating if the string is in subnet.
zDFailed to check whether gateway %s is contained within subnet %s: %sNF)r  rI   r5   rU  )r  r  r=   s      r   should_add_gateway_onlink_flagr    sD    
"7333 1	
 s    
>9>c                     U S   R                  S5      (       d  U S   [        ;   a  gU S   S:X  a   [        U R                  S5      5      (       a  gg)z:Common helper for checking network_state subnets for ipv6.rk   6Tstaticr  F)endswithIPV6_DYNAMIC_TYPESr  r   )r  s    r   subnet_is_ipv6r    sM     f~s##vf~9K'K	8	#

98M(N(Nr"   c                 Z    [        [        R                  " SU  35      R                  5      $ )zConvert a network prefix to an ipv4 netmask.

This is the inverse of ipv4_mask_to_net_prefix.
    24 -> "255.255.255.0"
Also supports input as a string.0.0.0.0/)r   r  r  netmask)prefixs    r   net_prefix_to_ipv4_maskr    s'     y$$xx%89AABBr"   c                 H    [         R                  " SU  35      R                  $ )zConvert an ipv4 netmask into a network prefix length.

If the input is already an integer or a string representation of
an integer, then int(mask) will be returned.
   "255.255.255.0" => 24
   str(24)         => 24
   "24"            => 24
r  )r  r  	prefixlen)masks    r   ipv4_mask_to_net_prefixr    s"     (4& 12<<<r"   c                     [         R                  " SU  35      R                  nU$ ! [         a     Of = f[         R                  " U 5      n[        U5      nUS:X  a  U$ [        [         R                  U) US-
  -  R                  5       5      nX4-	  n[         R                  U-
  nSU-  S-
  nXV:w  a  [        SU -  5      eU$ )zConvert an ipv6 netmask (very uncommon) or prefix (64) to prefix.

If the input is already an integer or a string representation of
an integer, then int(mask) will be returned.
   "ffff:ffff:ffff::"  => 48
   "48"                => 48
z::/r   r  zInvalid network mask '%s')	r  r  r  rI   r  r   min
IPV6LENGTH
bit_length)r  r  r  mask_inttrailing_zeroesleading_onesall_oness          r   ipv6_mask_to_net_prefixr  '  s    ((3tf6@@	  	
 ""4(G7|H1}yHqL9EEGO .L$$6IY!#H4t;<<s   $' 
44r  r(  c                 \    [        [        R                  " U SU  3SS9R                  5      $ )zCGet string representation of broadcast address from an ip/mask pairr%   Fr  )r   r  r  broadcast_address)r  r(  s     r   mask_and_ipv4_to_bcast_addrr  J  s/    AdVnU;MM r"   c                       \ rS rSrSrg)RendererNotFoundErroriQ  r!   N)r   r   r   r   r   r!   r"   r   r  r  Q  s    r"   r  )r   )NNNNr   )F)T)TTN)TTTTTTF)er+   	functoolsr  loggingrV   r   typingr   r   r   r   r   	cloudinitr   r	   cloudinit.net.netops.iproute2r
   	getLoggerr   r5   r    r   r  rv   r/  r   r#   r)   r?   rG   rK   rR   rY   r\   r`   rf   ri   rm   	lru_cacherq   rt   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;  rh  rl  rq  r   rz  rs  rt  ru  rv  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  r!   r"   r   <module>r     s<       	 	 8 8   2!!"  % ! !jj4 

7 "JH;<G$6 T"$  # T" T   # (s t 
t 0B01
A) A+
.T#Y 
.,8C= ,J$s) J	 	JS	 J	hsm 	Ed3i EP	HSM 	HTN :-G`$(+^ BF[.|+0t 0c hsm $ 8  $  D DP -1(,?C#' !&9%)9!%9 9=9 	9
 !9 9 9 
9x'%i('%U3S#-./'% 
'%T ( S &	B3 	B4 	B	CS 	CT 	C	CS 	CT 	C	P3 	P4 	PS T S T (S (# ($ ("C   2d Cs C	=S 	= S  Fc s s 	L 	r"   