예제 #1
0
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 ipv4_lpm(self,sw):
        for host in self.topo.get_hosts_connected_to("s1"):
            dstip=self.topo.get_host_ip(host)
            shortestways=self.topo.get_shortest_paths_between_nodes(sw, host)
            nhopmac=self.topo.node_to_node_mac(shortestways[0][1],sw)
            nhopport=self.topo.node_to_node_port_num(sw, shortestways[0][1])
            self.controllers[sw].table_add("ipv4_lpm", "set_nhop", [dstip+'/24'],[nhopmac, str(nhopport)])
            print("From switch "+str(sw)+" to host "+str(dstip)+", next hop is "+str(shortestways[0][1])+", egress port is "+str(nhopport)+'\n')

        for sw2 in self.controllers.keys():
            if sw==sw2 :
                continue
            shortestways=self.topo.get_shortest_paths_between_nodes(sw, sw2)
            nhopmac=self.topo.node_to_node_mac(shortestways[0][1],sw)
            nhopport=self.topo.node_to_node_port_num(sw, shortestways[0][1])
            dstip="20.0."+str(sw2[1:])+".0/24"
            self.controllers[sw].table_add("ipv4_lpm", "set_nhop", [dstip],[nhopmac, str(nhopport)])
            print("From switch "+str(sw)+" to switch "+str(sw2)+" at "+str(dstip)+", next hop is "+str(shortestways[0][1])+", egress port is "+str(nhopport)+'\n')
    def op(self,sw):
        self.controllers[sw].table_add("op","NetChain_insert",[str(3)],[])
        self.controllers[sw].table_add("op","NetChain_delete",[str(4)],[])
    def pkt_for_me(self,sw):
        self.controllers[sw].table_add("pkt_for_me", "NoAction", ["20.0."+str(sw[1:])+".0/24",'35678'],[])

    def seq(self,sw):
        self.controllers[sw].table_add("seq","assignseq",[str(0)],[])
                
    def read_write_trans(self,sw):
            self.controllers[sw].table_add("read_write_trans","NetChain_write",["20.0."+str(sw[1:])+".1",str(1)],[])
            self.controllers[sw].table_add("read_write_trans","NetChain_read",["20.0."+str(sw[1:])+".1",str(2)],[])
            self.controllers[sw].table_add("read_write_trans","NetChain_transfer",["20.0."+str(sw[1:])+".1",str(6)],[])
