def parse_api_attribute (self,command,peers,action): # This is a quick solution which does not support next-hop self attribute,nlris = command.split('nlri') route = '%s route 0.0.0.0/0 %s' % (action, ' '.join(attribute.split()[2:])) parsed = self.parse_api_route(route,peers,action) if parsed in (True,False,None): return parsed attributes = parsed[0][1].attributes nexthop = parsed[0][1].nlri.nexthop changes = [] for nlri in nlris.split(): ip,mask = nlri.split('/') klass = Prefix if 'path-information' in command else MPLS change = Change( klass( afi=IP.toafi(ip), safi=IP.tosafi(ip), packed=IP.pton(ip), mask=int(mask), nexthop=nexthop.packed, action=action ) ,attributes ) if action == 'withdraw': change.nlri.action = OUT.withdraw else: change.nlri.action = OUT.announce changes.append((peers.keys(),change)) return changes
def api_attribute (self, command, peers, action): # This is a quick solution which does not support next-hop self attribute,nlris = command.split('nlri') route = '%s route 0.0.0.0/0 %s' % (action, ' '.join(attribute.split()[2:])) parsed = self.api_route(peers,route) if parsed in (True,False,None): return parsed attributes = parsed[0][1].attributes nexthop = parsed[0][1].nlri.nexthop changes = [] for nlri in nlris.split(): ip,mask = nlri.split('/') klass = MPLS if 'path-information' in command else INET change = Change( klass( afi=IP.toafi(ip), safi=IP.tosafi(ip), packed=IP.pton(ip), mask=int(mask), nexthop='', # could be NextHopSelf action=action ), attributes ) change.nlri.nexthop = nexthop if action == 'withdraw': change.nlri.action = OUT.WITHDRAW else: change.nlri.action = OUT.ANNOUNCE changes.append((peers.keys(),change)) return changes
def insert_static_route (self, scope, name, command, tokens): try: ip = tokens.pop(0) except IndexError: return self.error.set(self.syntax) try: ip,mask = ip.split('/') mask = int(mask) except ValueError: mask = 32 try: if 'rd' in tokens: klass = MPLS elif 'route-distinguisher' in tokens: klass = MPLS elif 'label' in tokens: klass = MPLS else: klass = INET # nexthop must be false and its str return nothing .. an empty string does that update = Change(klass(afi=IP.toafi(ip),safi=IP.tosafi(ip),packed=IP.pton(ip),mask=mask,nexthop=None,action=OUT.ANNOUNCE),Attributes()) except ValueError: return self.error.set(self.syntax) if 'announce' not in scope[-1]: scope[-1]['announce'] = [] scope[-1]['announce'].append(update) return True
def parse_api_attribute(self, command, peers, action): # This is a quick solution which does not support next-hop self attribute, nlris = command.split('nlri') route = '%s route 0.0.0.0/0 %s' % (action, ' '.join( attribute.split()[2:])) parsed = self.parse_api_route(route, peers, action) if parsed in (True, False, None): return parsed attributes = parsed[0][1].attributes nexthop = parsed[0][1].nlri.nexthop changes = [] for nlri in nlris.split(): ip, mask = nlri.split('/') klass = Prefix if 'path-information' in command else MPLS change = Change( klass(afi=IP.toafi(ip), safi=IP.tosafi(ip), packed=IP.pton(ip), mask=int(mask), nexthop=nexthop.packed, action=action), attributes) if action == 'withdraw': change.nlri.action = OUT.withdraw else: change.nlri.action = OUT.announce changes.append((peers.keys(), change)) return changes
def inet(tokeniser): ipmask = prefix(tokeniser) inet = INET(afi=IP.toafi(ipmask.top()), safi=IP.tosafi(ipmask.top()), action=OUT.UNSET) inet.cidr = CIDR(ipmask.ton(), ipmask.mask) return Change(inet, Attributes())
def mpls(tokeniser): ipmask = prefix(tokeniser) mpls = IPVPN(afi=IP.toafi(ipmask.top()), safi=IP.tosafi(ipmask.top()), action=OUT.ANNOUNCE) mpls.cidr = CIDR(ipmask.ton(), ipmask.mask) return Change(mpls, Attributes())
def attributes(tokeniser): ipmask = prefix(lambda: tokeniser.tokens[-1]) if 'rd' in tokeniser.tokens or 'route-distinguisher' in tokeniser.tokens: nlri = IPVPN(IP.toafi(ipmask.top()), SAFI.mpls_vpn, OUT.ANNOUNCE) elif 'label' in tokeniser.tokens: nlri = Labelled(IP.toafi(ipmask.top()), SAFI.nlri_mpls, OUT.ANNOUNCE) else: nlri = INET(IP.toafi(ipmask.top()), IP.tosafi(ipmask.top()), OUT.ANNOUNCE) nlri.cidr = CIDR(ipmask.pack(), ipmask.mask) change = Change(nlri, Attributes()) while True: command = tokeniser() if not command: return [] if command == 'nlri': break action = ParseStatic.action[command] if action == 'attribute-add': change.attributes.add(ParseStatic.known[command](tokeniser)) elif action == 'nlri-set': change.nlri.assign(ParseStatic.assign[command], ParseStatic.known[command](tokeniser)) elif action == 'nexthop-and-attribute': nexthop, attribute = ParseStatic.known[command](tokeniser) change.nlri.nexthop = nexthop change.attributes.add(attribute) else: raise ValueError('route: unknown command "%s"' % command) attributes = change.attributes nexthop = change.nlri.nexthop changes = [] while True: nlri = tokeniser.peek() if not nlri: break ipmask = prefix(tokeniser) new = Change( change.nlri.__class__(change.nlri.afi, change.nlri.safi, OUT.UNSET), attributes) new.nlri.cidr = CIDR(ipmask.pack(), ipmask.mask) new.nlri.nexthop = nexthop changes.append(new) return changes
def route (tokeniser): action = OUT.ANNOUNCE if tokeniser.announce else OUT.WITHDRAW ipmask = prefix(tokeniser) check = lambda change,afi: True if 'rd' in tokeniser.tokens or 'route-distinguisher' in tokeniser.tokens: nlri = IPVPN(IP.toafi(ipmask.top()),SAFI.mpls_vpn,action) check = AnnounceVPN.check elif 'label' in tokeniser.tokens: nlri = Label(IP.toafi(ipmask.top()),SAFI.nlri_mpls,action) check = AnnounceLabel.check else: nlri = INET(IP.toafi(ipmask.top()), IP.tosafi(ipmask.top()), action) check = AnnouncePath.check nlri.cidr = CIDR(ipmask.pack(),ipmask.mask) change = Change( nlri, Attributes() ) while True: command = tokeniser() if not command: break if command == 'label': nlri.labels = label(tokeniser) continue if command == 'rd' or command == 'route-distinguisher': nlri.rd = route_distinguisher(tokeniser) continue action = ParseStatic.action.get(command,'') if action == 'attribute-add': change.attributes.add(ParseStatic.known[command](tokeniser)) elif action == 'nlri-set': change.nlri.assign(ParseStatic.assign[command],ParseStatic.known[command](tokeniser)) elif action == 'nexthop-and-attribute': nexthop,attribute = ParseStatic.known[command](tokeniser) change.nlri.nexthop = nexthop change.attributes.add(attribute) else: raise ValueError('unknown command "%s"' % command) if not check(change,nlri.afi): raise ValueError('invalid route (missing next-hop, label or rd ?)') return list(ParseStatic.split(change))
def inet (tokeniser): ipmask = prefix(tokeniser) inet = INET( afi=IP.toafi(ipmask.top()), safi=IP.tosafi(ipmask.top()), action=OUT.UNSET ) inet.cidr = CIDR(ipmask.ton(),ipmask.mask) return Change( inet, Attributes() )
def mpls (tokeniser): ipmask = prefix(tokeniser) mpls = IPVPN( afi=IP.toafi(ipmask.top()), safi=IP.tosafi(ipmask.top()), action=OUT.UNSET ) mpls.cidr = CIDR(ipmask.ton(),ipmask.mask) return Change( mpls, Attributes() )
def inet (tokeniser): ipmask = prefix(tokeniser) return Change( INET( afi=IP.toafi(ipmask.string), safi=IP.tosafi(ipmask.string), packed=IP.pton(ipmask.string), mask=ipmask.mask, nexthop=None, action=OUT.UNSET ), Attributes() )
def route (tokeniser): ipmask = prefix(tokeniser) if 'rd' in tokeniser.tokens or 'route-distinguisher' in tokeniser.tokens: klass = MPLS safi = SAFI(SAFI.mpls_vpn) elif 'label' in tokeniser.tokens: # XXX: should we create a LABEL class ? klass = MPLS safi = SAFI(SAFI.nlri_mpls) else: klass = INET safi = IP.tosafi(ipmask.string) change = Change( klass( IP.toafi(ipmask.string), safi, ipmask.pack(), ipmask.mask, '', OUT.UNSET ), Attributes() ) while True: command = tokeniser() if not command: break action = ParseStatic.action[command] if action == 'attribute-add': change.attributes.add(ParseStatic.known[command](tokeniser)) elif action == 'nlri-set': change.nlri.assign(ParseStatic.assign[command],ParseStatic.known[command](tokeniser)) elif action == 'nexthop-and-attribute': nexthop,attribute = ParseStatic.known[command](tokeniser) change.nlri.nexthop = nexthop change.attributes.add(attribute) else: raise ValueError('route: unknown command "%s"' % command) return list(ParseStatic.split(change))
def route (tokeniser): ipmask = prefix(tokeniser) if 'rd' in tokeniser.tokens or 'route-distinguisher' in tokeniser.tokens: nlri = IPVPN(IP.toafi(ipmask.top()),SAFI.mpls_vpn,OUT.ANNOUNCE) elif 'label' in tokeniser.tokens: nlri = Label(IP.toafi(ipmask.top()),SAFI.nlri_mpls,OUT.ANNOUNCE) else: nlri = INET(IP.toafi(ipmask.top()),IP.tosafi(ipmask.top()),OUT.ANNOUNCE) nlri.cidr = CIDR(ipmask.pack(),ipmask.mask) change = Change( nlri, Attributes() ) while True: command = tokeniser() if not command: break if command == 'label': nlri.labels = label(tokeniser) continue if command == 'rd' or command == 'route-distinguisher': nlri.rd = route_distinguisher(tokeniser) continue action = ParseStatic.action.get(command,'') if action == 'attribute-add': change.attributes.add(ParseStatic.known[command](tokeniser)) elif action == 'nlri-set': change.nlri.assign(ParseStatic.assign[command],ParseStatic.known[command](tokeniser)) elif action == 'nexthop-and-attribute': nexthop,attribute = ParseStatic.known[command](tokeniser) change.nlri.nexthop = nexthop change.attributes.add(attribute) else: raise ValueError('route: unknown command "%s"' % command) return list(ParseStatic.split(change))
def route(tokeniser): ipmask = prefix(tokeniser) if 'rd' in tokeniser.tokens or 'route-distinguisher' in tokeniser.tokens: nlri = IPVPN(IP.toafi(ipmask.top()), SAFI.mpls_vpn, OUT.ANNOUNCE) elif 'label' in tokeniser.tokens: nlri = Label(IP.toafi(ipmask.top()), SAFI.nlri_mpls, OUT.ANNOUNCE) else: nlri = INET(IP.toafi(ipmask.top()), IP.tosafi(ipmask.top()), OUT.ANNOUNCE) nlri.cidr = CIDR(ipmask.pack(), ipmask.mask) change = Change(nlri, Attributes()) while True: command = tokeniser() if not command: break if command == 'label': nlri.labels = label(tokeniser) continue if command == 'rd' or command == 'route-distinguisher': nlri.rd = route_distinguisher(tokeniser) continue action = ParseStatic.action.get(command, '') if action == 'attribute-add': change.attributes.add(ParseStatic.known[command](tokeniser)) elif action == 'nlri-set': change.nlri.assign(ParseStatic.assign[command], ParseStatic.known[command](tokeniser)) elif action == 'nexthop-and-attribute': nexthop, attribute = ParseStatic.known[command](tokeniser) change.nlri.nexthop = nexthop change.attributes.add(attribute) else: raise ValueError('route: unknown command "%s"' % command) return list(ParseStatic.split(change))
def insert_static_route(self, scope, name, command, tokens): try: ip = tokens.pop(0) except IndexError: return self.error.set(self.syntax) try: ip, mask = ip.split('/') mask = int(mask) except ValueError: mask = 32 try: if 'rd' in tokens: klass = MPLS elif 'route-distinguisher' in tokens: klass = MPLS elif 'label' in tokens: klass = MPLS else: klass = INET # nexthop must be false and its str return nothing .. an empty string does that update = Change( klass(afi=IP.toafi(ip), safi=IP.tosafi(ip), packed=IP.pton(ip), mask=mask, nexthop=None, action=OUT.ANNOUNCE), Attributes()) except ValueError: return self.error.set(self.syntax) if 'announce' not in scope[-1]: scope[-1]['announce'] = [] scope[-1]['announce'].append(update) return True
def attributes (tokeniser): ipmask = prefix(lambda: tokeniser.tokens[-1]) if 'rd' in tokeniser.tokens or 'route-distinguisher' in tokeniser.tokens: nlri = MPLS(IP.toafi(ipmask.top()),SAFI.mpls_vpn,OUT.ANNOUNCE) elif 'label' in tokeniser.tokens: nlri = Label(IP.toafi(ipmask.top()),SAFI.nlri_mpls,OUT.ANNOUNCE) else: nlri = INET(IP.toafi(ipmask.top()),IP.tosafi(ipmask.top()),OUT.ANNOUNCE) nlri.cidr = CIDR(ipmask.pack(),ipmask.mask) change = Change( nlri, Attributes() ) while True: command = tokeniser() if not command: return [] if command == 'nlri': break action = ParseStatic.action[command] if action == 'attribute-add': change.attributes.add(ParseStatic.known[command](tokeniser)) elif action == 'nlri-set': change.nlri.assign(ParseStatic.assign[command],ParseStatic.known[command](tokeniser)) elif action == 'nexthop-and-attribute': nexthop,attribute = ParseStatic.known[command](tokeniser) change.nlri.nexthop = nexthop change.attributes.add(attribute) else: raise ValueError('route: unknown command "%s"' % command) attributes = change.attributes nexthop = change.nlri.nexthop changes = [] while True: nlri = tokeniser.peek() if not nlri: break ipmask = prefix(tokeniser) new = Change( change.nlri.__class__( change.nlri.afi, change.nlri.safi, OUT.UNSET ), attributes ) new.nlri.cidr = CIDR(ipmask.pack(),ipmask.mask) new.nlri.nexthop = nexthop changes.append(new) return changes
def attributes (tokeniser): action = OUT.ANNOUNCE if tokeniser.announce else OUT.WITHDRAW ipmask = prefix(lambda: tokeniser.tokens[-1]) tokeniser.afi = ipmask.afi if 'rd' in tokeniser.tokens or 'route-distinguisher' in tokeniser.tokens: nlri = IPVPN(IP.toafi(ipmask.top()), SAFI.mpls_vpn, action) elif 'label' in tokeniser.tokens: nlri = Label(IP.toafi(ipmask.top()), SAFI.nlri_mpls, action) else: nlri = INET(IP.toafi(ipmask.top()), IP.tosafi(ipmask.top()), action) nlri.cidr = CIDR(ipmask.pack(),ipmask.mask) attr = Attributes() labels = None rd = None while True: command = tokeniser() if not command: return [] if command == 'nlri': break if command == 'label': labels = label(tokeniser) continue if command == 'rd' or command == 'route-distinguisher': rd = route_distinguisher(tokeniser) continue action = ParseStatic.action[command] if action == 'attribute-add': attr.add(ParseStatic.known[command](tokeniser)) elif action == 'nlri-set': nlri.assign(ParseStatic.assign[command],ParseStatic.known[command](tokeniser)) elif action == 'nexthop-and-attribute': nexthop,attribute = ParseStatic.known[command](tokeniser) nlri.nexthop = nexthop attr.add(attribute) else: raise ValueError('unknown command "%s"' % command) changes = [] while True: peeked_nlri = tokeniser.peek() if not peeked_nlri: break ipmask = prefix(tokeniser) new = Change( nlri.__class__( nlri.afi, nlri.safi, OUT.UNSET ), attr ) new.nlri.cidr = CIDR(ipmask.pack(),ipmask.mask) if labels: new.nlri.labels = labels if rd: new.nlri.rd = rd new.nlri.nexthop = nlri.nexthop changes.append(new) return changes
def attributes (tokeniser): ipmask = prefix(lambda: tokeniser.tokens[-1]) if 'rd' in tokeniser.tokens or 'route-distinguisher' in tokeniser.tokens: nlri = IPVPN(IP.toafi(ipmask.top()),SAFI.mpls_vpn,OUT.ANNOUNCE) elif 'label' in tokeniser.tokens: nlri = Label(IP.toafi(ipmask.top()),SAFI.nlri_mpls,OUT.ANNOUNCE) else: nlri = INET(IP.toafi(ipmask.top()),IP.tosafi(ipmask.top()),OUT.ANNOUNCE) nlri.cidr = CIDR(ipmask.pack(),ipmask.mask) attr = Attributes() labels = None rd = None while True: command = tokeniser() if not command: return [] if command == 'nlri': break if command == 'label': labels = label(tokeniser) continue if command == 'rd' or command == 'route-distinguisher': rd = route_distinguisher(tokeniser) continue action = ParseStatic.action[command] if action == 'attribute-add': attr.add(ParseStatic.known[command](tokeniser)) elif action == 'nlri-set': nlri.assign(ParseStatic.assign[command],ParseStatic.known[command](tokeniser)) elif action == 'nexthop-and-attribute': nexthop,attribute = ParseStatic.known[command](tokeniser) nlri.nexthop = nexthop attr.add(attribute) else: raise ValueError('route: unknown command "%s"' % command) changes = [] while True: peeked_nlri = tokeniser.peek() if not peeked_nlri: break ipmask = prefix(tokeniser) new = Change( nlri.__class__( nlri.afi, nlri.safi, OUT.UNSET ), attr ) new.nlri.cidr = CIDR(ipmask.pack(),ipmask.mask) if labels: new.nlri.labels = labels if rd: new.nlri.rd = rd new.nlri.nexthop = nlri.nexthop changes.append(new) return changes