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 = 9090 #self.thrift_port = self.topo.get_thrift_port(sw_name) #self.cpu_port = self.topo.get_cpu_port_index(self.sw_name) self.cpu_port = 2 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 read_register(self): ns_recv = self.controller.register_read("ns_recv") na_recv = self.controller.register_read("na_recv") ns_filter = self.controller.register_read("ns_filter") na_filter = self.controller.register_read("na_filter") ns_recv_no_zero = [] for x in ns_recv: if x != 0: ns_recv_no_zero.append(x) na_recv_no_zero = [] for x in na_recv: if x != 0: na_recv_no_zero.append(x) ns_filter_no_zero = [] for x in ns_filter: if x != 0: ns_filter_no_zero.append(x) na_filter_no_zero = [] for x in na_filter: if x != 0: na_filter_no_zero.append(x) print "ns_recv: ", len(ns_recv_no_zero), ns_recv_no_zero print "ns_filter: ", len(ns_filter_no_zero), ns_filter_no_zero print "na_recv: ", len(na_recv_no_zero), na_recv_no_zero print "na_filter: ", len(na_filter_no_zero), na_filter_no_zero
class L2Controller(object): def __init__(self, sw_name): self.sw_name = sw_name self.thrift_port = 9090 self.cpu_port = 2 self.controller = SimpleSwitchAPI(self.thrift_port) self.init() def init(self): self.controller.reset_state() self.add_mirror() def add_mirror(self): if self.cpu_port: self.controller.mirroring_add(100, self.cpu_port) def fill_mac_query_table_test(self): self.controller.table_add("mac_forward", "modify_egress_spec", ['00:00:0a:00:00:01'], ['1']) self.controller.table_add("mac_forward", "modify_egress_spec", ['00:00:0a:00:00:02'], ['2']) self.controller.table_add("mac_forward", "modify_egress_spec", ['00:00:0a:00:00:03'], ['3']) self.controller.table_add("mac_forward", "modify_egress_spec", ['00:00:0a:00:00:04'], ['4']) def mac_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("mac_query", "set_mac_in", [str(mac_addr)]) self.controller.table_add("mac_forward", "modify_egress_spec", [str(mac_addr)], [str(ingress_port)]) def ipv6_learn(self, learning_data): for target_address, index in learning_data: print "target_address: %012X index: %s " % (target_address, index) self.controller.table_add("target_address_query", "set_target_address_in", [str(target_address)], [str(index)]) 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) print "digest:", digest, " digest len:", len(digest) self.mac_learn(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) sub.connect('ipc:///tmp/bmv2-0-notifications.ipc') sub.setsockopt(nnpy.SUB, nnpy.SUB_SUBSCRIBE, '') print "run_digest_loop" while True: msg = sub.recv() #print "msg:",msg 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.mac_learn([(cpu_header.macAddr, cpu_header.ingress_port)]) def run_cpu_port_loop(self): cpu_port_intf = "docker0" 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() #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 BlinkController: def __init__(self, topo_db, sw_name, ip_controller, port_controller, log_dir, \ monitoring=True, routing_file=None): self.topo = Topology(db=topo_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.controller.reset_state() self.log_dir = log_dir print 'connecting to ', ip_controller, port_controller # Socket used to communicate with the controller self.sock_controller = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = (ip_controller, port_controller) self.sock_controller.connect(server_address) print 'Connected!' # Send the switch name to the controller self.sock_controller.sendall(str(sw_name)) self.make_logging() if monitoring: # Monitoring scheduler self.t_sched = sched_timer.RepeatingTimer(10, 0.5, self.scheduling) self.t_sched.start() self.mapping_dic = {} tmp = list(self.topo.get_hosts()) + list(self.topo.get_p4switches()) self.mapping_dic = {k: v for v, k in enumerate(tmp)} self.log.info(str(self.mapping_dic)) self.routing_file = routing_file print 'routing_file ', routing_file if self.routing_file is not None: json_data = open(self.routing_file) self.topo_routing = json.load(json_data) def make_logging(self): # Logger for the pipeline logger.setup_logger('p4_to_controller', self.log_dir+'/p4_to_controller_'+ \ str(self.sw_name)+'.log', level=logging.INFO) self.log = logging.getLogger('p4_to_controller') # Logger for the sliding window logger.setup_logger('p4_to_controller_sw', self.log_dir+'/p4_to_controller_'+ \ str(self.sw_name)+'_sw.log', level=logging.INFO) self.log_sw = logging.getLogger('p4_to_controller_sw') # Logger for the rerouting logger.setup_logger('p4_to_controller_rerouting', self.log_dir+'/p4_to_controller_'+ \ str(self.sw_name)+'_rerouting.log', level=logging.INFO) self.log_rerouting = logging.getLogger('p4_to_controller_rerouting') # Logger for the Flow Selector logger.setup_logger('p4_to_controller_fs', self.log_dir+'/p4_to_controller_'+ \ str(self.sw_name)+'_fs.log', level=logging.INFO) self.log_fs = logging.getLogger('p4_to_controller_fs') def scheduling(self): for host in list(self.topo.get_hosts()): prefix = self.topo.get_host_ip(host) + '/24' # Print log about the sliding window for id_prefix in [ self.mapping_dic[host] * 2, self.mapping_dic[host] * 2 + 1 ]: with HiddenPrints(): sw_time = float( self.controller.register_read('sw_time', index=id_prefix)) / 1000. sw_index = self.controller.register_read('sw_index', index=id_prefix) sw_sum = self.controller.register_read('sw_sum', index=id_prefix) self.log_sw.info('sw_time\t' + host + '\t' + prefix + '\t' + str(id_prefix) + '\t' + str(sw_time)) self.log_sw.info('sw_index\t' + host + '\t' + prefix + '\t' + str(id_prefix) + '\t' + str(sw_index)) if sw_sum >= 32: self.log_sw.info('sw_sum\t' + host + '\t' + prefix + '\t' + str(id_prefix) + '\t' + str(sw_sum) + '\tREROUTING') else: self.log_sw.info('sw_sum\t' + host + '\t' + prefix + '\t' + str(id_prefix) + '\t' + str(sw_sum)) sw = [] tmp = 'sw ' + host + ' ' + prefix + ' ' + str(id_prefix) + '\t' for i in range(0, 10): with HiddenPrints(): binvalue = int( self.controller.register_read( 'sw', (id_prefix * 10) + i)) tmp = tmp + str(binvalue) + ',' sw.append(binvalue) tmp = tmp[:-1] self.log_sw.info(str(tmp)) # Print log about rerouting for host in list(self.topo.get_hosts()): prefix = self.topo.get_host_ip(host) + '/24' for id_prefix in [ self.mapping_dic[host] * 2, self.mapping_dic[host] * 2 + 1 ]: with HiddenPrints(): nh_avaibility_1 = self.controller.register_read( 'nh_avaibility_1', index=id_prefix) nh_avaibility_2 = self.controller.register_read( 'nh_avaibility_2', index=id_prefix) nh_avaibility_3 = self.controller.register_read( 'nh_avaibility_3', index=id_prefix) nbflows_progressing_2 = self.controller.register_read( 'nbflows_progressing_2', index=id_prefix) nbflows_progressing_3 = self.controller.register_read( 'nbflows_progressing_3', index=id_prefix) rerouting_ts = self.controller.register_read( 'rerouting_ts', index=id_prefix) threshold = self.controller.register_read( 'threshold_registers', index=id_prefix) self.log_rerouting.info('nh_avaibility\t'+host+'\t'+prefix+'\t'+ \ str(id_prefix)+'\t'+str(nh_avaibility_1)+'\t'+ \ str(nh_avaibility_2)+'\t'+str(nh_avaibility_3)) self.log_rerouting.info('nblows_progressing\t'+host+'\t'+prefix+'\t'+ \ str(id_prefix)+'\t'+str(nbflows_progressing_2)+'\t'+ \ str(nbflows_progressing_3)) self.log_rerouting.info('rerouting_ts\t'+host+'\t'+prefix+'\t'+ \ str(id_prefix)+'\t'+str(rerouting_ts)) self.log_rerouting.info('threshold\t'+host+'\t'+prefix+'\t'+ \ str(id_prefix)+'\t'+str(threshold)) nexthop_str = '' nha = [nh_avaibility_1, nh_avaibility_2, nh_avaibility_3] i = 0 if self.routing_file is not None: bgp_type = 'customer' if id_prefix % 2 == 0 else 'customer_provider_peer' if bgp_type not in self.topo_routing['switches'][ self.sw_name]['prefixes'][host]: nexthop_str = 'NoPathAvailable' else: if len(self.topo_routing['switches'][self.sw_name] ['prefixes'][host][bgp_type]) == 2: self.topo_routing['switches'][self.sw_name][ 'prefixes'][host][bgp_type].append( self.topo_routing['switches'][self.sw_name] ['prefixes'][host][bgp_type][-1]) for nexthop in self.topo_routing['switches'][ self.sw_name]['prefixes'][host][bgp_type]: tmp = 'y' if nha[i] == 0 else 'n' nexthop_str = nexthop_str + str( nexthop) + '(' + tmp + ')\t' i += 1 nexthop_str = nexthop_str[:-1] self.log_rerouting.info('nexthop\t'+host+'\t'+prefix+'\t'+ \ str(id_prefix)+'\t'+str(nexthop_str)) # Print log about the flow selector for host in list(self.topo.get_hosts()): prefix = self.topo.get_host_ip(host) + '/24' for id_prefix in [ self.mapping_dic[host] * 2, self.mapping_dic[host] * 2 + 1 ]: sw = [] tmp = 'fs_key ' + host + ' ' + prefix + ' ' + str( id_prefix) + '\t' for i in range(0, 64): with HiddenPrints(): binvalue = int( self.controller.register_read( 'flowselector_key', 64 * id_prefix + i)) tmp = tmp + str(binvalue) + ',' sw.append(binvalue) tmp = tmp[:-1] self.log_fs.info(str(tmp)) sw = [] tmp = 'fs ' + host + ' ' + prefix + ' ' + str(id_prefix) + '\t' for i in range(0, 64): with HiddenPrints(): binvalue = int( self.controller.register_read( 'flowselector_ts', 64 * id_prefix + i)) tmp = tmp + str(binvalue) + ',' sw.append(binvalue) tmp = tmp[:-1] self.log_fs.info(str(tmp)) sw = [] tmp = 'fs_last_ret ' + host + ' ' + prefix + ' ' + str( id_prefix) + '\t' for i in range(0, 64): with HiddenPrints(): binvalue = int( self.controller.register_read( 'flowselector_last_ret', 64 * id_prefix + i)) tmp = tmp + str(binvalue) + ',' sw.append(binvalue) tmp = tmp[:-1] self.log_fs.info(str(tmp)) sw = [] tmp = 'fs_last_ret_bin ' + host + ' ' + prefix + ' ' + str( id_prefix) + '\t' for i in range(0, 64): with HiddenPrints(): binvalue = int( self.controller.register_read( 'flowselector_last_ret_bin', 64 * id_prefix + i)) tmp = tmp + str(binvalue) + ',' sw.append(binvalue) tmp = tmp[:-1] self.log_fs.info(str(tmp)) sw = [] tmp = 'fs_fwloops ' + host + ' ' + prefix + ' ' + str( id_prefix) + '\t' for i in range(0, 64): with HiddenPrints(): binvalue = int( self.controller.register_read( 'flowselector_fwloops', 64 * id_prefix + i)) tmp = tmp + str(binvalue) + ',' sw.append(binvalue) tmp = tmp[:-1] self.log_fs.info(str(tmp)) sw = [] tmp = 'fs_correctness ' + host + ' ' + prefix + ' ' + str( id_prefix) + '\t' for i in range(0, 64): with HiddenPrints(): binvalue = int( self.controller.register_read( 'flowselector_correctness', 64 * id_prefix + i)) tmp = tmp + str(binvalue) + ',' sw.append(binvalue) tmp = tmp[:-1] self.log_fs.info(str(tmp)) def forwarding(self): p4switches = self.topo.get_p4switches() interfaces_to_node = p4switches[self.sw_name]['interfaces_to_node'] for k, v in interfaces_to_node.items(): try: dst_mac = self.topo.get_hosts()[v][self.sw_name]['mac'] except KeyError: dst_mac = self.topo.get_p4switches()[v][self.sw_name]['mac'] src_mac = p4switches[self.sw_name][v]['mac'] outport = p4switches[self.sw_name]['interfaces_to_port'][ p4switches[self.sw_name][v]['intf']] self.log.info('table add send set_nh ' + str(self.mapping_dic[v]) + ' => ' + str(outport) + ' ' + str(src_mac) + ' ' + str(dst_mac)) self.controller.table_add( 'send', 'set_nh', [str(self.mapping_dic[v])], [str(outport), str(src_mac), str(dst_mac)]) def run(self): sock_list = [self.sock_controller] controller_data = '' while True: inready, outready, excepready = select.select(sock_list, [], []) for sock in inready: if sock == self.sock_controller: data_tmp = '' toreturn = None try: data_tmp = sock.recv(100000000) except socket.error, e: err = e.args[0] if not (err == errno.EAGAIN or err == errno.EWOULDBLOCK): print 'p4_to_controller: ', e sock.close() sock = None if len(data_tmp) > 0: controller_data += data_tmp next_data = '' while len(controller_data ) > 0 and controller_data[-1] != '\n': next_data = controller_data[-1] + next_data controller_data = controller_data[:-1] toreturn = controller_data controller_data = next_data if toreturn is not None: for line in toreturn.split('\n'): if line.startswith('table add '): line = line.rstrip('\n').replace( 'table add ', '') fwtable_name = line.split(' ')[0] action_name = line.split(' ')[1] match_list = line.split(' => ')[0].split( ' ')[2:] action_list = line.split(' => ')[1].split(' ') print line print fwtable_name, action_name, match_list, action_list self.log.info(line) self.controller.table_add(fwtable_name, action_name, \ match_list, action_list) if line.startswith('do_register_write'): line = line.rstrip('\n') linetab = line.split(' ') register_name = linetab[1] index = int(linetab[2]) value = int(linetab[3]) self.log.info(line) self.controller.register_write(register_name, \ index, value) if line.startswith('reset_states'): self.log.info('RESETTING_STATES') # First stop the scheduler to avoid concurrent used # of the Thirft server self.t_sched.cancel() while self.t_sched.running: # Wait the end of the log printing time.sleep(0.5) time.sleep(1) # Reset the state of the switch self.controller.register_reset( 'nh_avaibility_1') self.controller.register_reset( 'nh_avaibility_2') self.controller.register_reset( 'nh_avaibility_3') self.controller.register_reset( 'nbflows_progressing_2') self.controller.register_reset( 'nbflows_progressing_3') self.controller.register_reset('rerouting_ts') self.controller.register_reset( 'timestamp_reference') self.controller.register_reset('sw_time') self.controller.register_reset('sw_index') self.controller.register_reset('sw_sum') self.controller.register_reset('sw') self.controller.register_reset( 'flowselector_key') self.controller.register_reset( 'flowselector_nep') self.controller.register_reset( 'flowselector_ts') self.controller.register_reset( 'flowselector_last_ret') self.controller.register_reset( 'flowselector_last_ret_bin') self.controller.register_reset( 'flowselector_correctness') self.controller.register_reset( 'flowselector_fwloops') print self.sw_name, ' RESET.' # Restart the scheduler time.sleep(1) self.t_sched.start()
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)