예제 #2
0
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", [])
            controller.table_set_default("ecmp_group_to_nhop", "drop", [])

    def add_mirroring_ids(self):

        for sw_name, controller in self.controllers.items():
            controller.mirroring_add(100, 1)

    def set_egress_type_table(self):

        for sw_name, controller in self.controllers.items():

            for intf, node in self.topo.get_interfaces_to_node(
                    sw_name).items():
                node_type = self.topo.get_node_type(node)
                port_number = self.topo.interface_to_port(sw_name, intf)

                if node_type == 'host':
                    node_type_num = 1
                elif node_type == 'switch':
                    node_type_num = 2

                print "table_add at {}:".format(sw_name)
                self.controllers[sw_name].table_add("egress_type",
                                                    "set_egress_type",
                                                    [str(port_number)],
                                                    [str(node_type_num)])

    def route(self):

        switch_ecmp_groups = {
            sw_name: {}
            for sw_name in self.topo.get_p4switches().keys()
        }

        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)

                        #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):
                        paths = self.topo.get_shortest_paths_between_nodes(
                            sw_name, sw_dst)
                        for host in self.topo.get_hosts_connected_to(sw_dst):

                            if len(paths) == 1:
                                next_hop = paths[0][1]

                                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)])

                            elif len(paths) > 1:
                                next_hops = [x[1] for x in paths]
                                dst_macs_ports = [
                                    (self.topo.node_to_node_mac(
                                        next_hop, sw_name),
                                     self.topo.node_to_node_port_num(
                                         sw_name, next_hop))
                                    for next_hop in next_hops
                                ]
                                host_ip = self.topo.get_host_ip(host) + "/24"

                                #check if the ecmp group already exists. The ecmp group is defined by the number of next
                                #ports used, thus we can use dst_macs_ports as key
                                if switch_ecmp_groups[sw_name].get(
                                        tuple(dst_macs_ports), None):
                                    ecmp_group_id = switch_ecmp_groups[
                                        sw_name].get(tuple(dst_macs_ports),
                                                     None)
                                    print "table_add at {}:".format(sw_name)
                                    self.controllers[sw_name].table_add(
                                        "ipv4_lpm", "ecmp_group",
                                        [str(host_ip)], [
                                            str(ecmp_group_id),
                                            str(len(dst_macs_ports))
                                        ])

                                #new ecmp group for this switch
                                else:
                                    new_ecmp_group_id = len(
                                        switch_ecmp_groups[sw_name]) + 1
                                    switch_ecmp_groups[sw_name][tuple(
                                        dst_macs_ports)] = new_ecmp_group_id

                                    #add group
                                    for i, (mac,
                                            port) in enumerate(dst_macs_ports):
                                        print "table_add at {}:".format(
                                            sw_name)
                                        self.controllers[sw_name].table_add(
                                            "ecmp_group_to_nhop", "set_nhop",
                                            [str(new_ecmp_group_id),
                                             str(i)],
                                            [str(mac), str(port)])

                                    #add forwarding rule
                                    print "table_add at {}:".format(sw_name)
                                    self.controllers[sw_name].table_add(
                                        "ipv4_lpm", "ecmp_group",
                                        [str(host_ip)], [
                                            str(new_ecmp_group_id),
                                            str(len(dst_macs_ports))
                                        ])

    def main(self):
        self.set_egress_type_table()
        self.add_mirroring_ids()
        self.route()
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", [])
            controller.table_set_default("ecmp_group_to_nhop", "drop", [])

    def get_conn_host_infos(self, p4switch):
        connected_hosts = self.topo.get_hosts_connected_to(p4switch)
        if connected_hosts:
            host = connected_hosts[0]
            switch_infos = self.topo.node(p4switch)
            host_mac = self.topo.get_host_mac(host)
            host_ip = self.topo.get_host_ip(host) + '/32'
            output_iface = self.topo.interface_to_port(
                p4switch, switch_infos[host]['intf'])
            return host_ip, host_mac, output_iface
        else:
            return None, None, None

    def add_ecmp_group(self, p4switch, ss_api, neigh, paths, ecmp_group):
        host_ip, host_mac, output_iface = self.get_conn_host_infos(neigh)
        if host_ip:
            next_hops = [path[1] for path in paths]
            dst_macs_ports = [
                (self.topo.node_to_node_mac(next_hop, p4switch),
                 self.topo.node_to_node_port_num(p4switch, next_hop))
                for next_hop in next_hops
            ]
            if ecmp_group.get(p4switch):
                if ecmp_group[p4switch].get(tuple(dst_macs_ports)):
                    ecmp_group[p4switch][tuple(
                        dst_macs_ports
                    )] = ecmp_group[p4switch][tuple(dst_macs_ports)] + 1
                else:
                    ecmp_group[p4switch][tuple(dst_macs_ports)] = 1
            else:
                ecmp_group[p4switch] = {}
                ecmp_group[p4switch][tuple(dst_macs_ports)] = 1

            print('Adding multipath entries')
            ss_api.table_add('ipv4_lpm', 'ecmp_group', [host_ip],
                             [str(1), str(len(next_hops))])
            index = 0
            for dst_mac_port in dst_macs_ports:
                ss_api.table_add(
                    'ecmp_group_to_nhop', 'set_nhop',
                    [str(1), str(index)],
                    [dst_mac_port[0], str(dst_mac_port[1])])
                index = index + 1

        return None

    def add_route_via_best(self, p4switch, ss_api, neigh, path):
        host_ip, host_mac, output_iface = self.get_conn_host_infos(neigh)
        if host_ip:
            neigh_mac = self.topo.node_to_node_mac(neigh, p4switch)
            output_iface = self.topo.node_to_node_port_num(p4switch, neigh)
            print('Add route via best', host_ip, neigh_mac, output_iface)
            ss_api.table_add('ipv4_lpm', 'set_nhop', [host_ip],
                             [neigh_mac, str(output_iface)])

    def add_directly_conn_host(self, p4switch, ss_api):
        host_ip, host_mac, output_iface = self.get_conn_host_infos(p4switch)
        if host_ip:
            print('Add directly connected route ', host_ip, host_mac,
                  output_iface)
            ss_api.table_add('ipv4_lpm', 'set_nhop', [host_ip],
                             [host_mac, str(output_iface)])

    def route(self):
        """implement this function"""
        ecmp_group = {}
        for p4switch, ss_api in self.controllers.items():
            for neigh in self.topo.get_p4switches():
                if p4switch == neigh:
                    # Check if we have connected hosts
                    self.add_directly_conn_host(p4switch, ss_api)
                else:
                    shortest_path = self.topo.get_shortest_paths_between_nodes(
                        p4switch, neigh)
                    if len(shortest_path) < 2:
                        # There is only 1 path
                        self.add_route_via_best(p4switch, ss_api, neigh,
                                                shortest_path)
                    else:
                        # multipath
                        self.add_ecmp_group(p4switch, ss_api, neigh,
                                            shortest_path, ecmp_group)

            #print(self.topo.node(p4switch)['interfaces_to_node'])
            #for iface, neigh in self.topo.node(p4switch)['interfaces_to_node'].items():
            #    print(self.topo.node_to_node_port_num(p4switch, neigh))

    def main(self):
        self.route()
