܍~c/ddlZddlZddlZddlZddlmZddlmZddlm Z ej e Z dZ dZdZdZdZd Zd Zd Zd Zd ZdZdZdZdZejeZejeZeezZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)edgdZ*edddgZ+edgdZ,Gdde-Z.dZ/dZ0d&dZ1d Z2d!Z3d"Z4d#Z5d$Z6d%Z7dS)'N) namedtuple)log)utili <IHHIIBHiIIRTAAttr)lengthrta_typedataInterfaceOperstateifname operstate NetlinkHeader)rtypeflagsseqpidceZdZdZdS)NetlinkCreateSocketErrorz5Raised if netlink socket fails during create or bind.N)__name__ __module__ __qualname____doc__C/usr/lib/python3/dist-packages/cloudinit/sources/helpers/netlink.pyr!r!9s????r'r!c tjtjtjtj}|t jtf|dn,#tj $r}d|z}t||d}~wwxYwt d|S)auCreates netlink socket and bind on netlink group to catch interface down/up events. The socket will bound only on RTMGRP_LINK (which only includes RTM_NEWLINK/RTM_DELLINK/RTM_GETLINK events). The socket is set to non-blocking mode since we're only receiving messages. :returns: netlink socket in non-blocking mode :raises: NetlinkCreateSocketError rz*Exception during netlink socket create: %sNzCreated netlink socket) socket AF_NETLINKSOCK_RAW NETLINK_ROUTEbindosgetpid RTMGRP_LINK setblockingerrorr!LOGdebug)netlink_socketemsgs r(create_bound_netlink_socketr9=s3  v0D   RY[[+6777""1%%%% <333:Q>&s++23II&''' sA6A99B"BB"c| Jdt|tks Jdtjt|dt \}}}}}t d|t|||||S)aGets netlink message type and length :param: data read from netlink socket :returns: netlink message type :raises: AssertionError if data is None or data is not >= NLMSGHDR_SIZE struct nlmsghdr { __u32 nlmsg_len; /* Length of message including header */ __u16 nlmsg_type; /* Type of message content */ __u16 nlmsg_flags; /* Additional flags */ __u32 nlmsg_seq; /* Sequence number */ __u32 nlmsg_pid; /* Sender port ID */ }; N data is nonez+data is smaller than netlink message headerzGot netlink msg of type %d) len NLMSGHDR_SIZEstructunpack NLMSGHDR_FMTMSG_TYPE_OFFSETr4r5r)rmsg_lenmsg_typerrrs r(get_netlink_msg_headerrDSs   ^    D ]"""4 #"")/d+O+,**&GXuc3II*H555 (E3 < <) from socket, if no data read, returns None :raises: AssertionError if netlink_socket is None Nnetlink socket is noneznetlink socket ready for readz,Reading from Netlink socket returned no data)selectr4r5recvMAX_SIZEr3)r6timeoutread_set_rs r(read_netlink_socketrMls  % %'? % % %]N#3RWEENHaX%%tII-...   x ( (D | @AAA Kr'c| Jdt|tks Jd|tks Jddx}}d} tjd||d}tjd||dzd}n#tj$rYdSwxYw||t z||z}t|||S) a(Unpack a single rta attribute. :param: data: string of data read from netlink socket :param: offset: starting offset of RTA Attribute :return: RTAAttr object with length, type and data. On error, return None. :raises: AssertionError if data is None or offset is not integer. Nr;zoffset is not integerz'rta offset is less than expected lengthrH)offsetr)rintRTATTR_START_OFFSETr> unpack_fromr3RTA_DATA_START_OFFSETr)rrPrr attr_datas r(unpack_rta_attrrVs   ^    <<3    7   %%%%0 &%%FXI#Cf===a@%c4 CCCAF <ttV33fvoEFI 68Y / //s =B BBc| Jdt|tks Jddx}}t}|t|krt||}|r |jdkrnt|jtzz tz}||j|zz }|jt krt|j}n?|jtkr/tj |jd}| d}|t|k|r|dStd||t||S)aReads Interface name and operational state from RTA Data. :param: data: string of data read from netlink socket :returns: InterfaceOperstate object containing if_name and oper_state. None if data does not contain valid IFLA_OPERSTATE and IFLA_IFNAME messages. :raises: AssertionError if data is None or length of data is smaller than RTATTR_START_OFFSET. Nr;z2length of data is smaller than RTATTR_START_OFFSETrzutf-8z!rta attrs: ifname %s operstate %d)r<rRrVr PAD_ALIGNMENTrIFLA_OPERSTATEordr IFLA_IFNAMEr decode_binarystripr4r5r)rrrrPattrpadleninterface_names r(read_rta_oper_staterbsM   ^    D ''''; (''FY F CII  tV,, t{a''  T[=8 9  $+&& =N * *DIII ]k ) )!/ 7CCN#))$//F CII   Y&tII169EEE fi 0 00r'ctddfd}t|dtgtt g|S)zBlock until a single nic is attached. :param: netlink_socket: netlink_socket to receive events :param: existing_nics: List of existing nics so that we can skip them. :raises: AssertionError if netlink_socket is none. z!Preparing to wait for nic attach.Nc|vrdS|dS)NTFr&)inamecarrier prevCarrier existing_nicsrs r(should_continue_cbz5wait_for_nic_attach_event..should_continue_cbs M ! !4ur')r4r5read_netlink_messages RTM_NEWLINKOPER_UP OPER_DOWN)r6rhrirs ` @r(wait_for_nic_attach_eventrnsmII1222 F  )  Mr'ctddfd}t|dtgtg|S)zBlock until a single nic is detached and its operational state is down. :param: netlink_socket: netlink_socket to receive events. z!Preparing to wait for nic detach.Nc |dS)NFr&)rerfrgrs r(riz5wait_for_nic_detach_event..should_continue_cbs ur')r4r5rj RTM_DELLINKrm)r6rirs @r(wait_for_nic_detach_eventrrsa II1222 F {mi[:L Mr'c| Jd Jdtdks Jdfd}tdt|tt gt tg|dS)aBlock until media disconnect and connect has happened on an interface. Listens on netlink socket to receive netlink events and when the carrier changes from 0 to 1, it considers event has happened and return from this function :param: netlink_socket: netlink_socket to receive events :param: ifname: Interface name to lookout for netlink events :raises: AssertionError if netlink_socket is None or ifname is None. NrFzinterface name is nonerzinterface name cannot be emptycr|tko |tk}|rtddSdS)NzMedia switch happened on %s.FT)rmrlr4r5)rerfrg isVnetSwitchrs r(riz=wait_for_media_disconnect_connect..should_continue_cbs>#y0Jw'7I   II4f = = =5tr'z1Wait for media disconnect and reconnect to happen)r<r4r5rjrkrqrlrm)r6rris ` r(!wait_for_media_disconnect_connectrvs  % %'? % % %   7    v;;???>>  2CII>>>d))w&'']F6{{]** ?@@@-f55H6{{X_,, FGGGo 59!>Ff_F II:F C C C}I--1&99O& =OOO)#*m;; L#*! ( ::!K%/G++& MwNFGG}a0r')N)8r/rGr*r> collectionsr cloudinitrloggingr getLoggerr"r4r1 NLMSG_NOOP NLMSG_ERROR NLMSG_DONErkrq RTM_GETLINK RTM_SETLINKrIRTA_DATA_OFFSETrArzr@ IFINFOMSG_FMTcalcsizer=IFINFOMSG_SIZErRrTrYr\rZ OPER_UNKNOWNOPER_NOTPRESENTrmOPER_LOWERLAYERDOWN OPER_TESTING OPER_DORMANTrlrrrrxr!r9rDrMrVrbrnrrrvrjr&r'r(rs?  """"""$$$$$$g!!           --  //#n4       *Y > > > ? ?Z 4x6MNN >>> @@@@@|@@@,===2.0004"1"1"1J:&@EEEEEr'