Looking for where is the LFA?

here I use a mesh topology where there are 2 hosts and 5 switches and I use LFA routing which in the picture on the left tab is the controller and the right is the mininet and when I do the command “fail s1 s2 to s1 s5” an error occurs like below

for the controller code like this
from p4utils.utils.topology import Topology
from p4utils.utils.sswitch_API import SimpleSwitchAPI
from networkx.algorithms import all_pairs_dijkstra
from cli import CLI

class RoutingController(object):

def __init__(self):

    self.topo = Topology(db="topology.db")
    self.controllers = {}
    self.init()

def init(self):
    self.connect_to_switches()
    self.reset_states()
    self.set_table_defaults()

def reset_states(self):
    [controller.reset_state() for controller in self.controllers.values()]

def connect_to_switches(self):
    for p4switch in self.topo.get_p4switches():
        thrift_port = self.topo.get_thrift_port(p4switch)
        self.controllers[p4switch] = SimpleSwitchAPI(thrift_port)

def set_table_defaults(self):
    for controller in self.controllers.values():
        controller.table_set_default("ipv4_lpm", "_drop", [])

def route(self, failures=None):
    switches = {sw_name:{} for sw_name in self.topo.get_p4switches().keys()}
print "switches:", switches
    print "==============================================================================="
    print "self.controllers:", self.controllers
    print "==============================================================================="
       	
    for sw_name, controller in self.controllers.items():
        for sw_dst in self.topo.get_p4switches():

            #if its ourselves we create direct connections
            if sw_name == sw_dst:
                for host in self.topo.get_hosts_connected_to(sw_name):
                    sw_port = self.topo.node_to_node_port_num(sw_name, host)
                    host_ip = self.topo.get_host_ip(host) + "/32"
                    host_mac = self.topo.get_host_mac(host)
		print host, "(", host_ip, host_mac, ")", "-->", sw_name, "with port:", sw_port  

                    #add rule
                    print "table_add at {}:".format(sw_name)
                    self.controllers[sw_name].table_add("ipv4_lpm", "set_nhop", [str(host_ip)], [str(host_mac), str(sw_port)])

            #check if there are directly connected hosts
            else:
                if self.topo.get_hosts_connected_to(sw_dst):
                graph = self.topo.network_graph
                    if failures is not None:
                      graph = graph.copy()
                      for failure in failures:
                        graph.remove_edge(*failure)

                    dijkstra = dict(all_pairs_dijkstra(graph, weight='weight'))
                    distances = {node: data[0] for node, data in dijkstra.items()}
                    all_shortest_paths = {node: data[1] for node, data in dijkstra.items()}
                    #print "all_shortest_paths:", all_shortest_paths
                    paths=all_shortest_paths[sw_name][sw_dst] 
                    print "paths=", paths
           
                    #paths = self.topo.get_shortest_paths_between_nodes(sw_name, sw_dst)
		print sw_name,"->",sw_dst,":",paths
                    for host in self.topo.get_hosts_connected_to(sw_dst):
                        next_hop = paths[1]
		    #next_hop = paths[0][1] #if there are more than one path, choose the first path
                        host_ip = self.topo.get_host_ip(host) + "/24"
                        sw_port = self.topo.node_to_node_port_num(sw_name, next_hop)
                        dst_sw_mac = self.topo.node_to_node_mac(next_hop, sw_name)

                        #add rule
                        print "table_add at {}:".format(sw_name)
                        self.controllers[sw_name].table_add("ipv4_lpm", "set_nhop", [str(host_ip)],
                                                                [str(dst_sw_mac), str(sw_port)])

def failure_notification(self, failures):
    """Called if a link fails.
    Args:
        failures (list(tuple(str, str))): List of failed links.
    """
    fp = open("a.txt", "a")
    print >> fp, "failure_notification() is called, failures=", failures 
    print >> fp, failures[0]
    for sw_name, controller in self.controllers.items():
      self.controllers[sw_name].table_clear("ipv4_lpm")
    self.route(failures)
    fp.close()  

def main(self):
    self.route()

if name == “main”:
controller = RoutingController()
controller.main()
CLI(controller)

and for the topology I made it like this
{
“program”: “ip_forward.p4”,
“switch”: “simple_switch”,
“compiler”: “p4c”,
“options”: “–target bmv2 --arch v1model --std p4-16”,
“switch_cli”: “simple_switch_CLI”,
“cli”: true,
“pcap_dump”: true,
“enable_log”: true,
“topo_module”: {
“file_path”: “”,
“module_name”: “p4utils.mininetlib.apptopo”,
“object_name”: “AppTopoStrategies”
},
“controller_module”: null,
“topodb_module”: {
“file_path”: “”,
“module_name”: “p4utils.utils.topology”,
“object_name”: “Topology”
},
“mininet_module”: {
“file_path”: “”,
“module_name”: “p4utils.mininetlib.p4net”,
“object_name”: “P4Mininet”
},
“topology”: {
“assignment_strategy”: “mixed”,
“auto_arp_tables”: “true”,
“auto_gw_arp”: “true”,
“links”: [[“h1”, “s1”], [“s1”, “s2”], [“s1”, “s3”], [“s1”, “s4”], [“s1”, “s5”], [“s2”, “s5”], [“s5”, “s4”], [“s2”, “s3”], [“s4”, “s3”], [“s5”, “s3”], [“s3”, “h2”]],
“hosts”: {
“h1”: {
},
“h2”: {
}
},
“switches”: {
“s1”: {
},
“s2”: {
},
“s3”: {
},
“s4”: {
},
“s5”: {
}
}
}
}

Hi @Agnesia28,

Please, we would really appreciate if you made a much, much more detailed description of your case and your questions. There are plenty of details that have not been mentioned and, thus, I guess most of us cannot help you yet.

Could you post the actual links? Or a picture of the topology? Or maybe even the Mininet file (attach and format the code or add a link to your git public repo). Sometimes, there is great difference when comparing the topology name or description and the actual links.

Could you describe what LFA routing is? Or provide a link to a description? Is it Topology-Independent Loop-Free Alternate? Does it use segment routing?

Not sure what this actually is. Is this an actual command? Which application? Who has developed the application (maybe a repo)? or have you just removed a link in Mininet?

This is unclear because I only see pings working. Maybe you could post which command you run on mininet.

Which application are you running? Who made the app? Public repository? Are you running it in the tutorial VM? Do you use bmv2? Which command are you running? What is the app supposed to achieve?

Also, could you edit your first question and make sure the code is properly pretty printed? In other words, the formatted text symbols do not cover the entire piece of code.

Thank you so much and have a nice week :slight_smile: