def __init__(self, sw_name):
     self.topo = load_topo('topology.json')
     self.sw_name = sw_name
     self.thrift_port = self.topo.get_thrift_port(sw_name)
     self.cpu_port = self.topo.get_cpu_port_index(self.sw_name)
     self.controller = SimpleSwitchThriftAPI(self.thrift_port)
     self.init()
Beispiel #2
0
class FillRegisters(object):
    def __init__(self, sw_name):
        self.topo = load_topo('topology.json')
        self.sw_name = sw_name
        self.thrift_port = self.topo.get_thrift_port(sw_name)
        self.controller = SimpleSwitchThriftAPI(self.thrift_port)

    def fill_registers(self):

        for i in range(128):
            self.controller.register_write("recirculate_register", i, i)
Beispiel #3
0
    def reset_states(self):
        """Resets registers, tables, etc.
        """
        for p4rtswitch, controller in self.controllers.items():
            # Reset grpc server
            controller.reset_state()

            # Connect to thrift server
            thrift_port = self.topo.get_thrift_port(p4rtswitch)
            controller_thrift = SimpleSwitchThriftAPI(thrift_port)
            # Reset forwarding states
            controller_thrift.reset_state()
Beispiel #4
0
class ReadCounters(object):
    def __init__(self, sw_name):
        self.topo = load_topo('topology.json')
        self.sw_name = sw_name
        self.thrift_port = self.topo.get_thrift_port(sw_name)
        self.controller = SimpleSwitchThriftAPI(self.thrift_port)

    def direct(self):
        entries = self.controller.table_num_entries('count_table')
        for i in range(0, 4):
            self.controller.counter_read('direct_port_counter', i)

    def indirect(self):
        for i in range(1, 5):
            self.controller.counter_read('port_counter', i)
 def connect_to_switches(self):
     """Connects to all the switches in the topology and saves them
      in self.controllers.
     """
     for p4switch in self.topo.get_p4switches():
         thrift_port = self.topo.get_thrift_port(p4switch)
         self.controllers[p4switch] = SimpleSwitchThriftAPI(thrift_port)
 def reset(self):
     # Reset grpc server
     self.controller.reset_state()
     # Due to a bug in the way the grpc switch reset its states with the message
     # SetForwardingPipelineConfigRequest and Action VERIFY_AND_COMMIT (this is
     # a problem in the implementation of the server), subsequent initializations
     # (i.e. those which happen after the switch reset) of multicast groups
     # (with the same multicast id) are appended to the previous ones
     # (i.e. those present before the reset), which are supposed to be erased by the reset, but
     # they actually are not. This leads to duplicate packets sent to the same port.
     # This seems to be caused by the fact that, even if the grpc server is reset, the
     # switch forwarding states are not completely erased. In order to overcome this,
     # a complete reset can be achieved by resetting the switch via thrift.
     thrift_port = self.topo.get_thrift_port(self.sw_name)
     controller_thrift = SimpleSwitchThriftAPI(thrift_port)
     # Reset forwarding states
     controller_thrift.reset_state()
Beispiel #7
0
 def connect_to_switches(self):
     for p4switch in self.topo.get_p4switches():
         thrift_port = self.topo.get_thrift_port(p4switch)
         self.controllers[p4switch] = SimpleSwitchThriftAPI(thrift_port)
class FloodingController(object):
    def __init__(self, sw_name):
        self.topo = load_topo('topology.json')
        self.sw_name = sw_name
        self.thrift_port = self.topo.get_thrift_port(sw_name)
        self.cpu_port = self.topo.get_cpu_port_index(self.sw_name)
        self.controller = SimpleSwitchThriftAPI(self.thrift_port)
        self.init()

    def init(self):
        self.controller.reset_state()
        self.fill_dmac_table()
        self.add_boadcast_groups()

    def fill_dmac_table(self):
        self.controller.table_add("dmac", "forward", ['00:00:0a:00:00:01'],
                                  ['1'])
        self.controller.table_add("dmac", "forward", ['00:00:0a:00:00:02'],
                                  ['2'])
        self.controller.table_add("dmac", "forward", ['00:00:0a:00:00:03'],
                                  ['3'])
        self.controller.table_add("dmac", "forward", ['00:00:0a:00:00:04'],
                                  ['4'])
        self.controller.table_set_default("dmac", "broadcast", [])

    def add_boadcast_groups(self):
        interfaces_to_port = self.topo.get_node_intfs[
            self.sw_name]["interfaces_to_port"].copy()
        #filter lo and cpu port
        interfaces_to_port.pop('lo', None)
        interfaces_to_port.pop(self.topo.get_cpu_port_intf(self.sw_name), None)

        mc_grp_id = 1
        rid = 0
        for ingress_port in interfaces_to_port.values():

            port_list = list(interfaces_to_port.values())
            del (port_list[port_list.index(ingress_port)])

            #add multicast group
            self.controller.mc_mgrp_create(mc_grp_id)

            #add multicast node group
            handle = self.controller.mc_node_create(rid, port_list)

            #associate with mc grp
            self.controller.mc_node_associate(mc_grp_id, handle)

            #fill broadcast table
            self.controller.table_add("select_mcast_grp", "set_mcast_grp",
                                      [str(ingress_port)], [str(mc_grp_id)])

            mc_grp_id += 1
            rid += 1
