<s> """<STR_LIT>""" <EOL> import netaddr <EOL> from ryu . lib import hub <EOL> from ryu . services . protocols . bgp . core_manager import CORE_MANAGER <EOL> from ryu . services . protocols . bgp . signals . emit import BgpSignalBus <EOL> from ryu . services . protocols . bgp . api . base import call <EOL> from ryu . services . protocols . bgp . api . base import PREFIX <EOL> from ryu . services . protocols . bgp . api . base import NEXT_HOP <EOL> from ryu . services . protocols . bgp . api . base import ROUTE_DISTINGUISHER <EOL> from ryu . services . protocols . bgp . api . base import ROUTE_FAMILY <EOL> from ryu . services . protocols . bgp . rtconf . common import LOCAL_AS <EOL> from ryu . services . protocols . bgp . rtconf . common import ROUTER_ID <EOL> from ryu . services . protocols . bgp . rtconf . common import BGP_SERVER_PORT <EOL> from ryu . services . protocols . bgp . rtconf . common import DEFAULT_BGP_SERVER_PORT <EOL> from ryu . services . protocols . bgp . rtconf . common import DEFAULT_REFRESH_MAX_EOR_TIME <EOL> from ryu . services . protocols . bgp . rtconf . common import DEFAULT_REFRESH_STALEPATH_TIME <EOL> from ryu . services . protocols . bgp . rtconf . common import DEFAULT_LABEL_RANGE <EOL> from ryu . services . protocols . bgp . rtconf . common import REFRESH_MAX_EOR_TIME <EOL> from ryu . services . protocols . bgp . rtconf . common import REFRESH_STALEPATH_TIME <EOL> from ryu . services . protocols . bgp . rtconf . common import LABEL_RANGE <EOL> from ryu . services . protocols . bgp . rtconf import neighbors <EOL> from ryu . services . protocols . bgp . rtconf import vrfs <EOL> from ryu . services . protocols . bgp . rtconf . base import CAP_MBGP_IPV4 <EOL> from ryu . services . protocols . bgp . rtconf . base import CAP_MBGP_IPV6 <EOL> from ryu . services . protocols . bgp . rtconf . base import CAP_MBGP_VPNV4 <EOL> from ryu . services . protocols . bgp . rtconf . base import CAP_MBGP_VPNV6 <EOL> from ryu . services . protocols . bgp . rtconf . base import CAP_ENHANCED_REFRESH <EOL> from ryu . services . protocols . bgp . rtconf . base import MULTI_EXIT_DISC <EOL> from ryu . services . protocols . bgp . rtconf . base import SITE_OF_ORIGINS <EOL> from ryu . services . protocols . bgp . rtconf . neighbors import DEFAULT_CAP_MBGP_IPV4 <EOL> from ryu . services . protocols . bgp . rtconf . neighbors import DEFAULT_CAP_MBGP_VPNV4 <EOL> from ryu . services . protocols . bgp . rtconf . neighbors import DEFAULT_CAP_MBGP_VPNV6 <EOL> from ryu . services . protocols . bgp . rtconf . neighbors import DEFAULT_CAP_ENHANCED_REFRESH <EOL> from ryu . services . protocols . bgp . rtconf . neighbors import DEFAULT_CONNECT_MODE <EOL> from ryu . services . protocols . bgp . rtconf . neighbors import PEER_NEXT_HOP <EOL> from ryu . services . protocols . bgp . rtconf . neighbors import PASSWORD <EOL> from ryu . services . protocols . bgp . rtconf . neighbors import IS_ROUTE_SERVER_CLIENT <EOL> from ryu . services . protocols . bgp . rtconf . neighbors import IS_NEXT_HOP_SELF <EOL> from ryu . services . protocols . bgp . rtconf . neighbors import CONNECT_MODE <EOL> from ryu . services . protocols . bgp . rtconf . neighbors import LOCAL_ADDRESS <EOL> from ryu . services . protocols . bgp . rtconf . neighbors import LOCAL_PORT <EOL> from ryu . services . protocols . bgp . info_base . base import Filter <EOL> from ryu . services . protocols . bgp . info_base . ipv4 import Ipv4Path <EOL> from ryu . services . protocols . bgp . info_base . ipv6 import Ipv6Path <EOL> from ryu . services . protocols . bgp . info_base . vpnv4 import Vpnv4Path <EOL> from ryu . services . protocols . bgp . info_base . vpnv6 import Vpnv6Path <EOL> NEIGHBOR_CONF_MED = '<STR_LIT>' <EOL> RF_VPN_V4 = vrfs . VRF_RF_IPV4 <EOL> RF_VPN_V6 = vrfs . VRF_RF_IPV6 <EOL> class EventPrefix ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , remote_as , route_dist , prefix , nexthop , label , <EOL> is_withdraw ) : <EOL> self . remote_as = remote_as <EOL> self . route_dist = route_dist <EOL> self . prefix = prefix <EOL> self . nexthop = nexthop <EOL> self . label = label <EOL> self . is_withdraw = is_withdraw <EOL> class BGPSpeaker ( object ) : <EOL> def __init__ ( self , as_number , router_id , <EOL> bgp_server_port = DEFAULT_BGP_SERVER_PORT , <EOL> refresh_stalepath_time = DEFAULT_REFRESH_STALEPATH_TIME , <EOL> refresh_max_eor_time = DEFAULT_REFRESH_MAX_EOR_TIME , <EOL> best_path_change_handler = None , <EOL> peer_down_handler = None , <EOL> peer_up_handler = None , <EOL> ssh_console = False , <EOL> label_range = DEFAULT_LABEL_RANGE ) : <EOL> """<STR_LIT>""" <EOL> super ( BGPSpeaker , self ) . __init__ ( ) <EOL> settings = { } <EOL> settings [ LOCAL_AS ] = as_number <EOL> settings [ ROUTER_ID ] = router_id <EOL> settings [ BGP_SERVER_PORT ] = bgp_server_port <EOL> settings [ REFRESH_STALEPATH_TIME ] = refresh_stalepath_time <EOL> settings [ REFRESH_MAX_EOR_TIME ] = refresh_max_eor_time <EOL> settings [ LABEL_RANGE ] = label_range <EOL> self . _core_start ( settings ) <EOL> self . _init_signal_listeners ( ) <EOL> self . _best_path_change_handler = best_path_change_handler <EOL> self . _peer_down_handler = peer_down_handler <EOL> self . _peer_up_handler = peer_up_handler <EOL> if ssh_console : <EOL> from ryu . services . protocols . bgp . operator import ssh <EOL> hub . spawn ( ssh . SSH_CLI_CONTROLLER . start ) <EOL> def _notify_peer_down ( self , peer ) : <EOL> remote_ip = peer . protocol . recv_open_msg . bgp_identifier <EOL> remote_as = peer . protocol . recv_open_msg . my_as <EOL> if self . _peer_down_handler : <EOL> self . _peer_down_handler ( remote_ip , remote_as ) <EOL> def _notify_peer_up ( self , peer ) : <EOL> remote_ip = peer . protocol . recv_open_msg . bgp_identifier <EOL> remote_as = peer . protocol . recv_open_msg . my_as <EOL> if self . _peer_up_handler : <EOL> self . _peer_up_handler ( remote_ip , remote_as ) <EOL> def _notify_best_path_changed ( self , path , is_withdraw ) : <EOL> if path . source : <EOL> nexthop = path . nexthop <EOL> is_withdraw = is_withdraw <EOL> remote_as = path . source . remote_as <EOL> else : <EOL> return <EOL> if isinstance ( path , Ipv4Path ) or isinstance ( path , Ipv6Path ) : <EOL> prefix = path . nlri . addr + '<STR_LIT:/>' + str ( path . nlri . length ) <EOL> route_dist = None <EOL> label = None <EOL> elif isinstance ( path , Vpnv4Path ) or isinstance ( path , Vpnv6Path ) : <EOL> prefix = path . nlri . prefix <EOL> route_dist = path . nlri . route_dist <EOL> label = path . nlri . label_list <EOL> else : <EOL> return <EOL> ev = EventPrefix ( remote_as , route_dist , prefix , nexthop , label , <EOL> is_withdraw ) <EOL> if self . _best_path_change_handler : <EOL> self . _best_path_change_handler ( ev ) <EOL> def _init_signal_listeners ( self ) : <EOL> CORE_MANAGER . get_core_service ( ) . _signal_bus . register_listener ( <EOL> BgpSignalBus . BGP_BEST_PATH_CHANGED , <EOL> lambda _ , info : <EOL> self . _notify_best_path_changed ( info [ '<STR_LIT:path>' ] , <EOL> info [ '<STR_LIT>' ] ) <EOL> ) <EOL> CORE_MANAGER . get_core_service ( ) . _signal_bus . register_listener ( <EOL> BgpSignalBus . BGP_ADJ_DOWN , <EOL> lambda _ , info : <EOL> self . _notify_peer_down ( info [ '<STR_LIT>' ] ) <EOL> ) <EOL> CORE_MANAGER . get_core_service ( ) . _signal_bus . register_listener ( <EOL> BgpSignalBus . BGP_ADJ_UP , <EOL> lambda _ , info : <EOL> self . _notify_peer_up ( info [ '<STR_LIT>' ] ) <EOL> ) <EOL> def _core_start ( self , settings ) : <EOL> waiter = hub . Event ( ) <EOL> call ( '<STR_LIT>' , waiter = waiter , ** settings ) <EOL> waiter . wait ( ) <EOL> def _serve_forever ( self ) : <EOL> pass <EOL> def shutdown ( self ) : <EOL> """<STR_LIT>""" <EOL> call ( '<STR_LIT>' ) <EOL> def neighbor_add ( self , address , remote_as , <EOL> enable_ipv4 = DEFAULT_CAP_MBGP_IPV4 , <EOL> enable_vpnv4 = DEFAULT_CAP_MBGP_VPNV4 , <EOL> enable_vpnv6 = DEFAULT_CAP_MBGP_VPNV6 , <EOL> enable_enhanced_refresh = DEFAULT_CAP_ENHANCED_REFRESH , <EOL> next_hop = None , password = None , multi_exit_disc = None , <EOL> site_of_origins = None , is_route_server_client = False , <EOL> is_next_hop_self = False , local_address = None , <EOL> local_port = None , connect_mode = DEFAULT_CONNECT_MODE ) : <EOL> """<STR_LIT>""" <EOL> bgp_neighbor = { } <EOL> bgp_neighbor [ neighbors . IP_ADDRESS ] = address <EOL> bgp_neighbor [ neighbors . REMOTE_AS ] = remote_as <EOL> bgp_neighbor [ PEER_NEXT_HOP ] = next_hop <EOL> bgp_neighbor [ PASSWORD ] = password <EOL> bgp_neighbor [ IS_ROUTE_SERVER_CLIENT ] = is_route_server_client <EOL> bgp_neighbor [ IS_NEXT_HOP_SELF ] = is_next_hop_self <EOL> bgp_neighbor [ CONNECT_MODE ] = connect_mode <EOL> bgp_neighbor [ CAP_ENHANCED_REFRESH ] = enable_enhanced_refresh <EOL> if netaddr . valid_ipv4 ( address ) : <EOL> bgp_neighbor [ CAP_MBGP_IPV4 ] = enable_ipv4 <EOL> bgp_neighbor [ CAP_MBGP_IPV6 ] = False <EOL> bgp_neighbor [ CAP_MBGP_VPNV4 ] = enable_vpnv4 <EOL> bgp_neighbor [ CAP_MBGP_VPNV6 ] = enable_vpnv6 <EOL> elif netaddr . valid_ipv6 ( address ) : <EOL> bgp_neighbor [ CAP_MBGP_IPV4 ] = False <EOL> bgp_neighbor [ CAP_MBGP_IPV6 ] = True <EOL> bgp_neighbor [ CAP_MBGP_VPNV4 ] = False <EOL> bgp_neighbor [ CAP_MBGP_VPNV6 ] = False <EOL> else : <EOL> pass <EOL> if multi_exit_disc : <EOL> bgp_neighbor [ MULTI_EXIT_DISC ] = multi_exit_disc <EOL> if site_of_origins : <EOL> bgp_neighbor [ SITE_OF_ORIGINS ] = site_of_origins <EOL> if local_address : <EOL> bgp_neighbor [ LOCAL_ADDRESS ] = local_address <EOL> if local_port : <EOL> bgp_neighbor [ LOCAL_PORT ] = local_port <EOL> call ( '<STR_LIT>' , ** bgp_neighbor ) <EOL> def neighbor_del ( self , address ) : <EOL> """<STR_LIT>""" <EOL> bgp_neighbor = { } <EOL> bgp_neighbor [ neighbors . IP_ADDRESS ] = address <EOL> call ( '<STR_LIT>' , ** bgp_neighbor ) <EOL> def neighbor_reset ( self , address ) : <EOL> """<STR_LIT>""" <EOL> bgp_neighbor = { } <EOL> bgp_neighbor [ neighbors . IP_ADDRESS ] = address <EOL> call ( '<STR_LIT>' , ** bgp_neighbor ) <EOL> def neighbor_update ( self , address , conf_type , conf_value ) : <EOL> """<STR_LIT>""" <EOL> assert conf_type == NEIGHBOR_CONF_MED or conf_type == CONNECT_MODE <EOL> func_name = '<STR_LIT>' <EOL> attribute_param = { } <EOL> if conf_type == NEIGHBOR_CONF_MED : <EOL> attribute_param = { neighbors . MULTI_EXIT_DISC : conf_value } <EOL> elif conf_type == CONNECT_MODE : <EOL> attribute_param = { neighbors . CONNECT_MODE : conf_value } <EOL> param = { neighbors . IP_ADDRESS : address , <EOL> neighbors . CHANGES : attribute_param } <EOL> call ( func_name , ** param ) <EOL> def neighbor_state_get ( self , address = None , format = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> show = { } <EOL> show [ '<STR_LIT>' ] = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> if address : <EOL> show [ '<STR_LIT>' ] . append ( address ) <EOL> show [ '<STR_LIT>' ] = format <EOL> return call ( '<STR_LIT>' , ** show ) <EOL> def prefix_add ( self , prefix , next_hop = None , route_dist = None ) : <EOL> """<STR_LIT>""" <EOL> func_name = '<STR_LIT>' <EOL> networks = { } <EOL> networks [ PREFIX ] = prefix <EOL> if next_hop : <EOL> networks [ NEXT_HOP ] = next_hop <EOL> if route_dist : <EOL> func_name = '<STR_LIT>' <EOL> networks [ ROUTE_DISTINGUISHER ] = route_dist <EOL> rf , p = self . _check_rf_and_normalize ( prefix ) <EOL> networks [ ROUTE_FAMILY ] = rf <EOL> networks [ PREFIX ] = p <EOL> if rf == vrfs . VRF_RF_IPV6 and netaddr . valid_ipv4 ( next_hop ) : <EOL> networks [ NEXT_HOP ] = str ( netaddr . IPAddress ( next_hop ) . ipv6 ( ) ) <EOL> return call ( func_name , ** networks ) <EOL> def prefix_del ( self , prefix , route_dist = None ) : <EOL> """<STR_LIT>""" <EOL> func_name = '<STR_LIT>' <EOL> networks = { } <EOL> networks [ PREFIX ] = prefix <EOL> if route_dist : <EOL> func_name = '<STR_LIT>' <EOL> networks [ ROUTE_DISTINGUISHER ] = route_dist <EOL> rf , p = self . _check_rf_and_normalize ( prefix ) <EOL> networks [ ROUTE_FAMILY ] = rf <EOL> networks [ PREFIX ] = p <EOL> call ( func_name , ** networks ) <EOL> def vrf_add ( self , route_dist , import_rts , export_rts , site_of_origins = None , <EOL> route_family = RF_VPN_V4 , multi_exit_disc = None ) : <EOL> """<STR_LIT>""" <EOL> assert route_family in ( RF_VPN_V4 , RF_VPN_V6 ) , '<STR_LIT>' <EOL> vrf = { } <EOL> vrf [ vrfs . ROUTE_DISTINGUISHER ] = route_dist <EOL> vrf [ vrfs . IMPORT_RTS ] = import_rts <EOL> vrf [ vrfs . EXPORT_RTS ] = export_rts <EOL> vrf [ vrfs . SITE_OF_ORIGINS ] = site_of_origins <EOL> vrf [ vrfs . VRF_RF ] = route_family <EOL> call ( '<STR_LIT>' , ** vrf ) <EOL> def vrf_del ( self , route_dist ) : <EOL> """<STR_LIT>""" <EOL> vrf = { } <EOL> vrf [ vrfs . ROUTE_DISTINGUISHER ] = route_dist <EOL> call ( '<STR_LIT>' , ** vrf ) <EOL> def vrfs_get ( self , format = '<STR_LIT>' ) : <EOL> show = { } <EOL> show [ '<STR_LIT>' ] = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:all>' ] <EOL> show [ '<STR_LIT>' ] = format <EOL> return call ( '<STR_LIT>' , ** show ) <EOL> def rib_get ( self , family = '<STR_LIT>' , format = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> show = { } <EOL> show [ '<STR_LIT>' ] = [ '<STR_LIT>' , family ] <EOL> show [ '<STR_LIT>' ] = format <EOL> return call ( '<STR_LIT>' , ** show ) <EOL> def neighbor_get ( self , routetype , address , format = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> show = { } <EOL> if routetype == '<STR_LIT>' or routetype == '<STR_LIT>' : <EOL> show [ '<STR_LIT>' ] = [ '<STR_LIT>' , routetype , address , '<STR_LIT:all>' ] <EOL> else : <EOL> show [ '<STR_LIT>' ] = [ '<STR_LIT>' , '<STR_LIT>' , address , '<STR_LIT:all>' ] <EOL> show [ '<STR_LIT>' ] = format <EOL> return call ( '<STR_LIT>' , ** show ) <EOL> def _set_filter ( self , filter_type , address , filters ) : <EOL> assert filter_type in ( '<STR_LIT>' , '<STR_LIT>' ) , '<STR_LIT>' <EOL> assert all ( isinstance ( f , Filter ) for f in filters ) , '<STR_LIT>' <EOL> if filters is None : <EOL> filters = [ ] <EOL> func_name = '<STR_LIT>' + filter_type + '<STR_LIT>' <EOL> param = { } <EOL> param [ neighbors . IP_ADDRESS ] = address <EOL> if filter_type == '<STR_LIT>' : <EOL> param [ neighbors . IN_FILTER ] = filters <EOL> else : <EOL> param [ neighbors . OUT_FILTER ] = filters <EOL> call ( func_name , ** param ) <EOL> def out_filter_set ( self , address , filters ) : <EOL> """<STR_LIT>""" <EOL> self . _set_filter ( '<STR_LIT>' , address , filters ) <EOL> def out_filter_get ( self , address ) : <EOL> """<STR_LIT>""" <EOL> func_name = '<STR_LIT>' <EOL> param = { } <EOL> param [ neighbors . IP_ADDRESS ] = address <EOL> out_filter = call ( func_name , ** param ) <EOL> return out_filter <EOL> def in_filter_set ( self , address , filters ) : <EOL> """<STR_LIT>""" <EOL> self . _set_filter ( '<STR_LIT>' , address , filters ) <EOL> def in_filter_get ( self , address ) : <EOL> """<STR_LIT>""" <EOL> func_name = '<STR_LIT>' <EOL> param = { } <EOL> param [ neighbors . IP_ADDRESS ] = address <EOL> in_filter = call ( func_name , ** param ) <EOL> return in_filter <EOL> def bmp_server_add ( self , address , port ) : <EOL> """<STR_LIT>""" <EOL> func_name = '<STR_LIT>' <EOL> param = { } <EOL> param [ '<STR_LIT:host>' ] = address <EOL> param [ '<STR_LIT:port>' ] = port <EOL> call ( func_name , ** param ) <EOL> def bmp_server_del ( self , address , port ) : <EOL> """<STR_LIT>""" <EOL> func_name = '<STR_LIT>' <EOL> param = { } <EOL> param [ '<STR_LIT:host>' ] = address <EOL> param [ '<STR_LIT:port>' ] = port <EOL> call ( func_name , ** param ) <EOL> def attribute_map_set ( self , address , attribute_maps , <EOL> route_dist = None , route_family = RF_VPN_V4 ) : <EOL> """<STR_LIT>""" <EOL> assert route_family in ( RF_VPN_V4 , RF_VPN_V6 ) , '<STR_LIT>' <EOL> func_name = '<STR_LIT>' <EOL> param = { } <EOL> param [ neighbors . IP_ADDRESS ] = address <EOL> param [ neighbors . ATTRIBUTE_MAP ] = attribute_maps <EOL> if route_dist is not None : <EOL> param [ vrfs . ROUTE_DISTINGUISHER ] = route_dist <EOL> param [ vrfs . VRF_RF ] = route_family <EOL> call ( func_name , ** param ) <EOL> def attribute_map_get ( self , address , route_dist = None , <EOL> route_family = RF_VPN_V4 ) : <EOL> """<STR_LIT>""" <EOL> assert route_family in ( RF_VPN_V4 , RF_VPN_V6 ) , '<STR_LIT>' <EOL> func_name = '<STR_LIT>' <EOL> param = { } <EOL> param [ neighbors . IP_ADDRESS ] = address <EOL> if route_dist is not None : <EOL> param [ vrfs . ROUTE_DISTINGUISHER ] = route_dist <EOL> param [ vrfs . VRF_RF ] = route_family <EOL> attribute_maps = call ( func_name , ** param ) <EOL> return attribute_maps <EOL> @ staticmethod <EOL> def _check_rf_and_normalize ( prefix ) : <EOL> """<STR_LIT>""" <EOL> ip , masklen = prefix . split ( '<STR_LIT:/>' ) <EOL> if netaddr . valid_ipv6 ( ip ) : <EOL> ipv6_prefix = str ( netaddr . IPAddress ( ip ) ) + '<STR_LIT:/>' + masklen <EOL> return vrfs . VRF_RF_IPV6 , ipv6_prefix <EOL> else : <EOL> return vrfs . VRF_RF_IPV4 , prefix </s>