예제 #4
0
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()
        '''
        OPTIONS FOR DEMO
        '''
        self.apply_src_priority = True
        self.apply_dst_priority = False
        self.src_high_priority = 'h1'
        self.src_low_priority = 'h4'
        self.dst_high_priority = 'h5'
        self.dst_low_priority = 'h8'

    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", [])
            controller.table_set_default("ecmp_group_to_nhop", "drop", [])

    def set_tables(self):
        # From project 6
        # Function outside of route() that sets the egress type table

        # loops through all switches
        for sw_name, controller in self.controllers.items():

            # gets the interface and node type
            for interface, node in self.topo.get_interfaces_to_node(
                    sw_name).items():

                node_type = self.topo.get_node_type(node)
                port_number = self.topo.interface_to_port(sw_name, interface)

                # numerates the node types to be put in the table
                if node_type == 'host':
                    node_type_num = 1

                    # NEW - CODE TO SET PRIORITY BASED ON HOST NUMBER
                    host_ip = self.topo.get_host_ip(node) + "/24"
                    priority_num = 2
                    if str(
                            node
                    ) == self.src_high_priority and self.apply_src_priority:
                        priority_num = 1
                    elif str(
                            node
                    ) == self.src_low_priority and self.apply_src_priority:
                        priority_num = 3
                    elif str(
                            node
                    ) == self.dst_high_priority and self.apply_dst_priority:
                        priority_num = 1
                    elif str(
                            node
                    ) == self.dst_low_priority and self.apply_dst_priority:
                        priority_num = 3
                    print "Node name: {}, ip address: {}, priority: {}".format(
                        str(node), str(host_ip), str(priority_num))
                    self.controllers[sw_name].table_add(
                        "priority_type", "set_priority", [str(host_ip)],
                        [str(priority_num)])
                    if self.apply_dst_priority:
                        self.controllers[sw_name].table_add(
                            "priority_type_dst", "set_priority",
                            [str(host_ip)], [str(priority_num)])

                elif node_type == 'switch':
                    node_type_num = 2

                # fills the table
                self.controllers[sw_name].table_add("egress_type", "set_type",
                                                    [str(port_number)],
                                                    [str(node_type_num)])

    def add_mirroring_ids(self):

        for sw_name, controller in self.controllers.items():
            # adding port 1 (it seems like the first argument is standard)
            controller.mirroring_add(100, 1)

    def route(self):

        switch_ecmp_groups = {
            sw_name: {}
            for sw_name in self.topo.get_p4switches().keys()
        }

        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)

                        #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):
                        paths = self.topo.get_shortest_paths_between_nodes(
                            sw_name, sw_dst)
                        for host in self.topo.get_hosts_connected_to(sw_dst):

                            if len(paths) == 1:
                                next_hop = paths[0][1]

                                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)])

                            elif len(paths) > 1:
                                next_hops = [x[1] for x in paths]
                                dst_macs_ports = [
                                    (self.topo.node_to_node_mac(
                                        next_hop, sw_name),
                                     self.topo.node_to_node_port_num(
                                         sw_name, next_hop))
                                    for next_hop in next_hops
                                ]
                                host_ip = self.topo.get_host_ip(host) + "/24"

                                #check if the ecmp group already exists. The ecmp group is defined by the number of next
                                #ports used, thus we can use dst_macs_ports as key
                                if switch_ecmp_groups[sw_name].get(
                                        tuple(dst_macs_ports), None):
                                    ecmp_group_id = switch_ecmp_groups[
                                        sw_name].get(tuple(dst_macs_ports),
                                                     None)
                                    print "table_add at {}:".format(sw_name)
                                    self.controllers[sw_name].table_add(
                                        "ipv4_lpm", "ecmp_group",
                                        [str(host_ip)], [
                                            str(ecmp_group_id),
                                            str(len(dst_macs_ports))
                                        ])

                                #new ecmp group for this switch
                                else:
                                    new_ecmp_group_id = len(
                                        switch_ecmp_groups[sw_name]) + 1
                                    switch_ecmp_groups[sw_name][tuple(
                                        dst_macs_ports)] = new_ecmp_group_id

                                    #add group
                                    for i, (mac,
                                            port) in enumerate(dst_macs_ports):
                                        print "table_add at {}:".format(
                                            sw_name)
                                        self.controllers[sw_name].table_add(
                                            "ecmp_group_to_nhop", "set_nhop",
                                            [str(new_ecmp_group_id),
                                             str(i)],
                                            [str(mac), str(port)])

                                    #add forwarding rule
                                    print "table_add at {}:".format(sw_name)
                                    self.controllers[sw_name].table_add(
                                        "ipv4_lpm", "ecmp_group",
                                        [str(host_ip)], [
                                            str(new_ecmp_group_id),
                                            str(len(dst_macs_ports))
                                        ])

    def main(self):
        self.set_tables()
        self.add_mirroring_ids()
        self.route()
