def SetConfiguration(self, request, context): """ Configure sender and reflector nodes for running an experiment. """ # pylint: disable=invalid-name, unused-argument, no-self-use # # Establish a gRPC connection to the sender and to the reflector with utils.get_grpc_session(request.sender.address, request.sender.port) as sender_channel, \ utils.get_grpc_session(request.reflector.address, request.reflector.port) as refl_channel: # Send the set configuration request logger.debug('Trying to set the experiment configuration') res = srv6_pm.set_configuration( sender_channel=sender_channel, reflector_channel=refl_channel, send_udp_port=request.send_udp_port, refl_udp_port=request.refl_udp_port, interval_duration=request.color_options.interval_duration, delay_margin=request.color_options.delay_margin, number_of_color=request.color_options.number_of_color, pm_driver=request.pm_driver) logger.debug('Configuration installed successfully') # TODO set_configuration should return an exception in case of # error logger.debug('%s\n\n', utils.STATUS_CODE_TO_DESC[res]) # Done, create a reply return srv6pm_manager_pb2_grpc.SRv6PMManagerReply( status=nb_commons_pb2.STATUS_SUCCESS)
def GetExperimentResults(self, request, context): """ Get the results of a running experiment. """ # pylint: disable=invalid-name, unused-argument, no-self-use # # Establish a gRPC connection to the sender and to the reflector with utils.get_grpc_session(request.sender.address, request.sender.port) as sender_channel, \ utils.get_grpc_session(request.reflector.address, request.reflector.port) as refl_channel: # Trying to collect the experiment results logger.debug('Trying to collect the experiment results') print( srv6_pm.get_experiment_results( sender_channel=sender_channel, reflector_channel=refl_channel, send_refl_sidlist=list(request.send_refl_sidlist), refl_send_sidlist=list(request.refl_send_sidlist))) logger.debug('Results retrieved successfully') # TODO get_experiment_results should return an exception in case of error # TODO get_experiment_results should return the results instead of printing them # Done, create a reply return srv6pm_manager_pb2_grpc.SRv6PMManagerReply( status=nb_commons_pb2.STATUS_SUCCESS)
def start_experiment(): """Start a new experiment""" logger.info('*** Starting a new experiment') # IP addresses sender = SENDER reflector = REFLECTOR logger.info('Sender: %s' % sender) logger.info('Reflector: %s' % reflector) # Open gRPC channels with utils.get_grpc_session(sender, GRPC_PORT) as sender_channel, \ utils.get_grpc_session(reflector, GRPC_PORT) as reflector_channel: # Start the experiment srv6_pm.start_experiment( sender_channel=sender_channel, reflector_channel=reflector_channel, send_refl_dest='fd00:0:83::2', refl_send_dest='fd00:0:13::2', send_refl_sidlist=['fcff:3::1', 'fcff:4::1', 'fcff:8::100'], refl_send_sidlist=['fcff:4::1', 'fcff:3::1', 'fcff:1::100'], send_refl_localseg='fcff:8::100', refl_send_localseg='fcff:1::100', send_in_interfaces=['r1-r2'], refl_in_interfaces=['r8-r6'], send_out_interfaces=['r1-r2_egr'], refl_out_interfaces=['r8-r6_egr'], measurement_protocol='TWAMP', measurement_type='LOSS', authentication_mode='HMAC_SHA_256', authentication_key='s75pbhd-xsh;290f', timestamp_format='PTPv2', delay_measurement_mode='OneWay', padding_mbz=10, loss_measurement_mode='Inferred', force=True)
def StopExperiment(self, request, context): """ Stop a running experiment. """ # pylint: disable=invalid-name, unused-argument, no-self-use # # Establish a gRPC connection to the sender and to the reflector with utils.get_grpc_session(request.sender.address, request.sender.port) as sender_channel, \ utils.get_grpc_session(request.reflector.address, request.reflector.port) as refl_channel: # Trying to stop the experiment logger.debug('Trying to stop the experiment') res = srv6_pm.stop_experiment( sender_channel=sender_channel, reflector_channel=refl_channel, send_refl_dest=request.send_refl_dest, refl_send_dest=request.refl_send_dest, send_refl_sidlist=list(request.send_refl_sidlist), refl_send_sidlist=list(request.refl_send_sidlist), send_refl_localseg=request.send_refl_localseg, refl_send_localseg=request.refl_send_localseg) logger.debug('Experiment stopped successfully') # TODO stop_experiment should return an exception in case of error logger.debug('%s\n\n', utils.STATUS_CODE_TO_DESC[res]) # Done, create a reply return srv6pm_manager_pb2_grpc.SRv6PMManagerReply( status=nb_commons_pb2.STATUS_SUCCESS)
def start_experiment( sender, reflector, sender_port, reflector_port, send_refl_dest, refl_send_dest, send_refl_sidlist, refl_send_sidlist, # send_in_interfaces, refl_in_interfaces, # send_out_interfaces, refl_out_interfaces, measurement_protocol, measurement_type, authentication_mode, authentication_key, timestamp_format, delay_measurement_mode, padding_mbz, loss_measurement_mode, measure_id=None, send_refl_localseg=None, refl_send_localseg=None, force=False): """Start an experiment""" # pylint: disable=too-many-arguments, too-many-locals with utils.get_grpc_session(sender, sender_port) as sender_channel, \ utils.get_grpc_session(reflector, reflector_port) as refl_channel: res = srv6_pm.start_experiment( sender_channel=sender_channel, reflector_channel=refl_channel, send_refl_dest=send_refl_dest, refl_send_dest=refl_send_dest, send_refl_sidlist=send_refl_sidlist.split(','), refl_send_sidlist=refl_send_sidlist.split(','), # Interfaces moved to set_configuration # send_in_interfaces=send_in_interfaces, # refl_in_interfaces=refl_in_interfaces, # send_out_interfaces=send_out_interfaces, # refl_out_interfaces=refl_out_interfaces, measurement_protocol=measurement_protocol, measurement_type=measurement_type, authentication_mode=authentication_mode, authentication_key=authentication_key, timestamp_format=timestamp_format, delay_measurement_mode=delay_measurement_mode, padding_mbz=padding_mbz, loss_measurement_mode=loss_measurement_mode, measure_id=measure_id, send_refl_localseg=send_refl_localseg, refl_send_localseg=refl_send_localseg, force=force) if res == 0: print('OK') else: print('Error')
def reset_configuration(sender, reflector, sender_port, reflector_port): """Clear node configuration""" with utils.get_grpc_session(sender, sender_port) as sender_channel, \ utils.get_grpc_session(reflector, reflector_port) as refl_channel: res = srv6_pm.reset_configuration(sender_channel=sender_channel, reflector_channel=refl_channel) if res == 0: print('OK') else: print('Error')
def get_experiment_results(sender, reflector, sender_port, reflector_port, send_refl_sidlist, refl_send_sidlist): """Get the results of a running experiment""" # pylint: disable=too-many-arguments with utils.get_grpc_session(sender, sender_port) as sender_channel, \ utils.get_grpc_session(reflector, reflector_port) as refl_channel: print( srv6_pm.get_experiment_results( sender_channel=sender_channel, reflector_channel=refl_channel, send_refl_sidlist=send_refl_sidlist.split(','), refl_send_sidlist=refl_send_sidlist.split(',')))
def handle_srv6_path( operation, grpc_address, grpc_port, destination, segments="", device='', encapmode="encap", table=-1, metric=-1, bsid_addr='', fwd_engine='Linux'): """Handle a SRv6 path""" # pylint: disable=too-many-arguments with utils.get_grpc_session(grpc_address, grpc_port) as channel: res = srv6_utils.handle_srv6_path( operation=operation, channel=channel, destination=destination, segments=segments.split(','), device=device, encapmode=encapmode, table=table, metric=metric, bsid_addr=bsid_addr, fwd_engine=fwd_engine ) if res == 0: print('OK') else: print('Error')
def handle_srv6_biditunnel(operation, node_l_ip, node_l_port, node_r_ip, node_r_port, sidlist_lr, sidlist_rl, dest_lr, dest_rl, localseg_lr=None, localseg_rl=None, bsid_addr='', fwd_engine='Linux'): """Handle SRv6 bidirectional tunnel""" # pylint: disable=too-many-arguments with utils.get_grpc_session(node_l_ip, node_l_port) as node_l_channel, \ utils.get_grpc_session(node_r_ip, node_r_port) as node_r_channel: if operation == 'add': res = srv6_utils.create_srv6_tunnel( node_l_channel=node_l_channel, node_r_channel=node_r_channel, sidlist_lr=sidlist_lr.split(','), sidlist_rl=sidlist_rl.split(','), dest_lr=dest_lr, dest_rl=dest_rl, localseg_lr=localseg_lr, localseg_rl=localseg_rl, bsid_addr=bsid_addr, fwd_engine=fwd_engine ) if res == 0: print('OK') else: print('Error') elif operation == 'del': res = srv6_utils.destroy_srv6_tunnel( node_l_channel=node_l_channel, node_r_channel=node_r_channel, dest_lr=dest_lr, dest_rl=dest_rl, localseg_lr=localseg_lr, localseg_rl=localseg_rl, bsid_addr=bsid_addr, fwd_engine=fwd_engine ) if res == 0: print('OK') else: print('Error') else: print('Invalid operation %s' % operation)
def StartExperiment(self, request, context): """ Start an experiment. """ # pylint: disable=invalid-name, unused-argument, no-self-use # # Establish a gRPC connection to the sender and to the reflector with utils.get_grpc_session(request.sender.address, request.sender.port) as sender_channel, \ utils.get_grpc_session(request.reflector.address, request.reflector.port) as refl_channel: # Trying to start the experiment logger.debug('Trying to start the experiment') res = srv6_pm.start_experiment( sender_channel=sender_channel, reflector_channel=refl_channel, send_refl_dest=request.send_refl_dest, refl_send_dest=request.refl_send_dest, send_refl_sidlist=list(request.send_refl_sidlist), refl_send_sidlist=list(request.refl_send_sidlist), measurement_protocol=grpc_to_py_measurement_protocol( request.measurement_protocol), measurement_type=grpc_to_py_measurement_type( request.measurement_type), authentication_mode=grpc_to_py_authentication_mode( request.authentication_mode), authentication_key=request.authentication_key, timestamp_format=grpc_to_py_timestamp_format( request.timestamp_format), delay_measurement_mode=grpc_to_py_delay_measurement_mode( request.delay_measurement_mode), padding_mbz=request.padding_mbz, loss_measurement_mode=grpc_to_py_loss_measurement_mode( request.loss_measurement_mode), measure_id=request.measure_id, send_refl_localseg=request.send_refl_localseg, refl_send_localseg=request.refl_send_localseg, force=request.force) logger.debug('Experiment started successfully') # TODO start_experiment should return an exception in case of error logger.debug('%s\n\n', utils.STATUS_CODE_TO_DESC[res]) # Done, create a reply return srv6pm_manager_pb2_grpc.SRv6PMManagerReply( status=nb_commons_pb2.STATUS_SUCCESS)
def get_experiment_results(): """Get the results of a running experiment""" logger.info('*** Get experiment results') # IP addresses sender = SENDER reflector = REFLECTOR logger.info('Sender: %s' % sender) logger.info('Reflector: %s' % reflector) # Open gRPC channels with utils.get_grpc_session(sender, GRPC_PORT) as sender_channel, \ utils.get_grpc_session(reflector, GRPC_PORT) as reflector_channel: # Get the results results = srv6_pm.get_experiment_results( sender_channel=sender_channel, reflector_channel=reflector_channel, send_refl_sidlist=['fcff:3::1', 'fcff:4::1', 'fcff:8::100'], refl_send_sidlist=['fcff:4::1', 'fcff:3::1', 'fcff:1::100'], ) # Check for errors if results is None: print('Error in get_experiment_results()') print() return # Print the results for result in results: print("------------------------------") print("Measurement ID: %s" % result['measure_id']) print("Interval: %s" % result['interval']) print("Timestamp: %s" % result['timestamp']) print("FW Color: %s" % result['fw_color']) print("RV Color: %s" % result['rv_color']) print("sender_seq_num: %s" % result['sender_seq_num']) print("reflector_seq_num: %s" % result['reflector_seq_num']) print("Sender TX counter: %s" % result['sender_tx_counter']) print("Sender RX counter: %s" % result['sender_rx_counter']) print("Reflector TX counter: %s" % result['reflector_tx_counter']) print("Reflector RX counter: %s" % result['reflector_rx_counter']) print("------------------------------") print() print()
def set_configuration(sender, reflector, sender_port, reflector_port, send_udp_port, refl_udp_port, interval_duration, delay_margin, number_of_color, pm_driver): """Configure a node""" # pylint: disable=too-many-arguments with utils.get_grpc_session(sender, sender_port) as sender_channel, \ utils.get_grpc_session(reflector, reflector_port) as refl_channel: res = srv6_pm.set_configuration(sender_channel=sender_channel, reflector_channel=refl_channel, send_udp_port=send_udp_port, refl_udp_port=refl_udp_port, interval_duration=interval_duration, delay_margin=delay_margin, number_of_color=number_of_color, pm_driver=pm_driver) if res == 0: print('OK') else: print('Error')
def set_configuration(): """Start a new experiment""" logger.info('*** Set experiment configuration') # IP addresses sender = SENDER reflector = REFLECTOR logger.info('Sender: %s' % sender) logger.info('Reflector: %s' % reflector) # Open gRPC channels with utils.get_grpc_session(sender, GRPC_PORT) as sender_channel, \ utils.get_grpc_session(reflector, GRPC_PORT) as reflector_channel: # Start the experiment srv6_pm.set_configuration( sender_channel=sender_channel, reflector_channel=reflector_channel, send_udp_port=1205, refl_udp_port=1206, interval_duration=10, delay_margin=5, # sec assert(<interval) number_of_color=2, # sec assert(==2) pm_driver=srv6pmCommons_pb2.PMDriver.Value('eBPF'))
def handle_srv6_unitunnel(operation, ingress_ip, ingress_port, egress_ip, egress_port, destination, segments, localseg=None, bsid_addr='', fwd_engine='Linux'): """Handle a SRv6 unidirectional tunnel""" # pylint: disable=too-many-arguments with utils.get_grpc_session(ingress_ip, ingress_port) as ingress_channel, \ utils.get_grpc_session(egress_ip, egress_port) as egress_channel: if operation == 'add': res = srv6_utils.create_uni_srv6_tunnel( ingress_channel=ingress_channel, egress_channel=egress_channel, destination=destination, segments=segments.split(','), localseg=localseg, bsid_addr=bsid_addr, fwd_engine=fwd_engine ) if res == 0: print('OK') else: print('Error') elif operation == 'del': res = srv6_utils.destroy_uni_srv6_tunnel( ingress_channel=ingress_channel, egress_channel=egress_channel, destination=destination, localseg=localseg, bsid_addr=bsid_addr, fwd_engine=fwd_engine ) if res == 0: print('OK') else: print('Error') else: print('Invalid operation %s' % operation)
def ResetConfiguration(self, request, context): """ Clear node configuration. """ # pylint: disable=invalid-name, unused-argument, no-self-use # # Establish a gRPC connection to the sender and to the reflector with utils.get_grpc_session(request.sender.address, request.sender.port) as sender_channel, \ utils.get_grpc_session(request.reflector.address, request.reflector.port) as refl_channel: # Send the reset configuration request logger.debug('Trying to reset the experiment configuration') res = srv6_pm.reset_configuration(sender_channel=sender_channel, reflector_channel=refl_channel) logger.debug('Configuration reset successfully') # TODO reset_configuration should return an exception in case of # error logger.debug('%s\n\n', utils.STATUS_CODE_TO_DESC[res]) # Done, create a reply return srv6pm_manager_pb2_grpc.SRv6PMManagerReply( status=nb_commons_pb2.STATUS_SUCCESS)
def stop_experiment(): """Stop a running experiment""" logger.info('*** Stopping experiment') # IP addresses sender = SENDER reflector = REFLECTOR logger.info('Sender: %s' % sender) logger.info('Reflector: %s' % reflector) # Open gRPC channels with utils.get_grpc_session(sender, GRPC_PORT) as sender_channel, \ utils.get_grpc_session(reflector, GRPC_PORT) as reflector_channel: # Stop the experiment srv6_pm.stop_experiment( sender_channel=sender_channel, reflector_channel=reflector_channel, send_refl_dest='fd00:0:83::2', refl_send_dest='fd00:0:13::2', send_refl_sidlist=['fcff:3::1', 'fcff:4::1', 'fcff:8::100'], refl_send_sidlist=['fcff:4::1', 'fcff:3::1', 'fcff:1::100'], send_refl_localseg='fcff:8::100', refl_send_localseg='fcff:1::100', )
def stop_experiment(sender, reflector, sender_port, reflector_port, send_refl_dest, refl_send_dest, send_refl_sidlist, refl_send_sidlist, send_refl_localseg=None, refl_send_localseg=None): """Stop a running experiment""" # pylint: disable=too-many-arguments with utils.get_grpc_session(sender, sender_port) as sender_channel, \ utils.get_grpc_session(reflector, reflector_port) as refl_channel: srv6_pm.stop_experiment(sender_channel=sender_channel, reflector_channel=refl_channel, send_refl_dest=send_refl_dest, refl_send_dest=refl_send_dest, send_refl_sidlist=send_refl_sidlist.split(','), refl_send_sidlist=refl_send_sidlist.split(','), send_refl_localseg=send_refl_localseg, refl_send_localseg=refl_send_localseg)
def handle_srv6_behavior( operation, grpc_address, grpc_port, segment, action='', device='', table=-1, nexthop="", lookup_table=-1, interface="", segments="", metric=-1, fwd_engine='Linux'): """Handle a SRv6 behavior""" # pylint: disable=too-many-arguments with utils.get_grpc_session(grpc_address, grpc_port) as channel: res = srv6_utils.handle_srv6_behavior( operation=operation, channel=channel, segment=segment, action=action, device=device, table=table, nexthop=nexthop, lookup_table=lookup_table, interface=interface, segments=segments.split(','), metric=metric, fwd_engine=fwd_engine ) if res == 0: print('OK') else: print('Error')
def handle_srv6_usid_policy(operation, lr_destination=None, rl_destination=None, nodes_lr=None, nodes_rl=None, table=-1, metric=-1, persistency=True, _id=None, l_grpc_ip=None, l_grpc_port=None, l_fwd_engine=None, r_grpc_ip=None, r_grpc_port=None, r_fwd_engine=None, decap_sid=None, locator=None, db_conn=None): """ Handle a SRv6 Policy using uSIDs :param operation: The operation to be performed on the uSID policy (i.e. add, get, change, del) :type operation: str :param destination: Destination of the SRv6 route :type destination: str :param nodes: Waypoints of the SRv6 route :type nodes: list :param device: Device of the SRv6 route. If not provided, the device is selected automatically by the node. :type device: str, optional :param table: Routing table containing the SRv6 route. If not provided, the main table (i.e. table 254) will be used. :type table: int, optional :param metric: Metric for the SRv6 route. If not provided, the default metric will be used. :type metric: int, optional :param l_grpc_ip: gRPC IP address of the left node, required if the left node is expressed numerically in the nodes list. :type l_grpc_ip: str, optional :param l_grpc_port: gRPC port of the left node, required if the left node is expressed numerically in the nodes list. :type l_grpc_port: str, optional :param l_fwd_engine: forwarding engine of the left node, required if the left node is expressed numerically in the nodes list. :type l_fwd_engine: str, optional :param r_grpc_ip: gRPC IP address of the right node, required if the right node is expressed numerically in the nodes list. :type r_grpc_ip: str, optional :param r_grpc_port: gRPC port of the right node, required if the right node is expressed numerically in the nodes list. :type r_grpc_port: str, optional :param r_fwd_engine: Forwarding engine of the right node, required if the right node is expressed numerically in the nodes list. :type r_fwd_engine: str, optional :param decap_sid: uSID used for the decap behavior (End.DT6). :type decap_sid: str, optional :param locator: Locator prefix (e.g. 'fcbb:bbbb::'). :type locator: str, optional :return: Status Code of the operation (e.g. 0 for STATUS_SUCCESS) :rtype: int :raises NodeNotFoundError: Node name not found in the mapping file :raises InvalidConfigurationError: The mapping file is not a valid YAML file :raises TooManySegmentsError: segments arg contains more than 6 segments :raises SIDLocatorError: SID Locator is wrong for one or more segments :raises InvalidSIDError: SID is wrong for one or more segments """ # pylint: disable=too-many-locals, too-many-arguments # pylint: disable=too-many-return-statements, too-many-branches # pylint: disable=too-many-statements # # Validate arguments if lr_destination is None: if operation in ['add']: logger.error('"lr_destination" argument is mandatory for %s ' 'operation', operation) return None if rl_destination is None: if operation in ['add']: logger.error('"rl_destination" argument is mandatory for %s ' 'operation', operation) return None if nodes_lr is None: if operation in ['add']: logger.error('"nodes_lr" argument is mandatory for %s ' 'operation', operation) return None if nodes_rl is None: pass if operation == 'change': logger.error('Operation not yet implemented: %s', operation) return None if operation == 'get': if not persistency: logger.error('Error in get(): Persistency is disabled') return None # Get the policy from the db policies = arangodb_driver.find_usid_policy( database=db_conn, key=_id, lr_dst=lr_destination, rl_dst=rl_destination, lr_nodes=nodes_lr, rl_nodes=nodes_rl, table=table if table != -1 else None, metric=metric if metric != -1 else None ) # Print policies print('\n\n*** uSID policies:') pprint.PrettyPrinter(indent=4).pprint(list(policies)) print('\n\n') return 0 if operation in ['add', 'del']: # Extract the nodes configuration from the db nodes_config = topo_utils.get_nodes_config() # # In order to perform this translation, a file containing the # mapping of node names to IPv6 addresses is required # # Read nodes from YAML file nodes_info = {node['name']: node for node in nodes_config['nodes']} locator_bits = DEFAULT_LOCATOR_BITS # TODO configurable locator bits usid_id_bits = DEFAULT_USID_ID_BITS # TODO configurable uSID id bits # Add nodes list for the left-to-right path to the 'nodes_info' dict if nodes_lr is not None: fill_nodes_info( nodes_info=nodes_info, nodes=nodes_lr, l_grpc_ip=l_grpc_ip, l_grpc_port=l_grpc_port, l_fwd_engine=l_fwd_engine, r_grpc_ip=r_grpc_ip, r_grpc_port=r_grpc_port, r_fwd_engine=r_fwd_engine, decap_sid=decap_sid, locator=locator ) # Add nodes list for the right-to-left path to the 'nodes_info' dict if nodes_rl is not None: fill_nodes_info( nodes_info=nodes_info, nodes=nodes_rl, l_grpc_ip=r_grpc_ip, l_grpc_port=r_grpc_port, l_fwd_engine=r_fwd_engine, r_grpc_ip=l_grpc_ip, r_grpc_port=l_grpc_port, r_fwd_engine=l_fwd_engine, decap_sid=decap_sid, locator=locator ) # Add if operation == 'add': policies = [{ 'lr_dst': lr_destination, 'rl_dst': rl_destination, 'lr_nodes': nodes_lr, 'rl_nodes': nodes_rl }] if operation == 'del': # Get the policy from the db policies = arangodb_driver.find_usid_policy( database=db_conn, key=_id, lr_dst=lr_destination, rl_dst=rl_destination, lr_nodes=nodes_lr, rl_nodes=nodes_rl, table=table if table != -1 else None, metric=metric if metric != -1 else None ) policies = list(policies) for policy in policies: # Add nodes list for the left-to-right path to the # 'nodes_info' dict if policy.get('lr_nodes') is not None: fill_nodes_info( nodes_info=nodes_info, nodes=policy.get('lr_nodes'), l_grpc_ip=policy.get('l_grpc_ip'), l_grpc_port=policy.get('l_grpc_port'), l_fwd_engine=policy.get('l_fwd_engine'), r_grpc_ip=policy.get('r_grpc_ip'), r_grpc_port=policy.get('r_grpc_port'), r_fwd_engine=policy.get('r_fwd_engine'), decap_sid=policy.get('decap_sid'), locator=policy.get('locator') ) # Add nodes list for the right-to-left path to the # 'nodes_info' dict if policy.get('rl_nodes') is not None: fill_nodes_info( nodes_info=nodes_info, nodes=policy.get('rl_nodes'), l_grpc_ip=policy.get('r_grpc_ip'), l_grpc_port=policy.get('r_grpc_port'), l_fwd_engine=policy.get('r_fwd_engine'), r_grpc_ip=policy.get('l_grpc_ip'), r_grpc_port=policy.get('l_grpc_port'), r_fwd_engine=policy.get('l_fwd_engine'), decap_sid=policy.get('decap_sid'), locator=policy.get('locator') ) if len(policies) == 0: logger.error('Policy not found') return None # Iterate on the policies for policy in policies: lr_destination = policy.get('lr_dst') rl_destination = policy.get('rl_dst') nodes_lr = policy.get('lr_nodes') nodes_rl = policy.get('rl_nodes') _id = policy.get('_key') # # If right to left nodes list is not provided, we use the reverse # left to right SID list (symmetric path) if nodes_rl is None: nodes_rl = nodes_lr[::-1] # The two SID lists must have the same endpoints if nodes_lr[0] != nodes_rl[-1] or nodes_rl[0] != nodes_lr[-1]: logger.error('Bad tunnel endpoints') return None # Create the SRv6 Policy try: # # Prefix length for local segment # prefix_len = locator_bits + usid_id_bits # Ingress node ingress_node = nodes_info[nodes_lr[0]] # Intermediate nodes intermediate_nodes_lr = list() for node in nodes_lr[1:-1]: intermediate_nodes_lr.append(nodes_info[node]) intermediate_nodes_rl = list() for node in nodes_rl[1:-1]: intermediate_nodes_rl.append(nodes_info[node]) # Egress node egress_node = nodes_info[nodes_lr[-1]] # Extract the segments segments_lr = list() for node in nodes_lr: segments_lr.append(nodes_info[node]['uN']) segments_rl = list() for node in nodes_rl: segments_rl.append(nodes_info[node]['uN']) # Ingress node with utils.get_grpc_session(ingress_node['grpc_ip'], ingress_node['grpc_port'] ) as channel: # Currently ony Linux and VPP are suppoted for the encap if ingress_node['fwd_engine'] not in ['linux', 'vpp']: logger.error( 'Encap operation is not supported for ' '%s with fwd engine %s', ingress_node['name'], ingress_node['fwd_engine']) return commons_pb2.STATUS_INTERNAL_ERROR # VPP requires a BSID address bsid_addr = '' if ingress_node['fwd_engine'] == 'VPP': for char in lr_destination: if char not in ('0', ':'): bsid_addr += char add_colon = False if len(bsid_addr) <= 28: add_colon = True bsid_addr = [(bsid_addr[i:i + 4]) for i in range(0, len(bsid_addr), 4)] bsid_addr = ':'.join(bsid_addr) if add_colon: bsid_addr += '::' udt_sids = list() # Locator mask locator_mask = str(IPv6Address( int('1' * 128, 2) ^ int('1' * (128 - locator_bits), 2))) # uDT mask udt_mask_1 = str( IPv6Address(int('1' * usid_id_bits, 2) << (128 - locator_bits - usid_id_bits))) udt_mask_2 = str( IPv6Address(int('1' * usid_id_bits, 2) << (128 - locator_bits - 2 * usid_id_bits))) # Build uDT sid list locator_int = int(IPv6Address(egress_node['uDT'])) & \ int(IPv6Address(locator_mask)) udt_mask_1_int = int(IPv6Address(egress_node['uDT'])) & \ int(IPv6Address(udt_mask_1)) udt_mask_2_int = int(IPv6Address(egress_node['uDT'])) & \ int(IPv6Address(udt_mask_2)) udt_sids += [str(IPv6Address(locator_int + udt_mask_1_int))] udt_sids += [str(IPv6Address(locator_int + (udt_mask_2_int << usid_id_bits)))] # We need to convert the SID list into a uSID list # before creating the SRv6 policy usid_list = sidlist_to_usidlist( sid_list=segments_lr[1:][:-1], udt_sids=[segments_lr[1:][-1]] + udt_sids, locator_bits=locator_bits, usid_id_bits=usid_id_bits ) # Handle a SRv6 path response = srv6_utils.handle_srv6_path( operation=operation, channel=channel, destination=lr_destination, segments=usid_list, encapmode='encap.red', table=table, metric=metric, bsid_addr=bsid_addr, fwd_engine=ingress_node['fwd_engine'], update_db=False ) if response != commons_pb2.STATUS_SUCCESS: # Error return response # # Create the uN behavior # response = handle_srv6_behavior( # operation=operation, # channel=channel, # segment='%s/%s' % (ingress_node['uN'], prefix_len), # action='uN', # fwd_engine=ingress_node['fwd_engine'] # ) # if response != commons_pb2.STATUS_SUCCESS: # # Error # return response # # Create the End behavior # response = handle_srv6_behavior( # operation=operation, # channel=channel, # segment='%s/%s' % (ingress_node['uN'], 64), # action='End', # fwd_engine=ingress_node['fwd_engine'] # ) # if response != commons_pb2.STATUS_SUCCESS: # # Error # return response # # Create the decap behavior # response = handle_srv6_behavior( # operation=operation, # channel=channel, # segment='%s/%s' % (ingress_node['uDT'], 64), # action='End.DT6', # lookup_table=254, # fwd_engine=ingress_node['fwd_engine'] # ) # if response != commons_pb2.STATUS_SUCCESS: # # Error # return response # # Intermediate nodes # for node in intermediate_nodes: # with utils.get_grpc_session(node['grpc_ip'], # node['grpc_port'] # ) as channel: # # Create the uN behavior # response = handle_srv6_behavior( # operation=operation, # channel=channel, # segment='%s/%s' % (node['uN'], prefix_len), # action='uN', # fwd_engine=node['fwd_engine'] # ) # if response != commons_pb2.STATUS_SUCCESS: # # Error # return response # Egress node with utils.get_grpc_session(egress_node['grpc_ip'], egress_node['grpc_port'] ) as channel: # Currently ony Linux and VPP are suppoted for the encap if egress_node['fwd_engine'] not in ['linux', 'vpp']: logger.error( 'Encap operation is not supported for ' '%s with fwd engine %s', egress_node['name'], egress_node['fwd_engine']) return commons_pb2.STATUS_INTERNAL_ERROR # VPP requires a BSID address bsid_addr = '' if egress_node['fwd_engine'] == 'VPP': for char in lr_destination: if char not in ('0', ':'): bsid_addr += char add_colon = False if len(bsid_addr) <= 28: add_colon = True bsid_addr = [(bsid_addr[i:i + 4]) for i in range(0, len(bsid_addr), 4)] bsid_addr = ':'.join(bsid_addr) if add_colon: bsid_addr += '::' # # Create the uN behavior # response = handle_srv6_behavior( # operation=operation, # channel=channel, # segment='%s/%s' % (egress_node['uN'], prefix_len), # action='uN', # fwd_engine=egress_node['fwd_engine'] # ) # if response != commons_pb2.STATUS_SUCCESS: # # Error # return response # # Create the End behavior # response = handle_srv6_behavior( # operation=operation, # channel=channel, # segment='%s/%s' % (egress_node['uN'], 64), # action='End', # fwd_engine=egress_node['fwd_engine'] # ) # if response != commons_pb2.STATUS_SUCCESS: # # Error # return response # # Create the decap behavior # response = handle_srv6_behavior( # operation=operation, # channel=channel, # segment='%s/%s' % (egress_node['uDT'], 64), # action='End.DT6', # lookup_table=254, # fwd_engine=egress_node['fwd_engine'] # ) # if response != commons_pb2.STATUS_SUCCESS: # # Error # return response udt_sids = list() # Locator mask locator_mask = str(IPv6Address( int('1' * 128, 2) ^ int('1' * (128 - locator_bits), 2))) # uDT mask udt_mask_1 = str(IPv6Address(int('1' * usid_id_bits, 2) << (128 - locator_bits - usid_id_bits))) udt_mask_2 = str(IPv6Address(int('1' * usid_id_bits, 2) << (128 - locator_bits - 2 * usid_id_bits))) # Build uDT sid list locator_int = int( IPv6Address( ingress_node['uDT'])) & int( IPv6Address(locator_mask)) udt_mask_1_int = int( IPv6Address( ingress_node['uDT'])) & int( IPv6Address(udt_mask_1)) udt_mask_2_int = int( IPv6Address( ingress_node['uDT'])) & int( IPv6Address(udt_mask_2)) udt_sids += [str(IPv6Address(locator_int + udt_mask_1_int))] udt_sids += [str(IPv6Address(locator_int + (udt_mask_2_int << usid_id_bits)))] # We need to convert the SID list into a uSID list # before creating the SRv6 policy usid_list = sidlist_to_usidlist( sid_list=segments_rl[1:][:-1], udt_sids=[segments_rl[1:][-1]] + udt_sids, locator_bits=locator_bits, usid_id_bits=usid_id_bits ) # Handle a SRv6 path response = srv6_utils.handle_srv6_path( operation=operation, channel=channel, destination=rl_destination, segments=usid_list, encapmode='encap.red', table=table, metric=metric, bsid_addr=bsid_addr, fwd_engine=egress_node['fwd_engine'], update_db=False ) if response != commons_pb2.STATUS_SUCCESS: # Error return response # Persist uSID policy to database if persistency: if operation == 'add': # Save the policy to the db arangodb_driver.insert_usid_policy( database=db_conn, lr_dst=lr_destination, rl_dst=rl_destination, lr_nodes=nodes_lr, rl_nodes=nodes_rl, table=table if table != -1 else None, metric=metric if metric != -1 else None, l_grpc_ip=l_grpc_ip, l_grpc_port=l_grpc_port, l_fwd_engine=l_fwd_engine, r_grpc_ip=r_grpc_ip, r_grpc_port=r_grpc_port, r_fwd_engine=r_fwd_engine, decap_sid=decap_sid, locator=locator ) elif operation == 'del': # Save the policy to the db arangodb_driver.delete_usid_policy( database=db_conn, key=_id, lr_dst=lr_destination, rl_dst=rl_destination, lr_nodes=nodes_lr, rl_nodes=nodes_rl, table=table if table != -1 else None, metric=metric if metric != -1 else None ) else: logger.error('Unsupported operation: %s', operation) except (InvalidConfigurationError, NodeNotFoundError, TooManySegmentsError, SIDLocatorError, InvalidSIDError): return commons_pb2.STATUS_INTERNAL_ERROR # Return the response return response logger.error('Unsupported operation: %s', operation) return None
def create_tunnel_r1r4r8(): # +--------------------------------------------------------------------+ # | Create a bidirectional tunnel between h11 and h83 | # | passing through router r4 (r1---r4---r8) | # +--------------------------------------------------------------------+ logger.info('*** Attempting to create tunnel r1---r4---r8') # IP addresses r1 = 'fcff:1::1' r8 = 'fcff:8::1' # Open gRPC channels with get_grpc_session(r1, GRPC_PORT) as r1_chan, \ get_grpc_session(r8, GRPC_PORT) as r8_chan: # +---------------------------------------------------------------+ # | Set tunnel from r1 to r8 for fd00:0:83::/64 | # +---------------------------------------------------------------+ logger.info('******* Set tunnel from r1 to r8 for fd00:0:83::/64') # # Encap route on r1 # on r1: ip -6 route add fd00:0:83::/64 encap seg6 mode encap segs # fcff:4::1,fcff:8::100 dev r1-h11 metric 200 logger.info('*********** Creating encap route') res = handle_srv6_path( op='add', channel=r1_chan, destination='fd00:0:83::/64', segments=['fcff:4::1', 'fcff:8::100'], device='r1-h11', metric=200 ) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route created successfully') else: logger.error('*********** Error while creating encap route') # # Decap route on r8 # on r8: ip -6 route add fcff:8::100 encap seg6local action End.DT6 # table 254 dev r8-h83 metric 200 logger.info('*********** Creating decap route') res = handle_srv6_behavior( op='add', channel=r8_chan, segment='fcff:8::100', action='End.DT6', lookup_table=254, device='r8-h83', metric=200 ) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route created successfully') else: logger.error('*********** Error while creating decap route') # # # +---------------------------------------------------------------+ # | Set tunnel from r8 to r1 for fd00:0:11::/64 | # +---------------------------------------------------------------+ logger.info('******* Set tunnel from r8 to r1 for fd00:0:11::/64') # # Encap route on r8 # on r8: ip -6 route add fd00:0:11::/64 encap seg6 mode encap segs # fcff:4::1,fcff:1::100 dev r8-h83 metric 200 logger.info('*********** Creating encap route') res = handle_srv6_path( op='add', channel=r8_chan, destination='fd00:0:11::/64', segments=['fcff:4::1', 'fcff:1::100'], device='r8-h83', metric=200 ) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route created successfully') else: logger.error('*********** Error while creating encap route') # # Decap route on r1 # on r1: ip -6 route add fcff:1::100 encap seg6local action End.DT6 # table 254 dev r1-h11 metric 200 logger.info('*********** Creating decap route') res = handle_srv6_behavior( op='add', channel=r1_chan, segment='fcff:1::100', action='End.DT6', lookup_table=254, device='r1-h11', metric=200 ) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route created successfully') else: logger.error('*********** Error while creating decap route') # # # +---------------------------------------------------------------+ # | Done | # +---------------------------------------------------------------+ print()
def shift_path(): # +--------------------------------------------------------------------+ # | Switch from r1---r7---r8 path to r1---r4---r8 path | # | by exchanging the metrics | # +--------------------------------------------------------------------+ logger.info( '*** Attempting to change path from r1---r7---r8 to r1---r4---r8') # IP addresses r1 = 'fcff:1::1' r8 = 'fcff:8::1' # Open gRPC channels with get_grpc_session(r1, GRPC_PORT) as r1_chan, \ get_grpc_session(r8, GRPC_PORT) as r8_chan: # +---------------------------------------------------------------+ # | Decreasing the metric value of the | # | r4 route to an intermediate value | # +---------------------------------------------------------------+ logger.info('******* Decreasing the metric value of ' 'the r4 route to an intermediate value') # # Encap route on r1 # on r1: ip -6 route add fd00:0:83::/64 encap seg6 mode encap segs # fcff:4::1,fcff:8:100 dev r1-h11 metric 99 logger.info('*********** Creating encap route on r1') res = handle_srv6_path(op='add', channel=r1_chan, destination='fd00:0:83::/64', segments=['fcff:4::1', 'fcff:8::100'], device='r1-h11', metric=99) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route created successfully') else: logger.error('*********** Error while creating encap route') # # Decap route on r8 # on r8: ip -6 route add fcff:8::100 encap seg6local action End.DT6 # table 254 dev r8-h83 metric 99 logger.info('*********** Creating decap route on r8') res = handle_srv6_behavior(op='add', channel=r8_chan, segment='fcff:8::100', action='End.DT6', lookup_table=254, device='r8-h83', metric=99) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route created successfully') else: logger.error('*********** Error while creating decap route') # # Encap route on r8 # on r8: ip -6 route add fd00:0:11::/64 encap seg6 mode encap segs # fcff:4::1,fcff:1:100 dev r8-h83 metric 99 logger.info('*********** Creating encap route on r8') res = handle_srv6_path(op='add', channel=r8_chan, destination='fd00:0:11::/64', segments=['fcff:4::1', 'fcff:1::100'], device='r8-h83', metric=99) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route created successfully') else: logger.error('*********** Error while creating encap route') # # Decap route on r1 # on r1: ip -6 route add fcff:1::100 encap seg6local action End.DT6 # table 254 dev r1-h11 metric 99 logger.info('*********** Creating decap route on r1') res = handle_srv6_behavior(op='add', channel=r1_chan, segment='fcff:1::100', action='End.DT6', lookup_table=254, device='r1-h11', metric=99) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route created successfully') else: logger.error('*********** Error while creating decap route') # # # +---------------------------------------------------------------+ # | Removing old route via r4 | # +---------------------------------------------------------------+ logger.info('*** Attempting to remove tunnel r1---r4---r8') # # Encap route on r1 # on r1: ip -6 route del fd00:0:83::/64 encap seg6 mode encap segs # fcff:4::1,fcff:8:100 dev r1-h11 metric 200 logger.info('*********** Removing encap route on r1') res = handle_srv6_path(op='del', channel=r1_chan, destination='fd00:0:83::/64', device='r1-h11', metric=200) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route removed successfully') else: logger.error('*********** Error while removing encap route') # # Decap route on r8 # on r8: ip -6 route del fcff:8::100 encap seg6local action End.DT6 # table 254 dev r8-h83 metric 200 logger.info('*********** Removing decap route on r8') res = handle_srv6_behavior(op='del', channel=r8_chan, segment='fcff:8::100', device='r8-h83', metric=200) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route removed successfully') else: logger.error('*********** Error while removing decap route') # # Encap route on r8 # on r8: ip -6 route del fd00:0:11::/64 encap seg6 mode encap segs # fcff:4::1,fcff:1:100 dev r8-h83 metric 200 logger.info('*********** Removing encap route on r8') res = handle_srv6_path(op='del', channel=r8_chan, destination='fd00:0:11::/64', device='r8-h83', metric=200) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route removed successfully') else: logger.error('*********** Error while removing encap route') # # Decap route on r1 # on r1: ip -6 route del fcff:1::100 encap seg6local action End.DT6 # table 254 dev r1-h11 metric 200 logger.info('*********** Removing decap route on r1') res = handle_srv6_behavior(op='del', channel=r1_chan, segment='fcff:1::100', device='r1-h11', metric=200) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route removed successfully') else: logger.error('*********** Error while removing decap route') # # # +----------------------------------------------------------------+ # | Increasing the metric value of the r7 path | # +----------------------------------------------------------------+ logger.info( '*** Increasing the metric value of the tunnel r1---r7---r8') # # Encap route on r1 # on r1: ip -6 route add fd00:0:83::/64 encap seg6 mode encap segs # fcff:7::1,fcff:8:100 dev r1-h11 metric 200 logger.info('*********** Creating encap route on r1') res = handle_srv6_path(op='add', channel=r1_chan, destination='fd00:0:83::/64', segments=['fcff:7::1', 'fcff:8::100'], device='r1-h11', metric=200) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route created successfully') else: logger.error('*********** Error while creating encap route') # # Decap route on r8 # on r8: ip -6 route add fcff:8::100 encap seg6local action End.DT6 # table 254 dev r8-h83 metric 200 logger.info('*********** Creating decap route on r8') res = handle_srv6_behavior(op='add', channel=r8_chan, segment='fcff:8::100', action='End.DT6', lookup_table=254, device='r8-h83', metric=200) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route created successfully') else: logger.error('*********** Error while creating decap route') # # Encap route on r8 # on r8: ip -6 route add fd00:0:11::/64 encap seg6 mode encap segs # fcff:7::1,fcff:1:100 dev r8-h83 metric 200 logger.info('*********** Creating encap route on r8') res = handle_srv6_path(op='add', channel=r8_chan, destination='fd00:0:11::/64', segments=['fcff:7::1', 'fcff:1::100'], device='r8-h83', metric=200) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route created successfully') else: logger.error('*********** Error while creating encap route') # # Decap route on r1 # on r1: ip -6 route add fcff:1::100 encap seg6local action End.DT6 # table 254 dev r1-h11 metric 200 logger.info('*********** Creating decap route on r1') res = handle_srv6_behavior(op='add', channel=r1_chan, segment='fcff:1::100', action='End.DT6', lookup_table=254, device='r1-h11', metric=200) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route created successfully') else: logger.error('*********** Error while creating decap route') # # # +---------------------------------------------------------------+ # | Removing old route via r7 | # +---------------------------------------------------------------+ logger.info('*** Attempting to remove tunnel r1---r7---r8') # Encap route on r1 # on r1: ip -6 route del fd00:0:83::/64 encap seg6 mode encap segs # fcff:7::1,fcff:8:100 dev r1-h11 metric 100 logger.info('*********** Removing encap route on r1') res = handle_srv6_path(op='del', channel=r1_chan, destination='fd00:0:83::/64', device='r1-h11', metric=100) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route removed successfully') else: logger.error('*********** Error while removing encap route') # # Decap route on r8 # on r8: ip -6 route del fcff:8::100 encap seg6local action End.DT6 # table 254 dev r8-h83 metric 100 logger.info('*********** Removing decap route on r8') res = handle_srv6_behavior(op='del', channel=r8_chan, segment='fcff:8::100', device='r8-h83', metric=100) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route removed successfully') else: logger.error('*********** Error while removing decap route') # # Encap route on r8 # on r8: ip -6 route del fd00:0:11::/64 encap seg6 mode encap segs # fcff:7::1,fcff:1:100 dev r8-h83 metric 100 logger.info('*********** Removing encap route on r8') res = handle_srv6_path(op='del', channel=r8_chan, destination='fd00:0:11::/64', device='r8-h83', metric=100) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route removed successfully') else: logger.error('*********** Error while removing encap route') # # Decap route on r1 # on r1: ip -6 route del fcff:1::100 encap seg6local action End.DT6 # table 254 dev r1-h11 metric 100 logger.info('*********** Removing decap route on r1') res = handle_srv6_behavior(op='del', channel=r1_chan, segment='fcff:1::100', device='r1-h11', metric=100) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route removed successfully') else: logger.error('*********** Error while removing decap route') # # # +---------------------------------------------------------------+ # | Assign to r4 route a definitive value of the metric | # +---------------------------------------------------------------+ logger.info('*** Assign to r4 route a definitive value of the metric') # # Encap route on r1 # on r1: ip -6 route add fd00:0:83::/64 encap seg6 mode encap segs # fcff:4::1,fcff:8:100 dev r1-h11 metric 100 logger.info('*********** Creating encap route on r1') res = handle_srv6_path(op='add', channel=r1_chan, destination='fd00:0:83::/64', segments=['fcff:4::1', 'fcff:8::100'], device='r1-h11', metric=100) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route created successfully') else: logger.error('*********** Error while creating encap route') # # Decap route on r8 # on r8: ip -6 route add fcff:8::100 encap seg6local action End.DT6 # table 254 dev r8-h83 metric 100 logger.info('*********** Creating decap route on r8') res = handle_srv6_behavior(op='add', channel=r8_chan, segment='fcff:8::100', action='End.DT6', lookup_table=254, device='r8-h83', metric=100) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route created successfully') else: logger.error('*********** Error while creating decap route') # # Encap route on r8 # on r8: ip -6 route add fd00:0:11::/64 encap seg6 mode encap segs # fcff:4::1,fcff:1:100 dev r8-h83 metric 100 logger.info('*********** Creating encap route on r8') res = handle_srv6_path(op='add', channel=r8_chan, destination='fd00:0:11::/64', segments=['fcff:4::1', 'fcff:1::100'], device='r8-h83', metric=100) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route created successfully') else: logger.error('*********** Error while creating encap route') # # Decap route on r1 # on r1: ip -6 route add fcff:1::100 encap seg6local action End.DT6 # table 254 dev r1-h11 metric 100 logger.info('*********** Creating decap route on r1') res = handle_srv6_behavior(op='add', channel=r1_chan, segment='fcff:1::100', action='End.DT6', lookup_table=254, device='r1-h11', metric=100) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route created successfully') else: logger.error('*********** Error while creating decap route') # # # +---------------------------------------------------------------+ # | Delete the r4 route with the intermediate value of the metric | # +---------------------------------------------------------------+ logger.info('*** Delete the r4 route with the intermediate value of ' 'the metric') # # Encap route on r1 # on r1: ip -6 route del fd00:0:83::/64 encap seg6 mode encap segs # fcff:4::1,fcff:8:100 dev r1-h11 metric 99 logger.info('*********** Removing encap route on r1') res = handle_srv6_path(op='del', channel=r1_chan, destination='fd00:0:83::/64', device='r1-h11', metric=99) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route removed successfully') else: logger.error('*********** Error while removing encap route') # # Decap route on r8 # on r8: ip -6 route del fcff:8::100 encap seg6local action End.DT6 # table 254 dev r8-h83 metric 99 logger.info('*********** Removing decap route on r8') res = handle_srv6_behavior(op='del', channel=r8_chan, segment='fcff:8::100', device='r8-h83', metric=99) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route removed successfully') else: logger.error('*********** Error while removing decap route') # # Encap route on r8 # on r8: ip -6 route del fd00:0:11::/64 encap seg6 mode encap segs # fcff:4::1,fcff:1:100 dev r8-h83 metric 99 logger.info('*********** Removing encap route on r8') res = handle_srv6_path(op='del', channel=r8_chan, destination='fd00:0:11::/64', device='r8-h83', metric=99) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route removed successfully') else: logger.error('*********** Error while removing encap route') # # Decap route on r1 # on r1: ip -6 route del fcff:1::100 encap seg6local action End.DT6 # table 254 dev r1-h11 metric 99 logger.info('*********** Removing decap route on r1') res = handle_srv6_behavior(op='del', channel=r1_chan, segment='fcff:1::100', device='r1-h11', metric=99) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route removed successfully') else: logger.error('*********** Error while removing decap route') # # # +---------------------------------------------------------------+ # | Done | # +---------------------------------------------------------------+ print()
def remove_tunnel_r1r7r8(): # +--------------------------------------------------------------------+ # | Remove a bidirectional tunnel between h11 and h83 | # | passing through router r7 (r1---r7---r8) | # +--------------------------------------------------------------------+ logger.info('*** Attempting to remove tunnel r1---r7---r8') # IP addresses r1 = 'fcff:1::1' r8 = 'fcff:8::1' # Open gRPC channels with get_grpc_session(r1, GRPC_PORT) as r1_chan, \ get_grpc_session(r8, GRPC_PORT) as r8_chan: # +---------------------------------------------------------------+ # | Remove tunnel from r1 to r8 for fd00:0:83::/64 | # +---------------------------------------------------------------+ logger.info('******* Removing tunnel from r1 to r8 for fd00:0:83::/64') # # Decap route on r8 # on r8: ip -6 route del fcff:8::100 dev r8-h83 metric 100 logger.info('*********** Removing decap route') res = handle_srv6_behavior(op='del', channel=r8_chan, segment='fcff:8::100', device='r8-h83', metric=200) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route removed successfully') else: logger.error('*********** Error while removing decap route') # # Encap route on r1 # on r1: ip -6 route del fd00:0:83::/64 dev r1-h11 metric 100 logger.info('*********** Removing encap route') res = handle_srv6_path(op='del', channel=r1_chan, destination='fd00:0:83::/64', device='r1-h11', metric=200) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route removed successfully') else: logger.error('*********** Error while removing encap route') # # # +---------------------------------------------------------------+ # | Remove tunnel from r8 to r1 for fd00:0:11::/64 | # +---------------------------------------------------------------+ logger.info('******* Removing tunnel from r8 to r1 for fd00:0:11::/64') # # Decap route on r1 # on r1: ip -6 route del fcff:1::100 dev r1-h11 metric 100 logger.info('*********** Removing decap route') res = handle_srv6_behavior(op='del', channel=r1_chan, segment='fcff:1::100', device='r1-h11', metric=200) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Decap route removed successfully') else: logger.error('*********** Error while removing decap route') # # Encap route on r8 # on r8: ip -6 route del fd00:0:11::/64 dev r8-h83 metric 200 logger.info('*********** Removing encap route') res = handle_srv6_path(op='del', channel=r8_chan, destination='fd00:0:11::/64', device='r8-h83', metric=200) if res == srv6_manager_pb2.StatusCode.STATUS_SUCCESS: logger.info('*********** Encap route removed successfully') else: logger.error('*********** Error while removing encap route') # # # +---------------------------------------------------------------+ # | Done | # +---------------------------------------------------------------+ print()