Esempio n. 1
0
class BGPListener(object):
    def __init__(self):
        logger.info('Initializing the BGPListener')

        # Initialize XRS Server
        self.server = Server(logger)
        self.run = True

    def start(self):
        logger.info("Starting the Server to handle incoming BGP Updates.")
        self.server.start()

        waiting = 0
        while self.run:
            # get BGP messages from ExaBGP via stdin in client.py,
            # which is routed to server.py via port 6000,
            # which is routed to here via receiver_queue.
            try:
                route = self.server.receiver_queue.get(True, 1)
            except Queue.Empty:
                if waiting == 0:
                    logger.debug("Waiting for BGP update...")
                waiting = (waiting + 1) % 30
                continue

            waiting = 0
            route = json.loads(route)

            logger.debug("Got route from ExaBGP: %s", route)

            # Received BGP route advertisement from ExaBGP
            try:
                advertise_ip = route['neighbor']['ip']
            except KeyError:
                continue

            found = []
            with participantsLock:
                try:
                    advertise_id = portip2participant[advertise_ip]
                    peers_out = participants[advertise_id].peers_out
                except KeyError:
                    continue

                for id, peer in participants.iteritems():
                    # Apply the filtering logic
                    if id in peers_out and advertise_id in peer.peers_in:
                        found.append(peer)

            for peer in found:
                # Now send this route to participant `id`'s controller'
                peer.send(route)

    def send(self, announcement):
        self.server.sender_queue.put(announcement)

    def stop(self):
        logger.info("Stopping BGPListener.")
        self.run = False
Esempio n. 2
0
    def __init__(self, config_file):
        logger.info("Initializing the Route Server.")

        # Init the Route Server
        self.server = None
        self.ah_socket = None
        self.participants = {}

        # Several useful mappings
        self.port_2_participant = {}
        self.participant_2_port = {}
        self.portip_2_participant = {}
        self.participant_2_portip = {}
        self.portmac_2_participant = {}
        self.participant_2_portmac = {}
        self.asn_2_participant = {}
        self.participant_2_asn = {}

        ## Parse Config
        self.parse_config(config_file)

        # Initialize a XRS Server
        self.server = Server(logger)
        self.run = True
        """
        Start the announcement Listener which will receive announcements
        from participants's controller and put them in XRS's sender queue.
        """
        self.set_announcement_handler()
Esempio n. 3
0
    def __init__(self, config_file):
        logger.info("Initializing the Route Server.")

        # Init the Route Server
        self.server = None
        self.ah_socket = None
        self.participants = {}

        # Several useful mappings
        self.port_2_participant = {}
        self.participant_2_port = {}
        self.portip_2_participant = {}
        self.participant_2_portip = {}
        self.portmac_2_participant = {}
        self.participant_2_portmac = {}
        self.asn_2_participant = {}
        self.participant_2_asn = {}

        ## Parse Config
        self.parse_config(config_file)

        # Initialize a XRS Server
        self.server = Server(logger)
        self.run = True

        """
        Start the announcement Listener which will receive announcements
        from participants's controller and put them in XRS's sender queue.
        """
        self.set_announcement_handler()
Esempio n. 4
0
    def __init__(self, as_num):
        logger.info('Initializing the BGPListener')

        # Initialize XRS Server
        self.server = Server(logger)
        self.run = True
        self.route_id = 0
        self.start_time = 0
        self.end_time = 0
        self.as_num = int(as_num)
        self.stop_counts = 0
Esempio n. 5
0
 def __init__(self,event_queue,ready_queue,sdx):
     
     self.event_queue = event_queue
     self.ready_queue = ready_queue
     self.server = Server()
     
     self.sdx = sdx
     self.sdx.server = self.server
     
     participants_ports_list = get_participants_ports_list(sdx.participants)
     
     ''' Create and assign participant RIBs '''
     for participant_name in sdx.participants:
         self.sdx.participants[participant_name].rs_client = Peer(participants_ports_list[participant_name])
    def __init__(self, event_queue, ready_queue, sdx):

        self.event_queue = event_queue
        self.ready_queue = ready_queue
        self.server = Server()

        self.sdx = sdx
        self.sdx.server = self.server

        participants_ports_list = get_participants_ports_list(sdx.participants)
        ''' Create and assign participant RIBs '''
        for participant_name in sdx.participants:
            self.sdx.participants[participant_name].rs_client = Peer(
                participants_ports_list[participant_name])
