def _update_received(self, timestamp, msg): # if self.msg_recv_stat['Updates'] % 1000 == 0: # LOG.info(self.msg_recv_stat['Updates']) # LOG.info(time.time()) """Called when a BGP Update message was received.""" result = Update().parse(timestamp, msg, self.fourbytesas, self.add_path_ipv4_receive, self.add_path_ipv4_send) if result['sub_error']: msg = { 'attr': result['attr'], 'nlri': result['nlri'], 'withdraw': result['withdraw'], 'hex': repr(result['hex']) } self.handler.on_update_error(self, timestamp, msg) LOG.error('[%s] Update message error: sub error=%s', self.factory.peer_addr, result['sub_error']) self.msg_recv_stat['Updates'] += 1 self.fsm.update_received() return afi_safi = None # process messages if result['nlri'] or result['withdraw']: afi_safi = 'ipv4' elif result['attr'].get(14): afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][14]['afi_safi']] elif result['attr'].get(15): afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][15]['afi_safi']] msg = { 'attr': result['attr'], 'nlri': result['nlri'], 'withdraw': result['withdraw'], 'afi_safi': afi_safi } self.update_receive_verion(result['attr'], result['nlri'], result['withdraw']) if CONF.bgp.rib: # try to update bgp rib in if msg.get('afi_safi') == 'ipv4': self.update_rib_in_ipv4(msg) # LOG.info(msg) self.handler.update_received(self, timestamp, msg) self.msg_recv_stat['Updates'] += 1 self.fsm.update_received()
def update_received(self, timestamp, msg): """Called when a BGP Update message was received.""" result = Update().parse(timestamp, msg, self.fourbytesas, self.add_path_ipv4_receive, self.add_path_ipv4_send) if result['sub_error']: msg = { 'attr': result['attr'], 'nlri': result['nlri'], 'withdraw': result['withdraw'], 'hex': repr(result['hex']) } self.factory.write_msg( timestamp=result['time'], msg_type=6, msg={'msg': msg}, flush=True ) LOG.error('[%s] Update message error: sub error=%s', self.factory.peer_addr, result['sub_error']) self.msg_recv_stat['Updates'] += 1 self.fsm.update_received() return afi_safi = None # process messages if result['nlri'] or result['withdraw']: afi_safi = 'ipv4' elif result['attr'].get(14): afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][14]['afi_safi']] elif result['attr'].get(15): afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][15]['afi_safi']] msg = { 'attr': result['attr'], 'nlri': result['nlri'], 'withdraw': result['withdraw'], 'afi_safi': afi_safi } # write message to disk self.factory.write_msg( timestamp=result['time'], msg_type=bgp_cons.MSG_UPDATE, msg={"msg": msg} ) self.factory.flush_and_check_file_size() # check channel filter if not CONF.standalone and self.factory.tag in \ [channel_cons.SOURCE_ROUTER_TAG, channel_cons.SOURCE_AND_TARGET_ROUTER_TAG]: self.channel_filter(msg=msg) # update rib self.update_rib(msg) self.msg_recv_stat['Updates'] += 1 self.fsm.update_received()
def construct_update_to_bin(self, msg): """ construct update message to binary :param msg: message dictionary :return: """ try: msg_update = Update().construct(msg, self.fourbytesas, self.add_path_ipv4_send) return msg_update except Exception as e: LOG.error(e) return "construct failed"
def send_update(self, msg): """ send update message to the peer :param msg: message dictionary :return: """ try: msg_update = Update().construct(msg, self.fourbytesas) self.transport.write(msg_update) self.msg_sent_stat['Updates'] += 1 return True except Exception as e: LOG.error(e) return False
def send_update(self, msg): """ send update message to the peer :param msg: message dictionary :return: """ try: msg_update = Update().construct(msg, self.fourbytesas, self.add_path_ipv4_send) reactor.callFromThread(self.write_tcp_thread, msg_update) self.msg_sent_stat['Updates'] += 1 return True except Exception as e: LOG.error(e) return False
def update_received(self, timestamp, msg): """Called when a BGP Update message was received.""" result = Update().parse(timestamp, msg, self.fourbytesas, self.add_path_ipv4_receive, self.add_path_ipv4_send) if result['sub_error']: msg = { 'attr': result['attr'], 'nlri': result['nlri'], 'withdraw': result['withdraw'], 'hex': repr(result['hex']) } self.factory.write_msg( timestamp=result['time'], msg_type=6, msg={'msg': msg}, flush=True ) LOG.error('[%s] Update message error: sub error=%s', self.factory.peer_addr, result['sub_error']) self.msg_recv_stat['Updates'] += 1 self.fsm.update_received() return # process messages msg = { 'attr': result['attr'], 'nlri': result['nlri'], 'withdraw': result['withdraw'] } # write message to disk self.factory.write_msg( timestamp=result['time'], msg_type=bgp_cons.MSG_UPDATE, msg={"msg": msg} ) if self.factory.flush_and_check_file_size(): for afi, safi in CONF.bgp.running_config[self.factory.peer_addr]['capability']['remote']['afi_safi']: self.send_route_refresh(afi=afi, safi=safi) # check channel filter if not CONF.standalone and self.factory.tag in \ [channel_cons.SOURCE_ROUTER_TAG, channel_cons.SOURCE_AND_TARGET_ROUTER_TAG]: self.channel_filter(msg=msg) # update rib self.update_rib(msg) self.msg_recv_stat['Updates'] += 1 self.fsm.update_received()
def update_received(self, timestamp, msg): """Called when a BGP Update message was received.""" result = Update().parse(timestamp, msg, self.fourbytesas, self.add_path_ipv4_receive, self.add_path_ipv4_send) if result['sub_error']: msg = { 'attr': result['attr'], 'nlri': result['nlri'], 'withdraw': result['withdraw'], 'hex': repr(result['hex']) } self.factory.write_msg(timestamp=result['time'], msg_type=6, msg=msg, flush=True) LOG.error('[%s] Update message error: sub error=%s', self.factory.peer_addr, result['sub_error']) self.msg_recv_stat['Updates'] += 1 self.fsm.update_received() return afi_safi = None # process messages if result['nlri'] or result['withdraw']: afi_safi = 'ipv4' elif result['attr'].get(14): afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][14]['afi_safi']] elif result['attr'].get(15): afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][15]['afi_safi']] msg = { 'attr': result['attr'], 'nlri': result['nlri'], 'withdraw': result['withdraw'], 'afi_safi': afi_safi } # write message to disk self.factory.write_msg(timestamp=result['time'], msg_type=bgp_cons.MSG_UPDATE, msg=msg) self.factory.flush_and_check_file_size() self.msg_recv_stat['Updates'] += 1 self.fsm.update_received()
def update_received(self, timestamp, msg): """Called when a BGP Update message was received.""" result = Update().parse([timestamp, self.fourbytesas, msg]) if result['sub_error']: self.factory.write_msg( timestamp=result['time'], msg_type=6, msg={ 'attr': result['attr'], 'nlri': result['nlri'], 'withdraw': result['withdraw'] }, flush=True ) LOG.error('[%s] Update message error: sub error=%s', self.factory.peer_addr, result['sub_error']) else: msg = { 'attr': result['attr'], 'nlri': result['nlri'], 'withdraw': result['withdraw'] } self.factory.write_msg( timestamp=result['time'], msg_type=bgp_cons.MSG_UPDATE, msg=msg, flush=True ) # update rib in ipv4 for prefix in msg['nlri']: self._adj_rib_in['ipv4'][prefix] = msg['attr'] for prefix in msg['withdraw']: if prefix in self._adj_rib_in['ipv4']: self._adj_rib_in['ipv4'].pop(prefix) else: LOG.warning('withdraw prefix which does not exist in rib table!') if not CONF.standalone: self.factory.channel.send_message(exchange='', routing_key=self.factory.peer_addr, message=str(msg)) self.msg_recv_stat['Updates'] += 1 self.fsm.update_received()
def _update_received(self, timestamp, msg): """Called when a BGP Update message was received.""" result = Update().parse(timestamp, msg, self.fourbytesas, self.add_path_ipv4_receive, self.add_path_ipv4_send) if result['sub_error']: msg = { 'attr': result['attr'], 'nlri': result['nlri'], 'withdraw': result['withdraw'], 'hex': repr(result['hex']) } self.handler.on_update_error(self, timestamp, msg) LOG.error('[%s] Update message error: sub error=%s', self.factory.peer_addr, result['sub_error']) self.msg_recv_stat['Updates'] += 1 self.fsm.update_received() return afi_safi = None # process messages if result['nlri'] or result['withdraw']: afi_safi = 'ipv4' elif result['attr'].get(14): afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][14]['afi_safi']] elif result['attr'].get(15): afi_safi = bgp_cons.AFI_SAFI_DICT[result['attr'][15]['afi_safi']] msg = { 'attr': result['attr'], 'nlri': result['nlri'], 'withdraw': result['withdraw'], 'afi_safi': afi_safi } self.handler.update_received(self, timestamp, msg) self.msg_recv_stat['Updates'] += 1 self.fsm.update_received()
def parse_route_monitoring_msg(msg): """ Route Monitoring messages are used for initial synchronization of ADJ-RIBs-In. They are also used for ongoing monitoring of received advertisements and withdraws. Following the common BMP header and per-peer header is a BGP Update PDU. :param msg: :return: """ LOG.debug('decode route monitoring message') bgp_msg_type = struct.unpack('!B', msg[18])[0] LOG.debug('bgp message type=%s' % bgp_msg_type) msg = msg[bgp_cons.HDR_LEN:] if bgp_msg_type == 2: # decode update message results = Update().parse(None, msg, asn4=True) if results['sub_error']: LOG.error( 'error: decode update message error!, error code: %s' % results['sub_error']) LOG.error('Raw data: %s' % repr(results['hex'])) return None return_result = { 'attr': results['attr'], 'nlri': results['nlri'], 'withdraw': results['withdraw'] } LOG.debug('bgp update message: %s' % return_result) return bgp_msg_type, return_result elif bgp_msg_type == 5: bgp_route_refresh_msg = RouteRefresh().parse(msg=msg) LOG.debug('bgp route refresh message: afi=%s,res=%s,safi=%s' % (bgp_route_refresh_msg[0], bgp_route_refresh_msg[1], bgp_route_refresh_msg[2])) return bgp_msg_type, { 'afi': bgp_route_refresh_msg[0], 'sub_type': bgp_route_refresh_msg[1], 'safi': bgp_route_refresh_msg[2] }
def parse_route_mirroring_msg(msg): """ Route Mirroring messages are used for verbatim duplication of messages as received. Following the common BMP header and per-peer header is a set of TLVs that contain information about a message or set of messages. :param msg: :return: """ LOG.debug('decode route mirroring message') msg_dict = {} open_l = [] update = [] notification = [] route_refresh = [] while msg: mirror_type, length = struct.unpack('!HH', msg[0:4]) mirror_value = msg[4:4 + length] msg = msg[4 + length:] if mirror_type == 0: # BGP message type bgp_msg_type = struct.unpack('!B', mirror_value[18])[0] LOG.debug('bgp message type=%s' % bgp_msg_type) bgp_msg_body = mirror_value[bgp_cons.HDR_LEN:] if bgp_msg_type == 2: # Update message bgp_update_msg = Update().parse(None, bgp_msg_body, asn4=True) if bgp_update_msg['sub_error']: LOG.error( 'error: decode update message error!, error code: %s' % bgp_update_msg['sub_error']) LOG.error('Raw data: %s' % repr(bgp_update_msg['hex'])) else: update.append(bgp_update_msg) elif bgp_msg_type == 5: # Route Refresh message bgp_route_refresh_msg = RouteRefresh().parse( msg=bgp_msg_body) LOG.debug( 'bgp route refresh message: afi=%s,res=%s,safi=%s' % (bgp_route_refresh_msg[0], bgp_route_refresh_msg[1], bgp_route_refresh_msg[2])) route_refresh.append(bgp_route_refresh_msg) elif bgp_msg_type == 1: # Open message open_msg = Open().parse(bgp_msg_body) open_l.append(open_msg) elif bgp_msg_type == 3: # Notification message notification_msg = Notification().parse(bgp_msg_body) notification.append(notification_msg) elif mirror_type == 1: # Information type. # Amount of this TLV is not specified but we can assume # only one per mirroring message is present. info_code_type = struct.unpack('!H', mirror_value)[0] msg_dict['1'] = info_code_type else: msg_dict[mirror_type] = binascii.unhexlify( binascii.hexlify(mirror_value)) LOG.info('unknow mirroring type, type = %s' % mirror_type) msg_dict['0'] = { 'update': update, 'route_refresh': route_refresh, 'open': open_l, 'notification': notification } return msg_dict