예제 #5
0
class FlowtableManager(object):
    def __init__(self):
        self.topo = Topology(db='topology.db')
        dic = self.topo.get_p4switches()
        self.sw_name = [sw for sw in dic.keys()]
        self.controller = {
            sw: SimpleSwitchAPI(self.topo.get_thrift_port(sw))
            for sw in self.sw_name
        }
        self.multicast_table = dict()

    def add_forward_table(self):
        host_list = [h for h in self.topo.get_hosts().keys()]
        for src in self.sw_name:
            self.controller[src].table_set_default('ingress.ipv4_c.ipv4',
                                                   'drop', [])
            direct_sw_list = self.topo.get_switches_connected_to(src)
            for sw in direct_sw_list:
                port = self.topo.node_to_node_port_num(src, sw)
                self.controller[src].table_add(
                    'egress.mac_c.adjust_mac', 'set_mac', [str(port)], [
                        str(self.topo.node_to_node_mac(src, sw)),
                        str(self.topo.node_to_node_mac(sw, src))
                    ])
            direct_host_list = self.topo.get_hosts_connected_to(src)
            for h in direct_host_list:
                ip = self.topo.get_host_ip(h)
                port = self.topo.node_to_node_port_num(src, h)
                self.controller[src].table_add('ingress.ipv4_c.ipv4',
                                               'forward', [str(ip) + '/32'],
                                               [str(port)])
                self.controller[src].table_add(
                    'egress.mac_c.adjust_mac', 'set_mac', [str(port)], [
                        str(self.topo.node_to_node_mac(src, h)),
                        str(self.topo.node_to_node_mac(h, src))
                    ])
            indirect_host_list = list(
                set(host_list).difference(direct_host_list))
            for h in indirect_host_list:
                ip = self.topo.get_host_ip(h)
                path = self.topo.get_shortest_paths_between_nodes(src, h)[0]
                port = self.topo.node_to_node_port_num(src, path[1])
                self.controller[src].table_add('ingress.ipv4_c.ipv4',
                                               'forward', [str(ip) + '/32'],
                                               [str(port)])

    def add_multicast_table(self):
        for sw in self.sw_name:
            self.multicast_table.update({sw: {}})
            port = self.topo.get_interfaces_to_port(sw)
            num = len(port) - 1
            if sw + '-cpu-eth0' in port.keys():
                num -= 1
            self.controller[sw].mc_mgrp_create('1')
            for i in range(int(comb(num, 2))):
                self.controller[sw].mc_mgrp_create(str(i + 2))
            port_list = []
            for i in range(num):
                port_list.append(str(i + 1))
            self.controller[sw].mc_node_create('0', port_list)
            self.controller[sw].mc_node_associate('1', '0')
            n = 2
            for i in range(num):
                for j in range(i + 1, num):
                    port_list = [str(i + 1), str(j + 1)]
                    self.controller[sw].mc_node_create(str(n - 1), port_list)
                    self.controller[sw].mc_node_associate(str(n), str(n - 1))
                    self.multicast_table[sw].update({
                        (str(i + 1), str(j + 1)): n
                    })
                    n += 1

    def add_forward_entry(self, sw, ip, port):
        try:
            self.controller[sw].table_add('ingress.ipv4_c.ipv4', 'forward',
                                          [str(ip)], [str(port)])
        except:
            print('add_forward_entry error')

    def add_l3_entry(self, sw, act=[], key=[]):
        try:
            self.controller[sw].table_add('ingress.ipv4_c.l3_match_to_index',
                                          'protect', key, act)
        except:
            print('add_l3_entry error')