Esempio n. 7
0
    def __init__(self, swift_config):
        logger.info('Initializing the BGPListener')

        # Initialize XRS Server
        self.server = Server(logger)
        self.run = True

        #Get Bpa parameters from sdg_global config file
        self.win_size = swift_config["win_size"]
        self.nb_withdrawals_burst_start = swift_config[
            "nb_withdrawals_burst_start"]
        self.nb_withdrawals_burst_end = swift_config[
            "nb_withdrawals_burst_end"]
        self.min_bpa_burst_size = swift_config["min_bpa_burst_size"]
        self.fm_freq = swift_config["fm_freq"]
        self.p_w = swift_config["p_w"]
        self.r_w = swift_config["r_w"]
        self.bpa_algo = swift_config["Bpa Algorithm"]
        self.max_depth = swift_config["max_depth"]
        self.nb_bits_aspath = swift_config["nb_bits_aspath"]
        self.run_encoding_threshold = swift_config["run_encoding_threshold"]
        self.silent = swift_config["silent"]
Esempio n. 8
0
class route_server():
    
    def __init__(self,event_queue,ready_queue,sdx):
        
        self.event_queue = event_queue
        self.ready_queue = ready_queue
        self.server = Server()
        
        self.sdx = sdx
        self.sdx.server = self.server
        
        participants_ports_list = get_participants_ports_list(sdx.participants)
        
        ''' Create and assign participant RIBs '''
        for participant_name in sdx.participants:
            self.sdx.participants[participant_name].rs_client = Peer(participants_ports_list[participant_name])
        
    def start(self):
        
        self.server.start()
    
        while True:
            route = self.server.receiver_queue.get()
            route = json.loads(route)
                
            # TODO: check the RIB update flow with others ...
            # At the moment, I am updating the RIB and will attach next-hop to the announcement at the end
                
            updates = []
            route_list = None
            
            # Update RIBs
            for participant_name in self.sdx.participants:
                route_list = self.sdx.participants[participant_name].rs_client.update(route)
                if route_list:
                    break
                
            # Best Path Selection algorithm
            for route_item in route_list:
                updates.extend(decision_process(self.sdx.participants,route_item))
            
            # Check for withdraw routes
            for route in route_list:
                if (route is None):
                    continue
                elif 'withdraw' in route:
                    for VNH in self.sdx.VNH_2_pfx:
                        if(route['withdraw']['prefix'] in list(self.sdx.VNH_2_pfx[VNH])):
                            self.server.sender_queue.put(withdraw_route(route['withdraw'],self.sdx.VNH_2_IP[VNH]))
                            break
            
            # Trigger policy updates
            bgp_trigger_update(self.event_queue,self.ready_queue)
           
            # Check for announced routes         
            #if (route_list):
            # TODO: need to correct this glue logic
            if hasattr(self.sdx, 'VNH_2_pfx'):
                for VNH in self.sdx.VNH_2_pfx:
                    for prefix in list(self.sdx.VNH_2_pfx[VNH]):
                        for paticipant_name in self.sdx.participants:
                            route = self.sdx.participants[paticipant_name].rs_client.get_route('local',prefix)
                            if route:
                                self.server.sender_queue.put(announce_route(route,self.sdx.VNH_2_IP[VNH]))
                                break