Beispiel #9
0
class L2Controller(object):

    def __init__(self, sw_name):
        self.topo = load_topo('topology.json')
        self.sw_name = sw_name
        self.thrift_port = self.topo.get_thrift_port(sw_name)
        self.cpu_port =  self.topo.get_cpu_port_index(self.sw_name)
        self.controller = SimpleSwitchThriftAPI(self.thrift_port)
        self.init()

    def init(self):
        self.controller.reset_state()
        self.add_boadcast_groups()
        self.add_mirror()
        #self.fill_table_test()

    def add_mirror(self):
        if self.cpu_port:
            self.controller.mirroring_add(100, self.cpu_port)

    def add_boadcast_groups(self):
        interfaces_to_port = self.topo.get_node_intfs(fields=['port'])[self.sw_name].copy()
        # Filter lo and cpu port
        interfaces_to_port.pop('lo', None)
        interfaces_to_port.pop(self.topo.get_cpu_port_intf(self.sw_name), None)

        mc_grp_id = 1
        rid = 0
        for ingress_port in interfaces_to_port.values():
            port_list = list(interfaces_to_port.values())
            del(port_list[port_list.index(ingress_port)])
            #add multicast group
            self.controller.mc_mgrp_create(mc_grp_id)
            #add multicast node group
            handle = self.controller.mc_node_create(rid, port_list)
            #associate with mc grp
            self.controller.mc_node_associate(mc_grp_id, handle)
            #fill broadcast table
            self.controller.table_add("broadcast", "set_mcast_grp", [str(ingress_port)], [str(mc_grp_id)])
            mc_grp_id +=1
            rid +=1

    def fill_table_test(self):
        self.controller.table_add("dmac", "forward", ['00:00:0a:00:00:01'], ['1'])
        self.controller.table_add("dmac", "forward", ['00:00:0a:00:00:02'], ['2'])
        self.controller.table_add("dmac", "forward", ['00:00:0a:00:00:03'], ['3'])
        self.controller.table_add("dmac", "forward", ['00:00:0a:00:00:04'], ['4'])

    def learn(self, learning_data):
        for mac_addr, ingress_port in  learning_data:
            print("mac: %012X ingress_port: %s " % (mac_addr, ingress_port))
            self.controller.table_add("smac", "NoAction", [str(mac_addr)])
            self.controller.table_add("dmac", "forward", [str(mac_addr)], [str(ingress_port)])

    def unpack_digest(self, msg, num_samples):
        digest = []
        starting_index = 32
        for sample in range(num_samples):
            mac0, mac1, ingress_port = struct.unpack(">LHH", msg[starting_index:starting_index+8])
            starting_index +=8
            mac_addr = (mac0 << 16) + mac1
            digest.append((mac_addr, ingress_port))
        return digest

    def recv_msg_digest(self, msg):
        topic, device_id, ctx_id, list_id, buffer_id, num = struct.unpack("<iQiiQi",
                                                                          msg[:32])
        digest = self.unpack_digest(msg, num)
        self.learn(digest)
        #Acknowledge digest
        self.controller.client.bm_learning_ack_buffer(ctx_id, list_id, buffer_id)

    def run_digest_loop(self):
        sub = nnpy.Socket(nnpy.AF_SP, nnpy.SUB)
        notifications_socket = self.controller.client.bm_mgmt_get_info().notifications_socket
        sub.connect(notifications_socket)
        sub.setsockopt(nnpy.SUB, nnpy.SUB_SUBSCRIBE, '')
        while True:
            msg = sub.recv()
            self.recv_msg_digest(msg)

    def recv_msg_cpu(self, pkt):
        packet = Ether(raw(pkt))
        if packet.type == 0x1234:
            cpu_header = CpuHeader(bytes(packet.load))
            self.learn([(cpu_header.macAddr, cpu_header.ingress_port)])

    def run_cpu_port_loop(self):
        cpu_port_intf = str(self.topo.get_cpu_port_intf(self.sw_name).replace("eth0", "eth1"))
        sniff(iface=cpu_port_intf, prn=self.recv_msg_cpu)