예제 #6
0
class GenFault(object):
    def __init__(self, program):
        if program == "f":
            self.topo = Topology(
                db="../p4src_flowsize/topology.db")  #set the topology
        elif program == "i":
            self.topo = Topology(
                db="../p4src_interval/topology.db")  #set the topology
        self.controllers = {}  #the switches
        self.init()

    def init(self):
        self.connect_to_switches()

    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 loop(self):
        switches = raw_input(
            "type the switch's name to gen loop,seperated by ','\nmust be physically loop-able:\n"
        ).split(',')

        IPs = []
        for sw_name in self.controllers.keys():
            for host in self.topo.get_hosts_connected_to(sw_name):
                host_ip = self.topo.get_host_ip(host) + "/24"
                IPs.append(host_ip)

        for i in range(len(switches)):
            sw_name = switches[i]
            self.controllers[sw_name].table_clear("ecmp_group_to_nhop")
            self.controllers[sw_name].table_clear("ipv4_lpm")

            #next_hop=NULL
            if i == len(switches) - 1:
                next_hop = switches[0]
            else:
                next_hop = switches[i + 1]

            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)
            #print "table_add at {}:".format(sw_name)
            for host_ip in IPs:
                self.controllers[sw_name].table_add("ipv4_lpm", "set_nhop", [str(host_ip)],\
                                [str(dst_sw_mac), str(sw_port)])

    def blackhole(self, args):
        if args.sw_name == None:
            pass
            print "Not implemented yet,please specify the switch name"
        else:
            self.controllers[args.sw_name].table_clear("ecmp_group_to_nhop")
            self.controllers[args.sw_name].table_clear("ipv4_lpm")
            print args.sw_name, "has been shut down"

    def remove_cpu(self):
        # log=open("./router.log","w")
        # log.write(str(self.topo))

        print(1)
        print(self.topo.get_shortest_paths_between_nodes("s5", "h2"))
        # print(self.topo["sw-cpu"])
        # print(self.topo.network_graph["sw-cpu"])

        self.topo.network_graph.remove_node("sw-cpu")
        # self.topo.save("../p4src_interval/topology.db")
        # self.topo.load("../p4src_interval/topology.db")
        # del self.topo
        #self.topo=Topology(db="../p4src_interval/topology.db")
        print("\n\n\n\n\n")

        print(2)
        print(self.topo.get_shortest_paths_between_nodes("h1", "h8"))

        # print(self.topo["sw-cpu"])
        # print(self.topo.network_graph["sw-cpu"])

        # log=open("./router1.log","w")
        # log.write(str(self.topo))

    def reroute(self):
        #log=open("./router.log","w")
        #log.write(str(self.topo))
        self.topo.network_graph.remove_node("sw-cpu")
        switch_ecmp_groups = {
            sw_name: {}
            for sw_name in self.topo.get_p4switches().keys()
        }
        for sw_name, controllers in self.controllers.items():
            controllers.table_clear("ecmp_group_to_nhop")
            controllers.table_clear("ipv4_lpm")
            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)

                        #add rule
                        print "table_add at {}:".format(sw_name)
                        # log.write("[1] table_add ipv4_lpm set_nhop at {} to host {} using port {}\n".format(sw_name,host,sw_port))
                        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):
                        paths = self.topo.get_shortest_paths_between_nodes(
                            sw_name, sw_dst)
                        for host in self.topo.get_hosts_connected_to(sw_dst):

                            if len(paths) == 1:
                                next_hop = paths[0][1]

                                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)
                                # log.write("[2] table_add ipv4_lpm set_nhop at {} to host {} using port {} to nexthop {}\n".format(sw_name,host,sw_port,next_hop))
                                self.controllers[sw_name].table_add(
                                    "ipv4_lpm", "set_nhop", [str(host_ip)],
                                    [str(dst_sw_mac),
                                     str(sw_port)])

                            elif len(paths) > 1:
                                next_hops = [x[1] for x in paths]
                                dst_macs_ports = [
                                    (self.topo.node_to_node_mac(
                                        next_hop, sw_name),
                                     self.topo.node_to_node_port_num(
                                         sw_name, next_hop))
                                    for next_hop in next_hops
                                ]
                                host_ip = self.topo.get_host_ip(host) + "/24"

                                #check if the ecmp group already exists. The ecmp group is defined by the number of next
                                #ports used, thus we can use dst_macs_ports as key
                                if switch_ecmp_groups[sw_name].get(
                                        tuple(dst_macs_ports), None):
                                    ecmp_group_id = switch_ecmp_groups[
                                        sw_name].get(tuple(dst_macs_ports),
                                                     None)
                                    print "table_add at {}:".format(sw_name)
                                    # log.write("[3] table_add ipv4_lpm ecmp_group at {} to switch {} to paths{}\n".format(sw_name,sw_dst,paths))
                                    self.controllers[sw_name].table_add(
                                        "ipv4_lpm", "ecmp_group",
                                        [str(host_ip)], [
                                            str(ecmp_group_id),
                                            str(len(dst_macs_ports))
                                        ])

                                #new ecmp group for this switch
                                else:
                                    new_ecmp_group_id = len(
                                        switch_ecmp_groups[sw_name]) + 1
                                    switch_ecmp_groups[sw_name][tuple(
                                        dst_macs_ports)] = new_ecmp_group_id

                                    #add group
                                    for i, (mac,
                                            port) in enumerate(dst_macs_ports):
                                        print "table_add at {}:".format(
                                            sw_name)
                                        #log.write("[4] table_add ipv4_lpm ecmp_group at {} to switch {} to paths{}\n".format(sw_name,sw_dst,paths))
                                        # log.write("[4] table_add ipv4_lpm ecmp_group at {} to switch {} using port {}\n".format(sw_name,sw_dst,port))
                                        self.controllers[sw_name].table_add(
                                            "ecmp_group_to_nhop", "set_nhop",
                                            [str(new_ecmp_group_id),
                                             str(i)],
                                            [str(mac), str(port)])

                                    #add forwarding rule
                                    print "table_add at {}:".format(sw_name)
                                    # log.write("[5] table_add ipv4_lpm ecmp_group at {} to switch {} to paths{}\n".format(sw_name,sw_dst,paths))

                                    self.controllers[sw_name].table_add(
                                        "ipv4_lpm", "ecmp_group",
                                        [str(host_ip)], [
                                            str(new_ecmp_group_id),
                                            str(len(dst_macs_ports))
                                        ])
