def run (env, comment, configurations, pid=0): from exabgp.logger import Logger logger = Logger() if comment: logger.configuration(comment) if not env.profile.enable: ok = Reactor(configurations).run() __exit(env.debug.memory,0 if ok else 1) try: import cProfile as profile except ImportError: import profile if not env.profile.file or env.profile.file == 'stdout': ok = profile.run('Reactor(configurations).run()') __exit(env.debug.memory,0 if ok else 1) if pid: profile_name = "%s-pid-%d" % (env.profile.file,pid) else: profile_name = env.profile.file notice = '' if os.path.isdir(profile_name): notice = 'profile can not use this filename as outpout, it is not a directory (%s)' % profile_name if os.path.exists(profile_name): notice = 'profile can not use this filename as outpout, it already exists (%s)' % profile_name if not notice: logger.reactor('profiling ....') profiler = profile.Profile() profiler.enable() try: ok = Reactor(configurations).run() except Exception: raise finally: profiler.disable() kprofile = lsprofcalltree.KCacheGrind(profiler) with open(profile_name, 'w+') as write: kprofile.output(write) __exit(env.debug.memory,0 if ok else 1) else: logger.reactor("-"*len(notice)) logger.reactor(notice) logger.reactor("-"*len(notice)) Reactor(configurations).run() __exit(env.debug.memory,1)
def cmdline(cmdarg): env = getenv() # Must be done before setting the logger as it modify its behaviour if cmdarg.verbose: env.log.all = True env.log.level = syslog.LOG_DEBUG log.init() if cmdarg.pdb: env.debug.pdb = True if cmdarg.verbose: env.log.parser = True for configuration in cmdarg.configuration: log.notice(f'loading {configuration}', 'configuration') location = getconf(configuration) if not location: log.critical(f'{configuration} is not an exabgp config file', 'configuration') sys.exit(1) config = Reactor([location]).configuration if not config.reload(): log.critical(f'{configuration} is not a valid config file', 'configuration') sys.exit(1) log.info(f'\u2713 loading', 'configuration') if cmdarg.neighbor: log.notice(f'checking neighbors', 'configuration') for name, neighbor in config.neighbors.items(): reparsed = neighbor.string() for line in reparsed.split('\n'): log.debug(line, configuration) log.info(f'\u2713 neighbor {name.split()[1]}', 'configuration') if cmdarg.route: log.notice(f'checking routes', 'configuration') if not check_generation(config.neighbors): log.critical(f'{configuration} has an invalid route', 'configuration') sys.exit(1) log.info(f'\u2713 routes', 'configuration')
def cmdline(cmdarg): route = ''.join(cmdarg.payload).replace(' ', '') if not is_bgp(route): # parser.print_usage() sys.stdout.write('Environment values are:\n%s\n\n' % '\n'.join(' - %s' % _ for _ in Env.default())) sys.stdout.write('The BGP message must be an hexadecimal string.\n\n') sys.stdout.write('All colons or spaces are ignored, for example:\n\n') sys.stdout.write(' 001E0200000007900F0003000101\n') sys.stdout.write(' 001E:02:0000:0007:900F:0003:0001:01\n') sys.stdout.write( ' FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF001E0200000007900F0003000101\n') sys.stdout.write( ' FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:001E:02:0000:0007:900F:0003:0001:01\n' ) sys.stdout.write( " FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 001E02 00000007900F0003000101\n" ) sys.stdout.flush() sys.exit(1) env = getenv() env.bgp.passive = True env.log.parser = True env.tcp.bind = '' if cmdarg.debug: env.log.all = True env.log.level = 'DEBUG' if cmdarg.pdb: env.debug.pdb = True log.init(env) trace_interceptor(env.debug.pdb) sanitized = ''.join(cmdarg.payload).replace(':', '').replace(' ', '') if cmdarg.configuration: configuration = Configuration([getconf(cmdarg.configuration)]) elif cmdarg.family: families = cmdarg.family.split() if len(families) % 2: sys.stdout.write('families provided are invalid') sys.stdout.flush() sys.exit(1) families_pair = [families[n:n + 2] for n in range(0, len(families), 2)] families_text = ';'.join([f'{a} {s}' for a, s in families_pair]) conf = conf_none.replace('[families]', families_text) configuration = Configuration([conf], text=True) else: configuration = Configuration([conf_all], text=True) valid_nlri = Reactor(configuration).check(sanitized, cmdarg.nlri) if valid_nlri: return 0 return 1
def cmdline(cmdarg): route = ''.join(cmdarg.payload).replace(' ', '') if not is_bgp(route): # parser.print_usage() sys.stdout.write('Environment values are:\n%s\n\n' % '\n'.join(' - %s' % _ for _ in Env.default())) sys.stdout.write('The BGP message must be an hexadecimal string.\n\n') sys.stdout.write('All colons or spaces are ignored, for example:\n\n') sys.stdout.write(' 001E0200000007900F0003000101\n') sys.stdout.write(' 001E:02:0000:0007:900F:0003:0001:01\n') sys.stdout.write( ' FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF001E0200000007900F0003000101\n') sys.stdout.write( ' FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:001E:02:0000:0007:900F:0003:0001:01\n' ) sys.stdout.write( " FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 001E02 00000007900F0003000101\n" ) sys.stdout.flush() sys.exit(1) env = getenv() env.bgp.passive = True env.log.parser = True env.tcp.bind = '' if cmdarg.debug: env.log.all = True env.log.level = 'DEBUG' if cmdarg.pdb: env.debug.pdb = True log.init(env) trace_interceptor(env.debug.pdb) sanitized = ''.join(cmdarg.payload).replace(':', '').replace(' ', '') Reactor([getconf(cmdarg.configuration)]).check(sanitized)
def cmdline(cmdarg): route = ''.join(cmdarg.payload).replace(' ', '') if not is_bgp(route): # parser.print_usage() sys.stdout.write('Environment values are:\n%s\n\n' % '\n'.join(' - %s' % _ for _ in Env.default())) sys.stdout.write('The BGP message must be an hexadecimal string.\n\n') sys.stdout.write('All colons or spaces are ignored, for example:\n\n') sys.stdout.write(' 001E0200000007900F0003000101\n') sys.stdout.write(' 001E:02:0000:0007:900F:0003:0001:01\n') sys.stdout.write( ' FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF001E0200000007900F0003000101\n') sys.stdout.write( ' FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:001E:02:0000:0007:900F:0003:0001:01\n' ) sys.stdout.write( " FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 001E02 00000007900F0003000101\n" ) sys.stdout.flush() sys.exit(1) env = getenv() env.log.parser = True env.debug.route = route env.tcp.bind = '' if cmdarg.debug: env.log.all = True env.log.level = syslog.LOG_DEBUG if cmdarg.pdb: env.debug.pdb = True log.init() Reactor([cmdarg.configuration]).run(False, ROOT)
def run(comment, configurations, validate, pid=0): env = getenv() log.notice('Thank you for using ExaBGP', 'welcome') log.notice('%s' % version, 'version') log.notice('%s' % sys.version.replace('\n', ' '), 'interpreter') log.notice('%s' % ' '.join(platform.uname()[:5]), 'os') log.notice('%s' % ROOT, 'installation') if comment: log.notice(comment, 'advice') warning = warn() if warning: log.warning(warning, 'advice') if env.api.cli: pipename = 'exabgp' if env.api.pipename is None else env.api.pipename pipes = named_pipe(ROOT, pipename) if len(pipes) != 1: env.api.cli = False log.error( 'could not find the named pipes (%s.in and %s.out) required for the cli' % (pipename, pipename), 'cli' ) log.error('we scanned the following folders (the number is your PID):', 'cli') for location in pipes: log.error(' - %s' % location, 'cli control') log.error('please make them in one of the folder with the following commands:', 'cli control') log.error('> mkfifo %s/run/%s.{in,out}' % (os.getcwd(), pipename), 'cli control') log.error('> chmod 600 %s/run/%s.{in,out}' % (os.getcwd(), pipename), 'cli control') if os.getuid() != 0: log.error( '> chown %d:%d %s/run/%s.{in,out}' % (os.getuid(), os.getgid(), os.getcwd(), pipename), 'cli control', ) else: pipe = pipes[0] os.environ['exabgp_cli_pipe'] = pipe os.environ['exabgp_api_pipename'] = pipename log.info('named pipes for the cli are:', 'cli control') log.info('to send commands %s%s.in' % (pipe, pipename), 'cli control') log.info('to read responses %s%s.out' % (pipe, pipename), 'cli control') if not env.profile.enable: exit_code = Reactor(configurations).run(validate, ROOT) __exit(env.debug.memory, exit_code) try: import cProfile as profile except ImportError: import profile if env.profile.file == 'stdout': profiled = 'Reactor(%s).run(%s,"%s")' % (str(configurations), str(validate), str(ROOT)) exit_code = profile.run(profiled) __exit(env.debug.memory, exit_code) if pid: profile_name = "%s-pid-%d" % (env.profile.file, pid) else: profile_name = env.profile.file notice = '' if os.path.isdir(profile_name): notice = 'profile can not use this filename as output, it is not a directory (%s)' % profile_name if os.path.exists(profile_name): notice = 'profile can not use this filename as output, it already exists (%s)' % profile_name if not notice: cwd = os.getcwd() log.debug('profiling ....', 'reactor') profiler = profile.Profile() profiler.enable() try: exit_code = Reactor(configurations).run(validate, ROOT) except Exception: exit_code = Reactor.Exit.unknown raise finally: from exabgp.vendoring import lsprofcalltree profiler.disable() kprofile = lsprofcalltree.KCacheGrind(profiler) try: destination = profile_name if profile_name.startswith('/') else os.path.join(cwd, profile_name) with open(destination, 'w+') as write: kprofile.output(write) except IOError: notice = 'could not save profiling in formation at: ' + destination log.debug("-" * len(notice), 'reactor') log.debug(notice, 'reactor') log.debug("-" * len(notice), 'reactor') __exit(env.debug.memory, exit_code) else: log.debug("-" * len(notice), 'reactor') log.debug(notice, 'reactor') log.debug("-" * len(notice), 'reactor') Reactor(configurations).run(validate, ROOT) __exit(env.debug.memory, 1)
def run(env, comment, configurations, root, validate, pid=0): logger = Logger() logger.info('Thank you for using ExaBGP', source='welcome') logger.info('%s' % version, source='version') logger.info('%s' % sys.version.replace('\n', ' '), source='interpreter') logger.info('%s' % ' '.join(platform.uname()[:5]), source='os') logger.info('%s' % root, source='installation') if comment: logger.info(comment, source='advice') warning = warn() if warning: logger.info(warning, source='advice') if env.api.cli: pipes = named_pipe(root) if len(pipes) != 1: env.api.cli = False logger.error( 'Could not find the named pipes (exabgp.in and exabgp.out) required for the cli', source='cli') logger.error( 'We scanned the following folders (the number is your PID):', source='cli') for location in pipes: logger.error(' - %s' % location, source='cli control') logger.error( 'please make them in one of the folder with the following commands:', source='cli control') logger.error('> mkfifo %s/run/exabgp.{in,out}' % os.getcwd(), source='cli control') logger.error('> chmod 600 %s/run/exabgp.{in,out}' % os.getcwd(), source='cli control') if os.getuid() != 0: logger.error('> chown %d:%d %s/run/exabgp.{in,out}' % (os.getuid(), os.getgid(), os.getcwd()), source='cli control') else: pipe = pipes[0] os.environ['exabgp_cli_pipe'] = pipe logger.info('named pipes for the cli are:', source='cli control') logger.info('to send commands %sexabgp.in' % pipe, source='cli control') logger.info('to read responses %sexabgp.out' % pipe, source='cli control') if not env.profile.enable: was_ok = Reactor(configurations).run(validate, root) __exit(env.debug.memory, 0 if was_ok else 1) try: import cProfile as profile except ImportError: import profile if env.profile.file == 'stdout': profiled = 'Reactor(%s).run(%s,"%s")' % (str(configurations), str(validate), str(root)) was_ok = profile.run(profiled) __exit(env.debug.memory, 0 if was_ok else 1) if pid: profile_name = "%s-pid-%d" % (env.profile.file, pid) else: profile_name = env.profile.file notice = '' if os.path.isdir(profile_name): notice = 'profile can not use this filename as output, it is not a directory (%s)' % profile_name if os.path.exists(profile_name): notice = 'profile can not use this filename as output, it already exists (%s)' % profile_name if not notice: cwd = os.getcwd() logger.reactor('profiling ....') profiler = profile.Profile() profiler.enable() try: was_ok = Reactor(configurations).run(validate, root) except Exception: was_ok = False raise finally: profiler.disable() kprofile = lsprofcalltree.KCacheGrind(profiler) try: destination = profile_name if profile_name.startswith( '/') else os.path.join(cwd, profile_name) with open(destination, 'w+') as write: kprofile.output(write) except IOError: notice = 'could not save profiling in formation at: ' + destination logger.reactor("-" * len(notice)) logger.reactor(notice) logger.reactor("-" * len(notice)) __exit(env.debug.memory, 0 if was_ok else 1) else: logger.reactor("-" * len(notice)) logger.reactor(notice) logger.reactor("-" * len(notice)) Reactor(configurations).run(validate, root) __exit(env.debug.memory, 1)
def exabgp(localip, routerid, asn, peerip, peerport, peeras): from exabgp.reactor.api.command.command import Command from exabgp.reactor.api.command.limit import match_neighbors from exabgp.reactor.api.command.limit import extract_neighbors from exabgp.reactor.loop import Reactor # Extend ExaBGP to handle a "send-raw-data [[neighbor IP] ...] filename" command to cram raw # data down the peers throat as fast as possible (limited by kernel syscall). @Command.register('text', 'send-raw-data') def send_raw_data(self, reactor, service, line): def callback(): try: descriptions, command = extract_neighbors(line) peers = match_neighbors(reactor.peers, descriptions) if not peers: self.log_failure( 'no neighbor matching the command : %s' % command) reactor.processes.answer(service, 'error') yield True return with open(command, "rb") as datafile: rawdata = datafile.read() assert rawdata for peer in peers: log.info("send-raw-data: %d bytes to %s", len(rawdata), str(peer)) peer.proto.connection.writer(rawdata) reactor.processes.answer_done(service) except Exception as ex: self.log_failure('issue with send-raw-data: ' + str(ex)) reactor.processes.answer(service, 'error') yield True reactor.asynchronous.schedule(service, line, callback()) # from exabgp.pplication.bgp import main from exabgp.application.bgp import __exit from exabgp.debug import setup_report setup_report() from exabgp.configuration.setup import environment env = environment.setup("/nofile") with tempfile.NamedTemporaryFile(mode='w') as scriptfile: scriptfile.write("""#!/bin/bash while read nchange; do echo $nchange >> /tmp/bgp-script-out.txt if [[ $(echo $nchange | sed '/neighbor {} up/!d') ]]; then echo send-raw-data foobar.raw fi done """.format(peerip)) scriptfile.flush() os.system("chmod 755 " + scriptfile.name) with tempfile.NamedTemporaryFile(mode='w') as conffile: conffile.write(""" process senddata {{ run bash {}; encoder text; }} neighbor {} {{ # Remote neighbor to peer with router-id {}; # Our local router-id local-address {}; # Our local update-source local-as {}; # Our local AS peer-as {}; # Peer's AS api {{ processes [senddata]; neighbor-changes; }} }} """.format(scriptfile.name, peerip, routerid, localip, asn, peeras)) conffile.flush() root = os.getcwd() exit_code = Reactor([conffile.name]).run(False, root) __exit(env.debug.memory, exit_code)
def run(env, comment, configurations, validate, pid=0): logger = Logger() logger.error('', source='ExaBGP') logger.error('%s' % version, source='version') logger.error('%s' % sys.version.replace('\n', ' '), source='interpreter') logger.error('%s' % ' '.join(platform.uname()[:5]), source='os') logger.error('', source='ExaBGP') if comment: logger.configuration(comment) warning = warn() if warning: logger.configuration(warning) if not env.profile.enable: ok = Reactor(configurations).run(validate) __exit(env.debug.memory, 0 if ok else 1) try: import cProfile as profile except ImportError: import profile if not env.profile.file or env.profile.file == 'stdout': ok = profile.run('Reactor(configurations).run(validate)') __exit(env.debug.memory, 0 if ok else 1) if pid: profile_name = "%s-pid-%d" % (env.profile.file, pid) else: profile_name = env.profile.file notice = '' if os.path.isdir(profile_name): notice = 'profile can not use this filename as output, it is not a directory (%s)' % profile_name if os.path.exists(profile_name): notice = 'profile can not use this filename as output, it already exists (%s)' % profile_name if not notice: logger.reactor('profiling ....') profiler = profile.Profile() profiler.enable() try: ok = Reactor(configurations).run() except Exception: raise finally: profiler.disable() kprofile = lsprofcalltree.KCacheGrind(profiler) with open(profile_name, 'w+') as write: kprofile.output(write) __exit(env.debug.memory, 0 if ok else 1) else: logger.reactor("-" * len(notice)) logger.reactor(notice) logger.reactor("-" * len(notice)) Reactor(configurations).run() __exit(env.debug.memory, 1)