Esempio n. 9
0
class route_server(object):
    def __init__(self, config_file):
        logger.info("Initializing the Route Server.")

        # Init the Route Server
        self.server = None
        self.ah_socket = None
        self.participants = {}

        # Several useful mappings
        self.port_2_participant = {}
        self.participant_2_port = {}
        self.portip_2_participant = {}
        self.participant_2_portip = {}
        self.portmac_2_participant = {}
        self.participant_2_portmac = {}
        self.asn_2_participant = {}
        self.participant_2_asn = {}

        ## Parse Config
        self.parse_config(config_file)

        # Initialize a XRS Server
        self.server = Server(logger)
        self.run = True
        """
        Start the announcement Listener which will receive announcements
        from participants's controller and put them in XRS's sender queue.
        """
        self.set_announcement_handler()

    def start(self):
        logger.info("Starting the Server to handle incoming BGP Updates.")
        self.server.start()

        waiting = 0

        while self.run:
            # get BGP messages from ExaBGP via stdin
            try:
                route = self.server.receiver_queue.get(True, 1)
                route = json.loads(route)

                waiting = 0

                logger.debug("Got route from ExaBGP. " + str(route) + ' ' +
                             str(type(route)))

                # Received BGP route advertisement from ExaBGP
                for id, peer in self.participants.iteritems():
                    # Apply the filtering logic
                    advertiser_ip = route['neighbor']['ip']
                    if advertiser_ip in self.portip_2_participant:
                        advertise_id = self.portip_2_participant[advertiser_ip]
                        if id in self.participants[
                                advertise_id].peers_out and advertise_id in self.participants[
                                    id].peers_in:
                            # Now send this route to participant `id`'s controller'
                            self.send_update(id, route)

            except Queue.Empty:
                if waiting == 0:
                    logger.debug("Waiting for BGP update...")
                    waiting = 1
                else:
                    waiting = (waiting % 30) + 1
                    if waiting == 30:
                        logger.debug("Waiting for BGP update...")

    def parse_config(self, config_file):
        # loading config file

        logger.debug("Begin parsing config...")

        config = json.load(open(config_file, 'r'))

        self.ah_socket = tuple(config["Route Server"]["AH_SOCKET"])

        for participant_name in config["Participants"]:
            participant = config["Participants"][participant_name]

            iname = int(participant_name)

            # adding asn and mappings
            asn = participant["ASN"]
            self.asn_2_participant[participant["ASN"]] = iname
            self.participant_2_asn[iname] = participant["ASN"]

            self.participant_2_port[iname] = []
            self.participant_2_portip[iname] = []
            self.participant_2_portmac[iname] = []

            for port in participant["Ports"]:
                self.port_2_participant[port['Id']] = iname
                self.portip_2_participant[port['IP']] = iname
                self.portmac_2_participant[port['MAC']] = iname
                self.participant_2_port[iname].append(port['Id'])
                self.participant_2_portip[iname].append(port['IP'])
                self.participant_2_portmac[iname].append(port['MAC'])

            # adding ports and mappings
            ports = [{
                "ID": port['Id'],
                "MAC": port['MAC'],
                "IP": port['IP']
            } for port in participant["Ports"]]

            peers_out = [peer for peer in participant["Peers"]]
            # TODO: Make sure this is not an insane assumption
            peers_in = peers_out

            addr, port = participant["EH_SOCKET"]
            eh_socket = (str(addr), int(port))

            # create peer and add it to the route server environment
            self.participants[iname] = XRSPeer(asn, ports, peers_in, peers_out,
                                               eh_socket)

        logger.debug("Done parsing config")

    def set_announcement_handler(self):
        '''Start the listener socket for BGP Announcements'''

        logger.info("Starting the announcement handler...")

        self.listener_eh = Listener(self.ah_socket, authkey=None)
        ps_thread = Thread(target=self.start_ah)
        ps_thread.daemon = True
        ps_thread.start()

    def start_ah(self):
        '''Announcement Handler '''

        logger.info("Announcement Handler started.")

        while True:
            conn_ah = self.listener_eh.accept()
            tmp = conn_ah.recv()

            logger.debug("Received an announcement.")

            announcement = json.loads(tmp)
            self.server.sender_queue.put(announcement)
            reply = "Announcement processed"
            conn_ah.send(reply)
            conn_ah.close()

    def send_update(self, id, route):
        # TODO: Explore what is better, persistent client sockets or
        # new socket for each BGP update
        "Send this BGP route to participant id's controller"
        logger.debug("Sending a route update to participant " + str(id))
        conn = Client(tuple(self.participants[id].eh_socket), authkey=None)
        conn.send(json.dumps({'bgp': route}))
        conn.recv()
        conn.close()

    def stop(self):

        logger.info("Stopping.")
        self.run = False
Esempio n. 10
0
    def __init__(self):
        logger.info('Initializing the BGPListener')

        # Initialize XRS Server
        self.server = Server(logger)
        self.run = True
