def api_vpls(self, command, peers, action): tokens = formated(command).split(' ')[1:] if len(tokens) < 4: return False if tokens[0] != 'vpls': return False changes = [] if 'self' in command: for peer, nexthop in peers.iteritems(): scope = [{}] self._nexthopself = nexthop if not self.l2vpn.vpls(scope, 'l2vpn', 'vpls', tokens[1:]): self._nexthopself = None return False for change in scope[0]['announce']: changes.append((peer, change)) self._nexthopself = None else: scope = [{}] if not self.l2vpn.vpls(scope, 'l2vpn', 'vpls', tokens[1:]): return False for peer in peers: for change in scope[0]['announce']: changes.append((peer, change)) if action == 'withdraw': for (peer, change) in changes: change.nlri.action = OUT.WITHDRAW return changes
def api_vpls (self, command, peers, action): tokens = formated(command).split(' ')[1:] if len(tokens) < 4: return False if tokens[0] != 'vpls': return False changes = [] if 'self' in command: for peer,nexthop in peers.iteritems(): scope = [{}] self._nexthopself = nexthop if not self.l2vpn.vpls(scope,'l2vpn','vpls',tokens[1:]): self._nexthopself = None return False for change in scope[0]['announce']: changes.append((peer,change)) self._nexthopself = None else: scope = [{}] if not self.l2vpn.vpls(scope,'l2vpn','vpls',tokens[1:]): return False for peer in peers: for change in scope[0]['announce']: changes.append((peer,change)) if action == 'withdraw': for (peer,change) in changes: change.nlri.action = OUT.WITHDRAW return changes
def api_refresh (self, command): tokens = formated(command).split(' ')[2:] if len(tokens) != 2: return False afi = AFI.value(tokens.pop(0)) safi = SAFI.value(tokens.pop(0)) if afi is None or safi is None: return False return RouteRefresh(afi,safi)
def api_refresh(self, command): tokens = formated(command).split(' ')[2:] if len(tokens) != 2: return False afi = AFI.value(tokens.pop(0)) safi = SAFI.value(tokens.pop(0)) if afi is None or safi is None: return False return RouteRefresh(afi, safi)
def api_flow (self, command, action): tokens = formated(command).split(' ',2)[2].replace('\\n','\n').replace('{','{\n').replace('}','}\n').replace(';',';\n').replace('\n\n','\n') self.tokens.set_text(tokens) scope = [{}] if not self._dispatch(scope,'root','flow',['route',],[],['root']): return False if not self.flow.check_flow(scope,self): return False changes = scope[0]['announce'] if action == 'withdraw': for change in changes: change.nlri.action = OUT.WITHDRAW return changes
def api_operational (self, command): tokens = formated(command).split(' ',3) if len(tokens) != 4: return False operational = tokens[1].lower() what = tokens[2].lower() if operational != 'operational': return False # None or a class return self.operational.operational(what,tokens[3])
def received(self): consumed_data = False for process in list(self._process): try: proc = self._process[process] # proc.poll returns None if the process is still fine # -[signal], like -15, if the process was terminated if proc.poll() is not None and self.reactor.respawn: raise ValueError('child died') r, _, _ = select.select([ proc.stdout, ], [], [], 0) if r: try: while True: # Calling next() on Linux and OSX works perfectly well # but not on OpenBSD where it always raise StopIteration # and only readline() works raw = proc.stdout.readline() line = raw.rstrip() consumed_data = True self.logger.processes( "Command from process %s : %s " % (process, line)) if raw == '': raise IOError('Child process died') yield (process, formated(line)) except IOError, exc: if not exc.errno or exc.errno in error.fatal: # if the program exists we can get an IOError with errno code zero ! self.logger.processes( "Issue with the process, terminating it and restarting it" ) self._terminate(process) self._start(process) elif exc.errno in error.block: # we often see errno.EINTR: call interrupted and # we most likely have data, we will try to read them a the next loop iteration pass else: self.logger.processes( "unexpected errno received from forked process (%s)" % errstr(exc)) except StopIteration: if not consumed_data: self.logger.processes( "The process died, trying to respawn it") self._terminate(process) self._start(process)
def api_operational(self, command): tokens = formated(command).split(' ', 3) if len(tokens) != 4: return False operational = tokens[1].lower() what = tokens[2].lower() if operational != 'operational': return False # None or a class return self.operational.operational(what, tokens[3])
def api_flow(self, command, action): tokens = formated(command).split(' ', 2)[2].replace( '\\n', '\n').replace('{', '{\n').replace('}', '}\n').replace( ';', ';\n').replace('\n\n', '\n') self.tokens.set_text(tokens) scope = [{}] if not self._dispatch(scope, 'root', 'flow', [ 'route', ], [], ['root']): return False if not self.flow.check_flow(scope, self): return False changes = scope[0]['announce'] if action == 'withdraw': for change in changes: change.nlri.action = OUT.WITHDRAW return changes
def api_eor (self, command): tokens = formated(command).split(' ')[2:] number = len(tokens) if not number: return Family(1,1) if number != 2: return False afi = AFI.fromString(tokens[0]) if afi == AFI.undefined: return False safi = SAFI.fromString(tokens[1]) if safi == SAFI.undefined: return False return Family(afi,safi)
def api_eor(self, command): tokens = formated(command).split(' ')[2:] number = len(tokens) if not number: return Family(1, 1) if number != 2: return False afi = AFI.fromString(tokens[0]) if afi == AFI.undefined: return False safi = SAFI.fromString(tokens[1]) if safi == SAFI.undefined: return False return Family(afi, safi)
def _tokenise(self, iterator): for line in iterator: replaced = formated(line) if not replaced: continue if replaced.startswith('#'): continue command = replaced[:3] if command in ('md5', 'asm'): string = line.strip()[3:].strip() if string[-1] == ';': string = string[:-1] yield [command, string, ';'] elif replaced[:3] == 'run': yield [t for t in replaced[:-1].split(' ', 1) if t ] + [replaced[-1]] else: yield [t.lower() for t in replaced[:-1].split(' ') if t ] + [replaced[-1]]
def received (self): consumed_data = False for process in list(self._process): try: proc = self._process[process] # proc.poll returns None if the process is still fine # -[signal], like -15, if the process was terminated if proc.poll() is not None and self.reactor.respawn: raise ValueError('child died') r,_,_ = select.select([proc.stdout,],[],[],0) if r: try: while True: # Calling next() on Linux and OSX works perfectly well # but not on OpenBSD where it always raise StopIteration # and only readline() works raw = proc.stdout.readline() line = raw.rstrip() consumed_data = True self.logger.processes("Command from process %s : %s " % (process,line)) if raw == '': raise IOError('Child process died') yield (process,formated(line)) except IOError,exc: if not exc.errno or exc.errno in error.fatal: # if the program exists we can get an IOError with errno code zero ! self.logger.processes("Issue with the process, terminating it and restarting it") self._terminate(process) self._start(process) elif exc.errno in error.block: # we often see errno.EINTR: call interrupted and # we most likely have data, we will try to read them a the next loop iteration pass else: self.logger.processes("unexpected errno received from forked process (%s)" % errstr(exc)) except StopIteration: if not consumed_data: self.logger.processes("The process died, trying to respawn it") self._terminate(process) self._start(process)
def api_route(self, command, peers, action): tokens = formated(command).split(' ')[1:] number = len(tokens) if number < 1: return False message = tokens[0] if message not in ('route', ): return False if number == 2 and action == 'withdraw' and 'next-hop' not in tokens: tokens.extend(['next-hop', '0.0.0.0']) changes = [] if 'self' in command: for peer, nexthop in peers.iteritems(): scope = [{}] self.route.nexthop(nexthop) if not self.route.static(scope, 'static', 'route', tokens[1:]): self.route.clear() return False for change in scope[0]['announce']: changes.append((peer, change)) self.route.clear() else: scope = [{}] if not self.route.static(scope, 'static', 'route', tokens[1:]): return False for peer in peers: for change in scope[0]['announce']: changes.append((peer, change)) if action == 'withdraw': for (peer, change) in changes: change.nlri.action = OUT.WITHDRAW return changes
def api_route (self, command, peers, action): tokens = formated(command).split(' ')[1:] number = len(tokens) if number < 1: return False message = tokens[0] if message not in ('route',): return False if number == 2 and action == 'withdraw' and 'next-hop' not in tokens: tokens.extend(['next-hop','0.0.0.0']) changes = [] if 'self' in command: for peer,nexthop in peers.iteritems(): scope = [{}] self.route.nexthop(nexthop) if not self.route.static(scope,'static','route',tokens[1:]): self.route.clear() return False for change in scope[0]['announce']: changes.append((peer,change)) self.route.clear() else: scope = [{}] if not self.route.static(scope,'static','route',tokens[1:]): return False for peer in peers: for change in scope[0]['announce']: changes.append((peer,change)) if action == 'withdraw': for (peer,change) in changes: change.nlri.action = OUT.WITHDRAW return changes
def _operational(self, klass, parameters, tokens): def utf8(string): return string.encode('utf-8')[1:-1] convert = { 'afi': AFI.value, 'safi': SAFI.value, 'sequence': int, 'counter': long, 'advisory': utf8 } def valid(_): return True def u32(_): return int(_) <= 0xFFFFFFFF def u64(_): return long(_) <= 0xFFFFFFFFFFFFFFFF def advisory(_): return len(_.encode('utf-8')) <= MAX_ADVISORY + 2 # the two quotes validate = { 'afi': AFI.value, 'safi': SAFI.value, 'sequence': u32, 'counter': u64, } number = len(parameters) * 2 tokens = formated(tokens).split(' ', number - 1) if len(tokens) != number: return self.error.set( 'invalid operational syntax, wrong number of arguments') data = {} while tokens and parameters: command = tokens.pop(0).lower() value = tokens.pop(0) if command == 'router-id': if isipv4(value): data['routerid'] = RouterID(value) else: self.error.set('invalid operational value for %s' % command) return None continue expected = parameters.pop(0) if command != expected: self.error.set( 'invalid operational syntax, unknown argument %s' % command) return None if not validate.get(command, valid)(value): self.error.set('invalid operational value for %s' % command) return None data[command] = convert[command](value) if tokens or parameters: self.error.set('invalid advisory syntax, missing argument(s) %s' % ', '.join(parameters)) return None if 'routerid' not in data: data['routerid'] = None return klass(**data)
def _operational (self, klass, parameters, tokens): def utf8 (string): return string.encode('utf-8')[1:-1] convert = { 'afi': AFI.value, 'safi': SAFI.value, 'sequence': int, 'counter': long, 'advisory': utf8 } def valid (_): return True def u32 (_): return int(_) <= 0xFFFFFFFF def u64 (_): return long(_) <= 0xFFFFFFFFFFFFFFFF def advisory (_): return len(_.encode('utf-8')) <= MAX_ADVISORY + 2 # the two quotes validate = { 'afi': AFI.value, 'safi': SAFI.value, 'sequence': u32, 'counter': u64, } number = len(parameters)*2 tokens = formated(tokens).split(' ',number-1) if len(tokens) != number: return self.error.set('invalid operational syntax, wrong number of arguments') data = {} while tokens and parameters: command = tokens.pop(0).lower() value = tokens.pop(0) if command == 'router-id': if isipv4(value): data['routerid'] = RouterID(value) else: self.error.set('invalid operational value for %s' % command) return None continue expected = parameters.pop(0) if command != expected: self.error.set('invalid operational syntax, unknown argument %s' % command) return None if not validate.get(command,valid)(value): self.error.set('invalid operational value for %s' % command) return None data[command] = convert[command](value) if tokens or parameters: self.error.set('invalid advisory syntax, missing argument(s) %s' % ', '.join(parameters)) return None if 'routerid' not in data: data['routerid'] = None return klass(**data)