ó oBú]c@sËddlmZddlmZddlmZddlZddlZddlZddl Z ej e ƒZ dZ dZdZdZdZd Zd Zd Zd Zd ZdZdZdZdZe jeƒZe jeƒZeeZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)eddddgƒZ*edddgƒZ+edddddd gƒZ,d!e-fd"„ƒYZ.d#„Z/d$„Z0dd%„Z2d&„Z3d'„Z4d(„Z5dS()iÿÿÿÿ(tlog(tutil(t namedtupleNiiiiiiiiÿÿi i<tIHHIItBHiIIiiiitRTAAttrtlengthtrta_typetdatatInterfaceOperstatetifnamet operstatet NetlinkHeaderttypetflagstseqtpidtNetlinkCreateSocketErrorcBseZdZRS(s5Raised if netlink socket fails during create or bind.(t__name__t __module__t__doc__(((sE/usr/lib/python2.7/site-packages/cloudinit/sources/helpers/netlink.pyR8scCsˆyHtjtjtjtjƒ}|jtjƒtfƒ|jdƒWn,tj k rv}d|}t |ƒ‚nXt j dƒ|S(suCreates 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 is*Exception during netlink socket create: %ssCreated netlink socket( tsockett AF_NETLINKtSOCK_RAWt NETLINK_ROUTEtbindtostgetpidt RTMGRP_LINKt setblockingterrorRtLOGtdebug(tnetlink_sockettetmsg((sE/usr/lib/python2.7/site-packages/cloudinit/sources/helpers/netlink.pytcreate_bound_netlink_socket=s     cCs|dk stdƒ‚t|ƒtks6tdƒ‚tjt|t ƒ\}}}}}tj d|ƒt |||||ƒS(sGets 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 */ }; s data is nones+data is smaller than netlink message headersGot netlink msg of type %dN( tNonetAssertionErrortlent NLMSGHDR_SIZEtstructtunpackt NLMSGHDR_FMTtMSG_TYPE_OFFSETRR R (Rtmsg_lentmsg_typeRRR((sE/usr/lib/python2.7/site-packages/cloudinit/sources/helpers/netlink.pytget_netlink_msg_headerSs  cCsˆ|dk stdƒ‚tj|ggg|ƒ\}}}||krLdStjdƒ|jtƒ}|dkr„tjdƒn|S(sÁSelect and read from the netlink socket if ready. :param: netlink_socket: specify which socket object to read from :param: timeout: specify a timeout value (integer) to wait while reading, if none, it will block indefinitely until socket ready for read :returns: string of data read (max length = ) from socket, if no data read, returns None :raises: AssertionError if netlink_socket is None snetlink socket is nonesnetlink socket ready for reads,Reading from Netlink socket returned no dataN(R%R&tselectRR trecvtMAX_SIZER(R!ttimeouttread_sett_R((sE/usr/lib/python2.7/site-packages/cloudinit/sources/helpers/netlink.pytread_netlink_socketjs $   cCsÛ|dk stdƒ‚t|ƒtks6tdƒ‚|tksNtdƒ‚d}}d}y@tjd|d|ƒd}tjd|d|dƒd}Wntjk rµdSX||t||!}t |||ƒS( s(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. s data is nonesoffset is not integers'rta offset is less than expected lengthitHtoffsetiN( R%R&R tinttRTATTR_START_OFFSETR)t unpack_fromRtRTA_DATA_START_OFFSETR(RR8RRt attr_data((sE/usr/lib/python2.7/site-packages/cloudinit/sources/helpers/netlink.pytunpack_rta_attrs  $cCs<|dk stdƒ‚t|ƒtks6tdƒ‚d}}t}x¼|t|ƒkrt||ƒ}| s€|jdkr„Pnt|jtt}||j|7}|jtkrËt |j ƒ}qI|jt krIt j |j dƒ}|jdƒ}qIqIW| s|dkrdStjd||ƒt||ƒS(sReads 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. s data is nones2length of data is smaller than RTATTR_START_OFFSETisutf-8ts!rta attrs: ifname %s operstate %dN(R%R&R'R:R>Rt PAD_ALIGNMENTRtIFLA_OPERSTATEtordRt IFLA_IFNAMERt decode_binarytstripRR R (RR R R8tattrtpadlentinterface_name((sE/usr/lib/python2.7/site-packages/cloudinit/sources/helpers/netlink.pytread_rta_oper_statešs*   c Csj|dk stdƒ‚|dk s0tdƒ‚t|ƒdksNtdƒ‚t}t}tƒ}tjdƒxótret|t ƒ}|dkršqsntjdt|ƒƒ||7}tjdt|ƒƒd}t|ƒ}xs||krW||}t|ƒt krtjdƒPnt |ƒ} t|ƒ| j krPtjd ƒPn| j t d t d @} || }tjd |ƒ| jttgkrŸqånt|ƒ} | dkrÍtjd | ƒqån| j|krøtjd | j|ƒqån| jttgkrqån|}| j}|tko7|tk} | råtjd|ƒdSqåW||}qsWdS(s»Block 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. snetlink socket is nonesinterface name is noneisinterface name cannot be emptys1Wait for media disconnect and reconnect to happensread %d bytes from socketsLength of data after concat %ds#Data is smaller than netlink headers*Partial data. Smaller than netlink messageis"offset to next netlink message: %ds!Failed to read rta attributes: %ss6Ignored netlink event on interface %s. Waiting for %s.sMedia switch happened on %s.N(R%R&R'tOPER_UPtbytesRR tTrueR6tSELECT_TIMEOUTR(R/RR@R t RTM_NEWLINKt RTM_DELLINKRIR R t OPER_DOWN( R!R tcarriert prevCarrierRt recv_dataR8tdatalentnl_msgtnlheaderRGtinterface_statet isVnetSwitch((sE/usr/lib/python2.7/site-packages/cloudinit/sources/helpers/netlink.pyt!wait_for_media_disconnect_connect½s`                (6t cloudinitRtloggingRt collectionsRRR0RR)t getLoggerRRRt NLMSG_NOOPt NLMSG_ERRORt NLMSG_DONERNROt RTM_GETLINKt RTM_SETLINKR2tRTA_DATA_OFFSETR,RMR+t IFINFOMSG_FMTtcalcsizeR(tIFINFOMSG_SIZER:R<R@RCRAt OPER_UNKNOWNtOPER_NOTPRESENTRPtOPER_LOWERLAYERDOWNt OPER_TESTINGt OPER_DORMANTRJRR R t RuntimeErrorRR$R/R%R6R>RIRY(((sE/usr/lib/python2.7/site-packages/cloudinit/sources/helpers/netlink.pyts\           #