<s> """<STR_LIT>""" <EOL> from struct import pack <EOL> from exabgp . bgp . message . notification import Notify <EOL> from exabgp . util . cache import Cache <EOL> class Attribute ( object ) : <EOL> ID = <NUM_LIT> <EOL> FLAG = <NUM_LIT> <EOL> CACHING = False <EOL> GENERIC = False <EOL> registered_attributes = dict ( ) <EOL> attributes_known = [ ] <EOL> attributes_well_know = [ ] <EOL> attributes_optional = [ ] <EOL> caching = False <EOL> cache = { } <EOL> class CODE ( int ) : <EOL> __slots__ = [ ] <EOL> ORIGIN = <NUM_LIT> <EOL> AS_PATH = <NUM_LIT> <EOL> NEXT_HOP = <NUM_LIT> <EOL> MED = <NUM_LIT> <EOL> LOCAL_PREF = <NUM_LIT> <EOL> ATOMIC_AGGREGATE = <NUM_LIT> <EOL> AGGREGATOR = <NUM_LIT> <EOL> COMMUNITY = <NUM_LIT> <EOL> ORIGINATOR_ID = <NUM_LIT> <EOL> CLUSTER_LIST = <NUM_LIT> <EOL> MP_REACH_NLRI = <NUM_LIT> <EOL> MP_UNREACH_NLRI = <NUM_LIT> <EOL> EXTENDED_COMMUNITY = <NUM_LIT> <EOL> AS4_PATH = <NUM_LIT> <EOL> AS4_AGGREGATOR = <NUM_LIT> <EOL> PMSI_TUNNEL = <NUM_LIT> <EOL> TUNNEL_ENCAP = <NUM_LIT> <EOL> AIGP = <NUM_LIT> <EOL> INTERNAL_NAME = <NUM_LIT> <EOL> INTERNAL_WITHDRAW = <NUM_LIT> <EOL> INTERNAL_WATCHDOG = <NUM_LIT> <EOL> INTERNAL_SPLIT = <NUM_LIT> <EOL> names = { <EOL> ORIGIN : '<STR_LIT>' , <EOL> AS_PATH : '<STR_LIT>' , <EOL> NEXT_HOP : '<STR_LIT>' , <EOL> MED : '<STR_LIT>' , <EOL> LOCAL_PREF : '<STR_LIT>' , <EOL> ATOMIC_AGGREGATE : '<STR_LIT>' , <EOL> AGGREGATOR : '<STR_LIT>' , <EOL> COMMUNITY : '<STR_LIT>' , <EOL> ORIGINATOR_ID : '<STR_LIT>' , <EOL> CLUSTER_LIST : '<STR_LIT>' , <EOL> MP_REACH_NLRI : '<STR_LIT>' , <EOL> MP_UNREACH_NLRI : '<STR_LIT>' , <EOL> EXTENDED_COMMUNITY : '<STR_LIT>' , <EOL> AS4_PATH : '<STR_LIT>' , <EOL> AS4_AGGREGATOR : '<STR_LIT>' , <EOL> PMSI_TUNNEL : '<STR_LIT>' , <EOL> TUNNEL_ENCAP : '<STR_LIT>' , <EOL> AIGP : '<STR_LIT>' , <EOL> <NUM_LIT> : '<STR_LIT>' , <EOL> <NUM_LIT> : '<STR_LIT>' , <EOL> <NUM_LIT> : '<STR_LIT>' , <EOL> <NUM_LIT> : '<STR_LIT>' , <EOL> } <EOL> def __repr__ ( self ) : <EOL> return self . names . get ( self , '<STR_LIT>' % hex ( self ) ) <EOL> def __str__ ( self ) : <EOL> return repr ( self ) <EOL> @ classmethod <EOL> def name ( cls , self ) : <EOL> return cls . names . get ( self , '<STR_LIT>' % hex ( self ) ) <EOL> class Flag ( int ) : <EOL> EXTENDED_LENGTH = <NUM_LIT> <EOL> PARTIAL = <NUM_LIT> <EOL> TRANSITIVE = <NUM_LIT> <EOL> OPTIONAL = <NUM_LIT> <EOL> MASK_EXTENDED = <NUM_LIT> <EOL> MASK_PARTIAL = <NUM_LIT> <EOL> MASK_TRANSITIVE = <NUM_LIT> <EOL> MASK_OPTIONAL = <NUM_LIT> <EOL> __slots__ = [ ] <EOL> def __str__ ( self ) : <EOL> r = [ ] <EOL> v = int ( self ) <EOL> if v & <NUM_LIT> : <EOL> r . append ( "<STR_LIT>" ) <EOL> v -= <NUM_LIT> <EOL> if v & <NUM_LIT> : <EOL> r . append ( "<STR_LIT>" ) <EOL> v -= <NUM_LIT> <EOL> if v & <NUM_LIT> : <EOL> r . append ( "<STR_LIT>" ) <EOL> v -= <NUM_LIT> <EOL> if v & <NUM_LIT> : <EOL> r . append ( "<STR_LIT>" ) <EOL> v -= <NUM_LIT> <EOL> if v : <EOL> r . append ( "<STR_LIT>" % hex ( v ) ) <EOL> return "<STR_LIT:U+0020>" . join ( r ) <EOL> def matches ( self , value ) : <EOL> return self | <NUM_LIT> == value | <NUM_LIT> <EOL> def _attribute ( self , value ) : <EOL> flag = self . FLAG <EOL> if flag & Attribute . Flag . OPTIONAL and not value : <EOL> return '<STR_LIT>' <EOL> length = len ( value ) <EOL> if length > <NUM_LIT> : <EOL> flag |= Attribute . Flag . EXTENDED_LENGTH <EOL> if flag & Attribute . Flag . EXTENDED_LENGTH : <EOL> len_value = pack ( '<STR_LIT>' , length ) <EOL> else : <EOL> len_value = chr ( length ) <EOL> return "<STR_LIT>" % ( chr ( flag ) , chr ( self . ID ) , len_value , value ) <EOL> def _len ( self , value ) : <EOL> length = len ( value ) <EOL> return length + <NUM_LIT:3> if length <= <NUM_LIT> else length + <NUM_LIT:4> <EOL> def __eq__ ( self , other ) : <EOL> return self . ID == other . ID and self . FLAG == other . FLAG <EOL> def __ne__ ( self , other ) : <EOL> return not self . __eq__ ( other ) <EOL> def __lt__ ( self , other ) : <EOL> return self . ID < other . ID <EOL> def __le__ ( self , other ) : <EOL> return self . ID <= other . ID <EOL> def __gt__ ( self , other ) : <EOL> return self . ID > other . ID <EOL> def __ge__ ( self , other ) : <EOL> return self . ID >= other . ID <EOL> @ classmethod <EOL> def register ( cls , attribute_id = None , flag = None ) : <EOL> def register_attribute ( klass ) : <EOL> aid = klass . ID if attribute_id is None else attribute_id <EOL> flg = klass . FLAG | Attribute . Flag . EXTENDED_LENGTH if flag is None else flag | Attribute . Flag . EXTENDED_LENGTH <EOL> if ( aid , flg ) in cls . registered_attributes : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> cls . registered_attributes [ ( aid , flg ) ] = klass <EOL> cls . attributes_known . append ( aid ) <EOL> if klass . FLAG & Attribute . Flag . OPTIONAL : <EOL> cls . attributes_optional . append ( aid ) <EOL> else : <EOL> cls . attributes_well_know . append ( aid ) <EOL> return klass <EOL> return register_attribute <EOL> @ classmethod <EOL> def registered ( cls , attribute_id , flag ) : <EOL> return ( attribute_id , flag | Attribute . Flag . EXTENDED_LENGTH ) in cls . registered_attributes <EOL> @ classmethod <EOL> def klass ( cls , attribute_id , flag ) : <EOL> key = ( attribute_id , flag | Attribute . Flag . EXTENDED_LENGTH ) <EOL> if key in cls . registered_attributes : <EOL> kls = cls . registered_attributes [ key ] <EOL> kls . ID = attribute_id <EOL> return kls <EOL> if attribute_id == Attribute . CODE . AS4_PATH : <EOL> kls = cls . attributes_known [ attribute_id ] <EOL> kls . ID = attribute_id <EOL> return kls <EOL> raise Notify ( <NUM_LIT:2> , <NUM_LIT:4> , '<STR_LIT>' % attribute_id ) <EOL> @ classmethod <EOL> def unpack ( cls , attribute_id , flag , data , negotiated ) : <EOL> cache = cls . caching and cls . CACHING <EOL> if cache and data in cls . cache . get ( cls . ID , { } ) : <EOL> return cls . cache [ cls . ID ] . retrieve ( data ) <EOL> key = ( attribute_id , flag | Attribute . Flag . EXTENDED_LENGTH ) <EOL> if key in Attribute . registered_attributes . keys ( ) : <EOL> instance = cls . klass ( attribute_id , flag ) . unpack ( data , negotiated ) <EOL> if cache : <EOL> cls . cache [ cls . ID ] . cache ( data , instance ) <EOL> return instance <EOL> raise Notify ( <NUM_LIT:2> , <NUM_LIT:4> , '<STR_LIT>' % attribute_id ) <EOL> @ classmethod <EOL> def setCache ( cls ) : <EOL> if not cls . cache : <EOL> for attribute in Attribute . CODE . names : <EOL> if attribute not in cls . cache : <EOL> cls . cache [ attribute ] = Cache ( ) <EOL> Attribute . setCache ( ) </s>
