class LearningSwitchControllerApp(object): def __init__(self, switchName): self.topo = Topology(db="topology.db") self.switchName = switchName self.thrift_port = self.topo.get_thrift_port(switchName) self.cpu_port = self.topo.get_cpu_port_index(self.switchName) self.controller = SimpleSwitchAPI(self.thrift_port) self.init() def init(self): self.controller.reset_state() self.add_mcast_grp() self.add_mirror() def add_mirror(self): if self.cpu_port: self.controller.mirroring_add(MIRROR_SESSION_ID, self.cpu_port) def add_mcast_grp(self): interfaces_to_port = self.topo[self.switchName]["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.switchName), None) mc_grp_id = 1 rid = 0 # add multicast group self.controller.mc_mgrp_create(mc_grp_id) port_list = interfaces_to_port.values()[:] # 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) def learn(self, learningData): for macAddr, ingressPort in learningData: print("macAddr: %012X ingressPort: %s ", macAddr, ingressPort) self.controller.table_add("srcMacAddr", "NoAction", [str(macAddr)]) self.controller.table_add("dstMacAddr", "forward", [ str(macAddr)], [str(ingressPort)]) def recv_msg_cpu(self, pkt): packet = Ether(str(pkt)) if packet.type == L2_LEARN_ETHER_TYPE: cpu_header = CpuHeader(bytes(packet.payload)) self.learn([(cpu_header.macAddr, cpu_header.ingressPort)]) def run_cpu_port_loop(self): cpu_port_intf = str(self.topo.get_cpu_port_intf( self.switchName).replace("eth0", "eth1")) sniff(iface=cpu_port_intf, prn=self.recv_msg_cpu)
class FloodingController(object): def __init__(self, sw_name): self.topo = Topology(db="topology.db") 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 = SimpleSwitchAPI(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[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 = 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
class L2Controller(object): def __init__(self, sw_name): self.topo = Topology(db="topology.db") 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 = SimpleSwitchAPI(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[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 = 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 = [] print len(msg), num_samples 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(str(pkt)) if packet.type == 0x1234: cpu_header = CpuHeader(packet.payload) 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)
class L2Controller(object): def __init__(self, sw_name): self.topo = Topology(db="topology.db") 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 = SimpleSwitchAPI(self.thrift_port) self.init() def init(self): self.controller.reset_state() self.add_boadcast_groups() self.add_mirror() 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[ 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 = 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 learn_route(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 learn_connection(self, srcA, dstA, srcP, dstP): print("========== UPDATING CONNECTION ==========") connection = srcA connection = connection << 32 connection = connection | dstA connection = connection << 16 connection = connection | srcP connection = connection << 16 connection = connection | dstP self.controller.table_add("tcp_forward", "NoAction", [str(connection)], []) connection = dstA connection = connection << 32 connection = connection | srcA connection = connection << 16 connection = connection | dstP connection = connection << 16 connection = connection | srcP self.controller.table_add("tcp_forward", "NoAction", [str(connection)], []) print("========== UPDATE FINISHED ==========") def recv_msg_cpu(self, pkt): packet = Ether(str(pkt)) if packet.type == 0x1234: learning = CpuRoute(packet.payload) print("got a packet of type route") self.learn_route([(learning.macAddr, learning.ingress_port)]) if packet.type == 0xF00D: learning = CpuCookie(packet.payload) print("got a packet of type cookie") self.learn_connection(learning.srcAddr, learning.dstAddr, learning.srcPort, learning.dstPort) 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)