Esempio n. 11
0
class BGPListener(object):
    def __init__(self):
        logger.info('Initializing the BGPListener')

        # Initialize XRS Server
        self.server = Server(logger)
        self.run = True


    def start(self):
        logger.info("Starting the Server to handle incoming BGP Updates.")
        self.server.start()

        waiting = 0
        while self.run:
            # get BGP messages from ExaBGP via stdin in client.py,
            # which is routed to server.py via port 6000,
            # which is routed to here via receiver_queue.
            try:
                route = self.server.receiver_queue.get(True, 1)
            except Queue.Empty:
                if waiting == 0:
                    logger.debug("Waiting for BGP update...")
                waiting = (waiting+1) % 30
                continue

            waiting = 0
            route = json.loads(route)

            logger.debug("Got route from ExaBGP: %s", route)

            # Received BGP route advertisement from ExaBGP
            try:
                advertise_ip = route['neighbor']['ip']
            except KeyError as e:
		logger.debug("KEY ERROR " + str(e.msg))
                continue

            found = []
            with participantsLock:
                try:
                    advertise_id = portip2participant[advertise_ip]
                    peers_out = participants[advertise_id].peers_out
                except KeyError:
                    logger.debug(str(participants))
                    continue
                logger.debug("PARTICIPANTS_SIZE " + str(len(participants)))
                for id, peer in participants.iteritems():
                    logger.debug("ADVDEBUG advertising %s to neighbor" % str(route))
                    # Apply the filtering logic
                    if id in peers_out and advertise_id in peer.peers_in:
                        found.append(peer)

            for peer in found:
                # Now send this route to participant `id`'s controller'
                logger.debug("SENDROUTETOPEER " + str(route))
                logger.info("PEERISOFTYPE: " + str(peer))
                peer.send(route)

    def send(self, announcement):
        logger.info("CRITICALQUEUEDEBUG " + str(self.server.sender_queue.qsize()))
        self.server.sender_queue.put(announcement)

    def stop(self):
        logger.info("Stopping BGPListener.")
        self.run = False