예제 #7
0
class Controller(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 install_rules(self):

        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)

                        #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):
                        paths = self.topo.get_shortest_paths_between_nodes(
                            sw_name, sw_dst)
                        for host in self.topo.get_hosts_connected_to(sw_dst):
                            next_hop = paths[0][1]
                            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 main(self):
        self.install_rules()
예제 #8
0
class RoutingController(object):

    def __init__(self):
        self.topo = Topology(db="./topology.db")  #set the topology
        self.controllers = {}                   #the switches
        self.custom_calcs={}
        self.register_num={}
        self.registers={}
        self.init()

        

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

        self.set_crc_custom_hashes()

    
    

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

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

    def set_table_defaults(self):
        for controllers in self.controllers.values():
            controllers.table_set_default("ipv4_lpm", "drop", [])
            controllers.table_set_default("ecmp_group_to_nhop", "drop", [])
    
    def set_custom_calcs(self):
        for p4switch in self.topo.get_p4switches():
            self.custom_calcs[p4switch]=self.controllers[p4switch].get_custom_crc_calcs()
            self.register_num[p4switch] =len(self.custom_calcs[p4switch])     

    def reset_all_registers(self):
        for sw, controller in self.controllers.items():
            for register in controller.get_register_arrays():
                controller.register_reset(register)

 

    def set_crc_custom_hashes(self):
        for sw_name in self.controllers.keys():
            i = 0
            for custom_crc32, width in sorted(self.custom_calcs[sw_name].items()):
                self.controllers[sw_name].set_crc32_parameters(custom_crc32, crc32_polinomials[i], 0xffffffff, 0xffffffff, True, True)
                i+=1

   
    


    def route(self):

        switch_ecmp_groups = {sw_name:{} for sw_name in self.topo.get_p4switches().keys()}
        # self.topo.network_graph.remove_node("sw-cpu")

        for sw_name, controllers 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)

                        #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):
                        paths = self.topo.get_shortest_paths_between_nodes(sw_name, sw_dst)
                        for host in self.topo.get_hosts_connected_to(sw_dst):

                            if len(paths) == 1:
                                next_hop = paths[0][1]

                                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)])

                            elif len(paths) > 1:
                                next_hops = [x[1] for x in paths]
                                dst_macs_ports = [(self.topo.node_to_node_mac(next_hop, sw_name),
                                                   self.topo.node_to_node_port_num(sw_name, next_hop))
                                                  for next_hop in next_hops]
                                host_ip = self.topo.get_host_ip(host) + "/24"

                                #check if the ecmp group already exists. The ecmp group is defined by the number of next
                                #ports used, thus we can use dst_macs_ports as key
                                if switch_ecmp_groups[sw_name].get(tuple(dst_macs_ports), None):
                                    ecmp_group_id = switch_ecmp_groups[sw_name].get(tuple(dst_macs_ports), None)
                                    print "table_add at {}:".format(sw_name)
                                    self.controllers[sw_name].table_add("ipv4_lpm", "ecmp_group", [str(host_ip)],
                                                                        [str(ecmp_group_id), str(len(dst_macs_ports))])

                                #new ecmp group for this switch
                                else:
                                    new_ecmp_group_id = len(switch_ecmp_groups[sw_name]) + 1
                                    switch_ecmp_groups[sw_name][tuple(dst_macs_ports)] = new_ecmp_group_id

                                    #add group
                                    for i, (mac, port) in enumerate(dst_macs_ports):
                                        print "table_add at {}:".format(sw_name)
                                        self.controllers[sw_name].table_add("ecmp_group_to_nhop", "set_nhop",
                                                                            [str(new_ecmp_group_id), str(i)],
                                                                            [str(mac), str(port)])

                                    #add forwarding rule
                                    print "table_add at {}:".format(sw_name)
                                    self.controllers[sw_name].table_add("ipv4_lpm", "ecmp_group", [str(host_ip)],
                                                                        [str(new_ecmp_group_id), str(len(dst_macs_ports))])
		




    def main(self):
        self.route()

        # for switch_id, controller in enumerate(self.controllers.values()):
            # controller.register_write("switch_id", 0, switch_id)
            # controller.register_write("swap_control", 0, 0)
            # controller.register_write("sketch_fg", 0, 0)
            # controller.register_write("previous_ingress_timestamp", 0, 0)

        for switch_id, switch_name in enumerate(self.controllers.keys()):
            print "{} {}".format(switch_id, switch_name)