diff options
Diffstat (limited to 'test/scenario_test/lib')
-rw-r--r-- | test/scenario_test/lib/base.py | 23 | ||||
-rw-r--r-- | test/scenario_test/lib/exabgp.py | 18 | ||||
-rw-r--r-- | test/scenario_test/lib/gobgp.py | 96 | ||||
-rw-r--r-- | test/scenario_test/lib/quagga.py | 27 |
4 files changed, 139 insertions, 25 deletions
diff --git a/test/scenario_test/lib/base.py b/test/scenario_test/lib/base.py index 778f3ce4..5767fd17 100644 --- a/test/scenario_test/lib/base.py +++ b/test/scenario_test/lib/base.py @@ -36,6 +36,7 @@ BGP_ATTR_TYPE_AS_PATH = 2 BGP_ATTR_TYPE_NEXT_HOP = 3 BGP_ATTR_TYPE_MULTI_EXIT_DISC = 4 BGP_ATTR_TYPE_LOCAL_PREF = 5 +BGP_ATTR_TYPE_COMMUNITIES = 8 BGP_ATTR_TYPE_MP_REACH_NLRI = 14 BGP_ATTR_TYPE_EXTENDED_COMMUNITIES = 16 @@ -158,7 +159,13 @@ class Container(object): for sv in self.shared_volumes: c << "-v {0}:{1}".format(sv[0], sv[1]) c << "--name {0} -id {1}".format(self.docker_name(), self.image) - self.id = local(str(c), capture=True) + for i in range(3): + try: + self.id = local(str(c), capture=True) + except: + time.sleep(1) + else: + break self.is_running = True self.local("ip li set up dev lo") return 0 @@ -216,7 +223,7 @@ class BGPContainer(Container): super(BGPContainer, self).run() return self.WAIT_FOR_BOOT - def add_peer(self, peer, passwd='', evpn=False, is_rs_client=False, + def add_peer(self, peer, passwd=None, evpn=False, is_rs_client=False, policies=None, passive=False, is_rr_client=False, cluster_id='', flowspec=False): @@ -231,7 +238,7 @@ class BGPContainer(Container): raise Exception('peer {0} seems not ip reachable'.format(peer)) if not policies: - policies = [] + policies = {} self.peers[peer] = {'neigh_addr': neigh_addr, 'passwd': passwd, @@ -259,10 +266,16 @@ class BGPContainer(Container): def enable_peer(self, peer): raise Exception('implement enable_peer() method') - def add_route(self, route, rf='ipv4', attribute=None, matchs=None, thens=None): + def add_route(self, route, rf='ipv4', attribute=None, aspath=None, + community=None, med=None, extendedcommunity=None, + matchs=None, thens=None): self.routes[route] = {'prefix': route, 'rf': rf, 'attr': attribute, + 'as-path': aspath, + 'community': community, + 'med': med, + 'extended-community': extendedcommunity, 'matchs': matchs, 'thens' : thens} if self.is_running: @@ -272,7 +285,7 @@ class BGPContainer(Container): def add_policy(self, policy, peer=None): self.policies[policy['name']] = policy if peer in self.peers: - self.peers[peer]['policies'].append(policy) + self.peers[peer]['policies'][policy['name']] = policy if self.is_running: self.create_config() self.reload_config() diff --git a/test/scenario_test/lib/exabgp.py b/test/scenario_test/lib/exabgp.py index 9d211342..f5cdd313 100644 --- a/test/scenario_test/lib/exabgp.py +++ b/test/scenario_test/lib/exabgp.py @@ -76,15 +76,25 @@ class ExaBGPContainer(BGPContainer): cmd << ' local-as {0};'.format(self.asn) cmd << ' peer-as {0};'.format(peer.asn) - routes = [r for r in self.routes.values() if r['rf'] == 'ipv4'] + routes = [r for r in self.routes.values() if r['rf'] == 'ipv4' or r['rf'] == 'ipv6'] if len(routes) > 0: cmd << ' static {' for route in routes: + r = CmdBuffer(' ') + r << ' route {0} next-hop {1}'.format(route['prefix'], local_addr) + if route['as-path']: + r << 'as-path [{0}]'.format(' '.join(str(i) for i in route['as-path'])) + if route['community']: + r << 'community [{0}]'.format(' '.join(c for c in route['community'])) + if route['med']: + r << 'med {0}'.format(route['med']) + if route['extended-community']: + r << 'extended-community [{0}]'.format(route['extended-community']) if route['attr']: - cmd << ' route {0} next-hop {1};'.format(route['prefix'], local_addr) - else: - cmd << ' route {0} next-hop {1} attribute {2};'.format(route['prefix'], local_addr, attr) + r << 'attribute {0}'.format(route['attr']) + + cmd << '{0};'.format(str(r)) cmd << ' }' routes = [r for r in self.routes.values() if r['rf'] == 'ipv4-flowspec'] diff --git a/test/scenario_test/lib/gobgp.py b/test/scenario_test/lib/gobgp.py index 63f65928..aed7f16d 100644 --- a/test/scenario_test/lib/gobgp.py +++ b/test/scenario_test/lib/gobgp.py @@ -21,8 +21,6 @@ from itertools import chain class GoBGPContainer(BGPContainer): - PEER_TYPE_INTERNAL = 0 - PEER_TYPE_EXTERNAL = 1 SHARED_VOLUME = '/root/shared_volume' def __init__(self, name, asn, router_id, ctn_image_name='gobgp', @@ -31,6 +29,10 @@ class GoBGPContainer(BGPContainer): ctn_image_name) self.shared_volumes.append((self.config_dir, self.SHARED_VOLUME)) self.log_level = log_level + self.prefix_set = None + self.neighbor_set = None + self.bgp_set = None + self.default_policy = None def _start_gobgp(self): c = CmdBuffer() @@ -75,11 +77,17 @@ class GoBGPContainer(BGPContainer): def enable_peer(self, peer): self._trigger_peer_cmd('enable', peer) - def get_local_rib(self, peer, rf='ipv4'): + def reset(self, peer): + self._trigger_peer_cmd('reset', peer) + + def softreset(self, peer, rf='ipv4', type='in'): + self._trigger_peer_cmd('softreset{0} -a {1}'.format(type, rf), peer) + + def get_local_rib(self, peer, prefix='', rf='ipv4'): if peer not in self.peers: raise Exception('not found peer {0}'.format(peer.router_id)) peer_addr = self.peers[peer]['neigh_addr'].split('/')[0] - cmd = 'gobgp -j neighbor {0} local -a {1}'.format(peer_addr, rf) + cmd = 'gobgp -j neighbor {0} local {1} -a {2}'.format(peer_addr, prefix, rf) output = self.local(cmd, capture=True) ret = json.loads(output) for d in ret: @@ -126,14 +134,26 @@ class GoBGPContainer(BGPContainer): output = self.local(cmd, capture=True) return json.loads(output)['info']['bgp_state'] + def clear_policy(self): + self.policies = {} + for info in self.peers.itervalues(): + info['policies'] = {} + self.prefix_set = [] + self.neighbor_set = [] + self.statements = [] + + def set_prefix_set(self, ps): + self.prefix_set = ps + + def set_neighbor_set(self, ns): + self.neighbor_set = ns + + def set_bgp_defined_set(self, bs): + self.bgp_set = bs + def create_config(self): config = {'Global': {'GlobalConfig': {'As': self.asn, 'RouterId': self.router_id}}} for peer, info in self.peers.iteritems(): - if self.asn == peer.asn: - peer_type = self.PEER_TYPE_INTERNAL - else: - peer_type = self.PEER_TYPE_EXTERNAL - afi_safi_list = [] version = netaddr.IPNetwork(info['neigh_addr']).version if version == 4: @@ -155,7 +175,6 @@ class GoBGPContainer(BGPContainer): {'NeighborAddress': info['neigh_addr'].split('/')[0], 'PeerAs': peer.asn, 'AuthPassword': info['passwd'], - 'PeerType': peer_type, }, 'AfiSafis': {'AfiSafiList': afi_safi_list} } @@ -171,11 +190,68 @@ class GoBGPContainer(BGPContainer): n['RouteReflector'] = {'RouteReflectorClient': True, 'RouteReflectorClusterId': clusterId} + f = lambda typ: [p for p in info['policies'].itervalues() if p['type'] == typ] + import_policies = f('import') + export_policies = f('export') + in_policies = f('in') + f = lambda typ: [p['default'] for p in info['policies'].itervalues() if p['type'] == typ and 'default' in p] + default_import_policy = f('import') + default_export_policy = f('export') + default_in_policy = f('in') + + if len(import_policies) + len(export_policies) + len(in_policies) + len(default_import_policy) \ + + len(default_export_policy) + len(default_in_policy) > 0: + n['ApplyPolicy'] = {'ApplyPolicyConfig': {}} + + if len(import_policies) > 0: + n['ApplyPolicy']['ApplyPolicyConfig']['ImportPolicy'] = [p['name'] for p in import_policies] + + if len(export_policies) > 0: + n['ApplyPolicy']['ApplyPolicyConfig']['ExportPolicy'] = [p['name'] for p in export_policies] + + if len(in_policies) > 0: + n['ApplyPolicy']['ApplyPolicyConfig']['InPolicy'] = [p['name'] for p in in_policies] + + def f(v): + if v == 'reject': + return 1 + elif v == 'accept': + return 0 + raise Exception('invalid default policy type {0}'.format(v)) + + if len(default_import_policy) > 0: + n['ApplyPolicy']['ApplyPolicyConfig']['DefaultImportPolicy'] = f(default_import_policy[0]) + + if len(default_export_policy) > 0: + n['ApplyPolicy']['ApplyPolicyConfig']['DefaultExportPolicy'] = f(default_export_policy[0]) + + if len(default_in_policy) > 0: + n['ApplyPolicy']['ApplyPolicyConfig']['DefaultInPolicy'] = f(default_in_policy[0]) + if 'Neighbors' not in config: config['Neighbors'] = {'NeighborList': []} config['Neighbors']['NeighborList'].append(n) + config['DefinedSets'] = {} + if self.prefix_set: + config['DefinedSets']['PrefixSets'] = {'PrefixSetList': [self.prefix_set]} + + if self.neighbor_set: + config['DefinedSets']['NeighborSets'] = {'NeighborSetList': [self.neighbor_set]} + + if self.bgp_set: + config['DefinedSets']['BgpDefinedSets'] = self.bgp_set + + policy_list = [] + for p in self.policies.itervalues(): + policy = {'Name': p['name'], + 'Statements':{'StatementList': p['statements']}} + policy_list.append(policy) + + if len(policy_list) > 0: + config['PolicyDefinitions'] = {'PolicyDefinitionList': policy_list} + with open('{0}/gobgpd.conf'.format(self.config_dir), 'w') as f: print colors.yellow('[{0}\'s new config]'.format(self.name)) print colors.yellow(indent(toml.dumps(config))) diff --git a/test/scenario_test/lib/quagga.py b/test/scenario_test/lib/quagga.py index e4de3ef1..8f2ba9a2 100644 --- a/test/scenario_test/lib/quagga.py +++ b/test/scenario_test/lib/quagga.py @@ -61,6 +61,7 @@ class QuaggaBGPContainer(BGPContainer): tn.write('show bgp {0} unicast\n'.format(rf)) tn.read_until(' Network Next Hop Metric ' 'LocPrf Weight Path') + read_next = False for line in tn.read_until('bgpd#').split('\n'): if line[:2] == '*>': line = line[2:] @@ -68,9 +69,24 @@ class QuaggaBGPContainer(BGPContainer): if line[0] == 'i': line = line[1:] ibgp = True - elems = line.split() - rib.append({'prefix': elems[0], 'nexthop': elems[1], - 'ibgp': ibgp}) + elif not read_next: + continue + + elems = line.split() + + if len(elems) == 1: + read_next = True + prefix = elems[0] + continue + elif read_next: + nexthop = elems[0] + else: + prefix = elems[0] + nexthop = elems[1] + read_next = False + + rib.append({'prefix': prefix, 'nexthop': nexthop, + 'ibgp': ibgp}) return rib @@ -149,12 +165,11 @@ class QuaggaBGPContainer(BGPContainer): c << 'no bgp default ipv4-unicast' c << 'neighbor {0} remote-as {1}'.format(n_addr, peer.asn) - for policy in info['policies']: - name = policy['name'] + for name, policy in info['policies'].iteritems(): direction = policy['direction'] c << 'neighbor {0} route-map {1} {2}'.format(n_addr, name, direction) - if info['passwd'] != '': + if info['passwd']: c << 'neighbor {0} password {1}'.format(n_addr, info['passwd']) if version == 6: c << 'address-family ipv6 unicast' |