Esempio n. 12
0
class BGPListener(object):
    def __init__(self, swift_config):
        logger.info('Initializing the BGPListener')

        # Initialize XRS Server
        self.server = Server(logger)
        self.run = True

        #Get Bpa parameters from sdg_global config file
        self.win_size = swift_config["win_size"]
        self.nb_withdrawals_burst_start = swift_config[
            "nb_withdrawals_burst_start"]
        self.nb_withdrawals_burst_end = swift_config[
            "nb_withdrawals_burst_end"]
        self.min_bpa_burst_size = swift_config["min_bpa_burst_size"]
        self.fm_freq = swift_config["fm_freq"]
        self.p_w = swift_config["p_w"]
        self.r_w = swift_config["r_w"]
        self.bpa_algo = swift_config["Bpa Algorithm"]
        self.max_depth = swift_config["max_depth"]
        self.nb_bits_aspath = swift_config["nb_bits_aspath"]
        self.run_encoding_threshold = swift_config["run_encoding_threshold"]
        self.silent = swift_config["silent"]

    def start(self):
        logger.info("Starting the Server to handle incoming BGP Updates.")
        self.server.start()

        self.peer_swift_dict = {}

        self.peer_queue_dict = {}

        self.peer_queue = Queue.Queue()

        self.FR_queue = Queue.Queue()

        self.waiting = 0

        route_server_listener_thread = Thread(
            target=self.Route_server_listener)

        route_server_sender_thread = Thread(target=self.Route_server_sender)

        route_server_sender_thread.start()
        route_server_listener_thread.start()

    def send(self, announcement):
        self.server.sender_queue.put(announcement)

    def stop(self):
        logger.info("Stopping BGPListener.")
        self.run = False

    def Route_server_listener(self):

        while self.run:
            try:
                route = self.server.receiver_queue.get(True, 1)
            except Queue.Empty:
                if self.waiting == 0:
                    logger.debug("Waiting for BGP update...")
                self.waiting = (self.waiting + 1) % 30
                continue

            self.waiting = 0

            route = json.loads(route)

            logger.info("Got route from ExaBGP: %s", route)
            logger.debug("Got route from ExaBGP: %s", route)

            # Received BGP route advertisement from ExaBGP
            try:
                advertise_ip = route['neighbor']['ip']
            except KeyError:
                print "KEYERROR", route
                logger.debug("KEYERROR" + str(route))
                continue

            with participantsLock:
                try:
                    advertise_id = portip2participant[advertise_ip]
                except KeyError:
                    continue

            route_list = self.route_2_bgp_updates(route)

            if len(route_list) == 1:
                if 'down' in route_list[0]:
                    logger.debug("down route received" + str(route_list[0]))
                    self.peer_queue.put(route_list[0])
                    continue
            #@TODO: when no more links to participant are active stop its siwft process

            if advertise_id not in self.peer_queue_dict:
                print "launching swift for peer_id:", advertise_id
                self.peer_queue_dict[advertise_id] = Queue.Queue()
                with participantsLock:
                    self.peer_swift_dict[advertise_id] = Thread(target=run_peer, \
                                    args=(logger, self.peer_queue_dict[advertise_id], self.peer_queue, self.FR_queue, self.win_size,advertise_id, self.nb_withdrawals_burst_start, \
                                    self.nb_withdrawals_burst_end, self.min_bpa_burst_size, "bursts", self.max_depth, self.fm_freq, self.p_w, \
                                    self.r_w, self.bpa_algo, self.nb_bits_aspath, self.run_encoding_threshold, \
                                    self.silent))

                self.peer_swift_dict[advertise_id].start()

            for route in route_list:
                self.peer_queue_dict[advertise_id].put(route)

        for thread in self.peer_swift_dict.items():
            thread.stop()

    def Route_server_sender(self):
        while self.run:
            route = None
            try:
                route = self.FR_queue.get(False)
            except Queue.Empty:
                pass

            if route is None:
                try:
                    route = self.peer_queue.get(False)
                except Queue.Empty:
                    continue

            if 'FR' in route:
                peer_id = route['FR']['peer_id']
                found = []
                with participantsLock:
                    try:
                        peers_out = participants[peer_id].peers_out
                    except KeyError:
                        continue

                    for id, peer in participants.iteritems():
                        # Apply the filtering logic
                        if id in peers_out and peer_id in peer.peers_in:
                            found.append(peer)

                for peer in found:
                    # Now send this route to participant `id`'s controller'
                    peer.send_FR(route)

            elif 'down' in route:
                try:
                    advertise_ip = route['down']
                except KeyError:
                    print "KEYERROR", route
                    logger.debug("KEYERROR" + str(route))
                    continue
                found = []
                with participantsLock:
                    try:
                        advertise_id = portip2participant[advertise_ip]
                        peers_out = participants[advertise_id].peers_out
                    except KeyError:
                        continue

                    for id, peer in participants.iteritems():
                        # Apply the filtering logic
                        if id in peers_out and advertise_id in peer.peers_in:
                            found.append(peer)

                for peer in found:
                    # Now send this route to participant `id`'s controller'
                    peer.send_FR(route)

            else:

                if 'announce' in route:
                    try:
                        advertise_ip = route['announce'].neighbor
                    except KeyError:
                        print "KEYERROR", route
                        logger.debug("KEYERROR" + str(route))
                        continue
                if 'withdraw' in route:
                    try:
                        advertise_ip = route['withdraw'].neighbor
                    except KeyError:
                        print "KEYERROR", route
                        logger.debug("KEYERROR" + str(route))
                        continue

                found = []
                with participantsLock:
                    try:
                        advertise_id = portip2participant[advertise_ip]
                        peers_out = participants[advertise_id].peers_out
                    except KeyError:
                        continue

                    for id, peer in participants.iteritems():
                        # Apply the filtering logic
                        if id in peers_out and advertise_id in peer.peers_in:
                            found.append(peer)

                for peer in found:
                    # Now send this route to participant `id`'s controller'
                    peer.send(route)

    def route_2_bgp_updates(self, route):
        origin = None
        as_path = None
        as_path_vmac = None
        med = None
        atomic_aggregate = None
        communities = None

        route_list = []

        if 'state' in route['neighbor'] and route['neighbor'][
                'state'] == 'down':
            print "state down update received from:", route['neighbor']['ip']
            down_ip = route['neighbor']['ip']
            route_list.append({'down': down_ip})
            return route_list

        # Extract out neighbor information in the given BGP update
        neighbor = route["neighbor"]["ip"]
        if 'message' in route['neighbor']:
            if 'update' in route['neighbor']['message']:
                time = route['time']
                if 'attribute' in route['neighbor']['message']['update']:
                    attribute = route['neighbor']['message']['update'][
                        'attribute']

                    origin = attribute[
                        'origin'] if 'origin' in attribute else ''

                    as_path = attribute[
                        'as-path'] if 'as-path' in attribute else []

                    as_path_vmac = attribute[
                        'as_path_vmac'] if 'as_path_vmac' in attribute else None

                    med = attribute['med'] if 'med' in attribute else ''

                    community = attribute[
                        'community'] if 'community' in attribute else ''
                    communities = ''
                    for c in community:
                        communities += ':'.join(map(str, c)) + " "

                    atomic_aggregate = attribute[
                        'atomic-aggregate'] if 'atomic-aggregate' in attribute else ''

                if 'announce' in route['neighbor']['message']['update']:
                    announce = route['neighbor']['message']['update'][
                        'announce']
                    if 'ipv4 unicast' in announce:
                        for next_hop in announce['ipv4 unicast'].keys():
                            for prefix in announce['ipv4 unicast'][
                                    next_hop].keys():
                                announced_route = BGPRoute(
                                    prefix, neighbor, next_hop, origin,
                                    as_path, as_path_vmac, communities, med,
                                    atomic_aggregate)

                                route_list.append({
                                    'announce': announced_route,
                                    'time': time
                                })

                elif 'withdraw' in route['neighbor']['message']['update']:
                    withdraw = route['neighbor']['message']['update'][
                        'withdraw']
                    if 'ipv4 unicast' in withdraw:
                        next_hop = None
                        for prefix in withdraw['ipv4 unicast'].keys():
                            withdrawn_route = BGPRoute(
                                prefix,
                                neighbor,
                                next_hop,
                                origin,
                                as_path,
                                as_path_vmac,
                                communities,
                                med,
                                atomic_aggregate,
                            )
                            route_list.append({
                                'withdraw': withdrawn_route,
                                'time': time
                            })

        return route_list
