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”: {
}
}
}
}