Esempio n. 13
0
class BGPListener(object):
    def __init__(self, as_num):
        logger.info('Initializing the BGPListener')

        # Initialize XRS Server
        self.server = Server(logger)
        self.run = True
        self.route_id = 0
        self.start_time = 0
        self.end_time = 0
        self.as_num = int(as_num)
        self.stop_counts = 0

    def start(self):
        logger.info("Starting the Server to handle incoming BGP Updates.")
        self.server.start()

        waiting = 0
        while self.run:
            # get BGP messages from ExaBGP via stdin in client.py,
            # which is routed to server.py via port 6000,
            # which is routed to here via receiver_queue.
            try:
                route = self.server.receiver_queue.get(True, 1)
            except Queue.Empty:
                if waiting == 0:
                    logger.debug("Waiting for BGP update...")
                waiting = (waiting + 1) % 30
                continue

            if self.start_time == 0:
                self.start_time = time.time()

            waiting = 0
            logger.debug(
                "\n BGPListener: Got original route from ExaBGP: %s\n", route)
            route = json.loads(route)

            if 'stop' in route:
                logger.info("BGPListener: stop signal received from ExaBGP")
                peers = participants.values()
                for peer in peers:
                    peer.send([])
                continue
            self.route_id = route["route_id"]

            # Received BGP route advertisement from ExaBGP
            try:
                advertise_ip = route['neighbor']['ip']
            except KeyError:
                continue

            found = []
            with participantsLock:
                try:
                    advertise_id = portip2participant[advertise_ip]
                    peers_out = participants[advertise_id].peers_out
                except KeyError:
                    continue

                for id, peer in participants.iteritems():
                    # Apply the filtering logic
                    if id in peers_out and advertise_id in peer.peers_in:
                        found.append(peer)

            for peer in found:
                # Now send this route to participant `id`'s controller'
                peer.send(route)

            self.end_time = time.time()
        self.server.stop()

    def send(self, announcement):
        self.end_time = time.time()
        #self.server.sender_queue.put(announcement)

    def stop(self):
        logger.info("Stopping BGPListener.")
        self.run = False
Esempio n. 14
0
    def __init__(self):
        logger.info('Initializing the BGPListener')

        # Initialize XRS Server
        self.server = Server(logger)
        self.run = True
class route_server():
    def __init__(self, event_queue, ready_queue, sdx):

        self.event_queue = event_queue
        self.ready_queue = ready_queue
        self.server = Server()

        self.sdx = sdx
        self.sdx.server = self.server

        participants_ports_list = get_participants_ports_list(sdx.participants)
        ''' Create and assign participant RIBs '''
        for participant_name in sdx.participants:
            self.sdx.participants[participant_name].rs_client = Peer(
                participants_ports_list[participant_name])

    def start(self):

        self.server.start()

        while True:
            route = self.server.receiver_queue.get()
            route = json.loads(route)

            # TODO: check the RIB update flow with others ...
            # At the moment, I am updating the RIB and will attach next-hop to the announcement at the end

            updates = []
            route_list = None

            # Update RIBs
            for participant_name in self.sdx.participants:
                route_list = self.sdx.participants[
                    participant_name].rs_client.update(route)
                if route_list:
                    break

            # Best Path Selection algorithm
            for route_item in route_list:
                updates.extend(
                    decision_process(self.sdx.participants, route_item))

            # Check for withdraw routes
            for route in route_list:
                if (route is None):
                    continue
                elif 'withdraw' in route:
                    for VNH in self.sdx.VNH_2_pfx:
                        if (route['withdraw']['prefix']
                                in list(self.sdx.VNH_2_pfx[VNH])):
                            self.server.sender_queue.put(
                                withdraw_route(route['withdraw'],
                                               self.sdx.VNH_2_IP[VNH]))
                            break

            # Trigger policy updates
            bgp_trigger_update(self.event_queue, self.ready_queue)

            # Check for announced routes
            #if (route_list):
            # TODO: need to correct this glue logic
            if hasattr(self.sdx, 'VNH_2_pfx'):
                for VNH in self.sdx.VNH_2_pfx:
                    for prefix in list(self.sdx.VNH_2_pfx[VNH]):
                        for paticipant_name in self.sdx.participants:
                            route = self.sdx.participants[
                                paticipant_name].rs_client.get_route(
                                    'local', prefix)
                            if route:
                                self.server.sender_queue.put(
                                    announce_route(route,
                                                   self.sdx.VNH_2_IP[VNH]))
                                break
Esempio n. 16
0
class BGPListener(object):
    def __init__(self):
        logger.info('Initializing the BGPListener')

        # Initialize XRS Server
        self.server = Server(logger)
        self.run = True


    def start(self):
        logger.info("Starting the Server to handle incoming BGP Updates.")
        self.server.start()

        waiting = 0
        while self.run:
            # get BGP messages from ExaBGP via stdin in client.py,
            # which is routed to server.py via port 6000,
            # which is routed to here via receiver_queue.
            try:
                route = self.server.receiver_queue.get(True, 1)
            except Queue.Empty:
                if waiting == 0:
                    logger.debug("Waiting for BGP update...")
                waiting = (waiting+1) % 30
                continue

            waiting = 0
            route = json.loads(route)

            if 'state' in route['neighbor']:
                logger.debug("Got route state from ExaBGP: %s", route)
                if 'down' not in route['neighbor']['state']:
                    continue

            logger.debug("Got route from ExaBGP: %s", route)

            # Received BGP route advertisement from ExaBGP
            try:
                advertise_ip = route['neighbor']['ip']
            except KeyError:
                continue

            found = []
            with participantsLock:
                try:
                    advertise_id = portip2participant[advertise_ip]
                    peers_out = participants[advertise_id].peers_out
                except KeyError:
                    continue

                for id, peer in participants.iteritems():
                    # Apply the filtering logic
                    if id in peers_out and advertise_id in peer.peers_in:
                        found.append(peer)

            for peer in found:
                # Now send this route to participant `id`'s controller'
                peer.send(route)


    def send(self, announcement):
        self.server.sender_queue.put(announcement)


    def stop(self):
        logger.info("Stopping BGPListener.")
        self.run = False
Esempio n. 17
0
class route_server(object):

    def __init__(self, config_file):
        logger.info("Initializing the Route Server.")

        # Init the Route Server
        self.server = None
        self.ah_socket = None
        self.participants = {}

        # Several useful mappings
        self.port_2_participant = {}
        self.participant_2_port = {}
        self.portip_2_participant = {}
        self.participant_2_portip = {}
        self.portmac_2_participant = {}
        self.participant_2_portmac = {}
        self.asn_2_participant = {}
        self.participant_2_asn = {}

        ## Parse Config
        self.parse_config(config_file)

        # Initialize a XRS Server
        self.server = Server(logger)
        self.run = True

        """
        Start the announcement Listener which will receive announcements
        from participants's controller and put them in XRS's sender queue.
        """
        self.set_announcement_handler()


    def start(self):
        logger.info("Starting the Server to handle incoming BGP Updates.")
        self.server.start()

        waiting = 0

        while self.run:
            # get BGP messages from ExaBGP via stdin
            try:
                route = self.server.receiver_queue.get(True, 1)
                route = json.loads(route)

                waiting = 0

                logger.debug("Got route from ExaBGP. "+str(route)+' '+str(type(route)))

                # Received BGP route advertisement from ExaBGP
                for id, peer in self.participants.iteritems():
                    # Apply the filtering logic
                    advertiser_ip = route['neighbor']['ip']
                    if advertiser_ip in self.portip_2_participant:
                        advertise_id = self.portip_2_participant[advertiser_ip]
                        if id in self.participants[advertise_id].peers_out and advertise_id in self.participants[id].peers_in:
                            # Now send this route to participant `id`'s controller'
                            self.send_update(id, route)

            except Queue.Empty:
                if waiting == 0:
                    logger.debug("Waiting for BGP update...")
                    waiting = 1
                else:
                    waiting = (waiting % 30) + 1
                    if waiting == 30:
                        logger.debug("Waiting for BGP update...")


    def parse_config(self, config_file):
        # loading config file

        logger.debug("Begin parsing config...")

        config = json.load(open(config_file, 'r'))

        self.ah_socket = tuple(config["Route Server"]["AH_SOCKET"])

        for participant_name in config["Participants"]:
            participant = config["Participants"][participant_name]

            iname = int(participant_name)

            # adding asn and mappings
            asn = participant["ASN"]
            self.asn_2_participant[participant["ASN"]] = iname
            self.participant_2_asn[iname] = participant["ASN"]

            self.participant_2_port[iname] = []
            self.participant_2_portip[iname] = []
            self.participant_2_portmac[iname] = []

            for port in participant["Ports"]:
                self.port_2_participant[port['Id']] = iname
                self.portip_2_participant[port['IP']] = iname
                self.portmac_2_participant[port['MAC']] = iname
                self.participant_2_port[iname].append(port['Id'])
                self.participant_2_portip[iname].append(port['IP'])
                self.participant_2_portmac[iname].append(port['MAC'])

            # adding ports and mappings
            ports = [{"ID": port['Id'],
                         "MAC": port['MAC'],
                         "IP": port['IP']}
                         for port in participant["Ports"]]

            peers_out = [peer for peer in participant["Peers"]]
            # TODO: Make sure this is not an insane assumption
            peers_in = peers_out

            addr, port = participant["EH_SOCKET"]
            eh_socket = (str(addr), int(port))

            # create peer and add it to the route server environment
            self.participants[iname] = XRSPeer(asn, ports, peers_in, peers_out, eh_socket)

        logger.debug("Done parsing config")


    def set_announcement_handler(self):
        '''Start the listener socket for BGP Announcements'''

        logger.info("Starting the announcement handler...")

        self.listener_eh = Listener(self.ah_socket, authkey=None)
        ps_thread = Thread(target=self.start_ah)
        ps_thread.daemon = True
        ps_thread.start()


    def start_ah(self):
        '''Announcement Handler '''

        logger.info("Announcement Handler started.")

        while True:
            conn_ah = self.listener_eh.accept()
            tmp = conn_ah.recv()

            logger.debug("Received an announcement.")

            announcement = json.loads(tmp)
            self.server.sender_queue.put(announcement)
            reply = "Announcement processed"
            conn_ah.send(reply)
            conn_ah.close()


    def send_update(self, id, route):
        # TODO: Explore what is better, persistent client sockets or
        # new socket for each BGP update
        "Send this BGP route to participant id's controller"
        logger.debug("Sending a route update to participant "+str(id))
        conn = Client(tuple(self.participants[id].eh_socket), authkey = None)
        conn.send(json.dumps({'bgp': route}))
        conn.recv()
        conn.close()


    def stop(self):

        logger.info("Stopping.")
        self.run = False