def MW_sock_send(MW_ID): # sender function for the MW sockets global MW_sock_input_queues, MW_sockets print "[INFO] <MW_sock_send> for MW({}) :[STARTED]".format( MW_ID) REPLICA_log("[INFO] <MW_sock_send>", " for MW({}) :[STARTED]".format(MW_ID)) while True: try: out_msg = MW_sock_input_queues[MW_ID].pop(0) print "[MW][OUT] <MW_sock_send> => msg to MW ({}), len ({}), kind: ({})".format( MW_ID, su("H", out_msg[:2])[0], su("H", out_msg[2:4])[0]) REPLICA_log( "[MW][OUT] <MW_sock_send>", "msg to MW ({},{}), len ({}), kind: ({})".format( MW_ID, su("H", out_msg[4:6])[0], su("H", out_msg[:2])[0], su("H", out_msg[2:4])[0])) MW_sockets[MW_ID][0].send(out_msg) except IndexError: time.sleep(1) pass except: raise
def VNF_sock_send(VNF_ID): # sender function for the VNF sockets global VNF_sock_input_queues, VNF_sockets print "[INFO] <VNF_sock_send> for VNF({}) :[STARTED]".format( VNF_ID) mid_log("[INFO] <VNF_sock_send>", " for VNF({}) :[STARTED]".format(VNF_ID)) while True: try: out_msg = VNF_sock_input_queues[VNF_ID].pop(0) print "[VNF][OUT] <VNF_sock_send> => msg to VNF ({}), len ({}), kind: ({})".format( VNF_ID, su("H", out_msg[:2])[0], su("H", out_msg[2:4])[0]) mid_log( "[VNF][OUT] <VNF_sock_send>", "msg to VNF ({},{}), len ({}), kind: ({})".format( VNF_ID, su("H", out_msg[4:6])[0], su("H", out_msg[:2])[0], su("H", out_msg[2:4])[0])) VNF_sockets[VNF_ID][0].send(out_msg) except IndexError: time.sleep(1) pass except: raise
def send_msg(): global sending_queue, NF_sock NF_log("[INIT] <send_msg>", " :[STARTED]") print "[INIT] <send_msg>", " :[STARTED]" while True: try: out_msg = sending_queue.pop(0) NF_log( "[OUT] <send_msg>", "MSG len({}), kind({})".format( su("H", out_msg[:2])[0], msg_kind(int(su("H", out_msg[2:4])[0])))) print "[OUT] <send_msg> => sending msg with len({}), kind({})\n".format( su("H", out_msg[:2])[0], msg_kind(int(su("H", out_msg[2:4])[0]))) if len(out_msg) == int(su("H", out_msg[:2])[0]): NF_sock.send(out_msg) else: print "len(out_msg) != int(su('h',out_msg[:2])[0])" except IndexError: time.sleep(1) pass
def packet_in_metadata(pkt_in): pkt_in_metadata = {} print("Received Packet-in\n") packet = pkt_in.packet.payload metadata = pkt_in.packet.metadata for meta in metadata: metadata_id = meta.metadata_id value = meta.value pkt_in_metadata[metadata_id] = value input_port = int(su("!H", pkt_in_metadata[1])[0]) tmp_pkt = copy.deepcopy(packet) tmp_pkt1 = Ether(_pkt=tmp_pkt) raw_var_id = [ bin(int(x))[2:].zfill(8) for x in tmp_pkt1[IP].dst[4:].split(".") ] var_id = int(raw_var_id[0][2:] + raw_var_id[1] + raw_var_id[2], 2) print tmp_pkt1[IP].dst print "var_id: ", var_id return packet, pkt_in_metadata, input_port, var_id
def msg_cleaner_handler(): global init_NF_ID, init_PUB_ID, received_queue, NF_id, variable_id, variable_name, var_names_IDs, answer, SUB_ID_ans current_data = "" # empty for started NF_log("[INIT] <msg_cleaner_handler>", ":[STARTED]") print "[INIT] <msg_cleaner_handler> :[STARTED]\n" while True: try: current_data += received_queue.pop( 0 ) # pop the first received chunk and add to the remained bytes (if any) # more than 2 bytes to know the lenght of the msg AND enough bytes to rebuild a msg while (len(current_data) > 2 and len(current_data) >= int(su("H", current_data[:2])[0])): in_msg = current_data[:int(su("H", current_data[:2]) [0])] # we extract the msg #### INIT NF_ID REPLY => (kind = 0) ## Length(2B)+kind(2B)+NF_global_ID(2B) if int( su("H", in_msg[2:4])[0] ) == 0: # it is an NF_global_ID reply from the SDN controller init_NF_ID = 1 NF_id = int(su("H", in_msg[6:8])[0]) # NF_global_ID NF_log("[IN] <msg_cleaner_handler>", "My NF_ID : global={}".format(NF_id)) #### CUT PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg #### INIT PUB_variable_ID REPLY => (kind = 1) ## Length(2B)+kind(2B)+NF_global_ID(2B) elif int( su("H", in_msg[2:4])[0] ) == 1: # it is an PUB_variable_ID reply from the SDN controller init_PUB_ID = 1 variable_id = int(su("H", in_msg[6:8])[0]) # PUB_variable_ID var_names_IDs[variable_name] = int( su("H", in_msg[6:8])[0]) # convert and save the Variable_ID NF_log("[IN] <msg_cleaner_handler>", "My Publish variable_ID : {}".format(variable_id)) update_num = 0 # initializing #### CUT PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg #### PUBLISH MSG => (kind = 2) ## kind(2B)+variable_id(4B)+update_num(2B)+frag_tot(2B)+frag_num(2B)+DATA(mB) elif int(su("H", in_msg[2:4])[0]) == 2: # it is a publish NF_log( "[IN] <msg_cleaner_handler>", "Received PUBLISH => len({}), kind({})\ ".format( su("H", in_msg[:2])[0], msg_kind(int(su("H", in_msg[2:4])[0])))) print "[IN] <msg_cleaner_handler>", "Received PUBLISH => len({}), kind({})\ ".format( su("H", in_msg[:2])[0], msg_kind(int(su("H", in_msg[2:4])[0]))) # checking if drop mark for "Variable_ID,update_num" if (str(su("H", in_msg[6:8])[0]) + "," + str(su("H", in_msg[8:10])[0]) ) not in drop_update.keys(): drop_update[str(su("H", in_msg[6:8])[0]) + "," + str(su("H", in_msg[8:10]) [0])] = 0 # do not drop this update ## making a fake last received packet for the first time global_table_last_frame[int(su( "H", in_msg[6:8])[0])] = [ int(su("H", in_msg[8:10])[0]), int(su("H", in_msg[10:12])[0]), int(su("H", in_msg[12:14])[0]) - 1 ] tmp_recvd_publishes[int(su("H", in_msg[6:8])[0])] = [ ] # building place for the first msg # there is no drop desicion on this "Variable_ID,update_num" if (drop_update[str(su("H", in_msg[6:8])[0]) + "," + str(su("H", in_msg[8:10])[0])]) == 0: if global_table_last_frame[int( su("H", in_msg[6:8])[0])][0] == int( su("H", in_msg[8:10]) [0]): # from the same update_num if global_table_last_frame[int( su("H", in_msg[6:8])[0])][2] + 1 == int( su("H", in_msg[12:14]) [0]): # we have normal next fragment # appending the pure msg to the temporary list for this update_num of this variable_id tmp_recvd_publishes[int( su("H", in_msg[6:8])[0])].append(in_msg[14:]) if int(su("H", in_msg[10:12])[0]) == int( su("H", in_msg[12:14]) [0]): # last fragment of the update fileName = "logs/P_recv_" + str( su("H", in_msg[6:8]) [0]) # making filname for saving data with open( fileName, "a" ) as f: # open file for external save(DEBUGING) f.write("".join( tmp_recvd_publishes[int( su("H", in_msg[6:8]) [0])])) # external save tmp_recvd_publishes[int( su("H", in_msg[6:8])[0] )] = [ ] # cleaning the in_msg for next update # ready for first fragment of next update global_table_last_frame[int( su("H", in_msg[6:8])[0])] = [ int(su("H", in_msg[8:10])[0]) + 1, 0, 0 ] else: # we have lost fragment/s # puting drop desicion on this "Variable_ID,update_num" # drop_update[str(su("H",in_msg[6:8])[0])+","+str(su("H",in_msg[8:10])[0])] = 1 # Data_length(2B)+kind(2B)+Global_ID(2B)+variable_id(2B)+update_num(2B) recover_msg = sp("H", 10) + sp("H", 6) + sp( "H", NF_id) + in_msg[6:10] sending_queue.append(recover_msg) tmp_recvd_publishes[int( su("H", in_msg[6:8])[0] )] = [ ] # cleaning the in_msg due to lost fragment elif int( su("H", in_msg[12:14])[0] ) > 1: # we have lost msg from 2 consequent updates # drop_update[str(su("H",in_msg[6:8])[0])+","+str(su("H",in_msg[8:10])[0])] = 1 # puting drop desicion on this "variable_id,update_num" ## Data_length(2B)+kind(2B)+Global_ID(2B)+variable_id(2B)+previous_update_num(2B) recover_msg = sp("H", 10) + sp("H", 6) + sp( "H", NF_id) + in_msg[6:8] + sp( "H", int(su("H", in_msg[8:10])[0]) - 1) #recover for previous update sending_queue.append(recover_msg) tmp_recvd_publishes[int( su("H", in_msg[6:8])[0] ) - 1] = [ ] # cleaning the in_msg due to lost fragment of previous update ## Data_length(2B)+kind(2B)+Global_ID(2B)+variable_id(2B)+update_num(2B) recover_msg = sp("H", 10) + sp("H", 6) + sp( "H", NF_id) + in_msg[6:10] sending_queue.append(recover_msg) tmp_recvd_publishes[int(su( "H", in_msg[6:8])[0])] = [ ] # cleaning the in_msg due to lost fragment else: tmp_recvd_publishes[int(su("H", in_msg[6:8])[0])] = [ ] # empty the tempory received update because of fragment/s lost #### CUT PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg #### SUBSCRIBE VARIABLE_ID RESPONSE elif int( su("H", in_msg[2:4])[0] ) == 5: # it is a SDN reply to variable_ID request for subscription if int(su("H", in_msg[6:8])[0]) == 0: SUB_ID_ans = "error" NF_log( "msg_cleaner_handler", "UN-SUCCESSFUL VAR_ID_REQ response from the SDN") print "msg_cleaner_handler: UN-SUCCESSFUL VAR_ID_REQ response from the SDN" else: SUB_ID_ans = "ok" var_name = "".join([su("c", x)[0] for x in in_msg[8:] ]) # the variable_name # print "var_name: ",var_name var_names_IDs[var_name] = int( su("H", in_msg[6:8]) [0]) # convert and save the Variable_ID NF_log("msg_cleaner_handler", "SUCCESSFUL VAR_ID_REQ response from the SDN") print "msg_cleaner_handler: SUCCESSFUL VAR_ID_REQ response from the SDN" #### CUT PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg answer = 1 except IndexError: time.sleep(1) pass
def recv_data_middleware(): global VNF_local_global_id, VNF_local_global_id, VNF_publishes, VNF_sock_input_queues, rcv_mw_sock global VNF_subscriptions, rcv_mw_socks # Create the socket rcv_mw_socks[0] = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) rcv_mw_socks[0].setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) # Bind to the server address rcv_mw_socks[0].bind(('', 65432)) while True: data, addr_uni = rcv_mw_socks[0].recvfrom(2048) try: mid_log( "[SW][IN] <recv_data_middleware>", "MSG len({}), kind({})".format( su("H", data[:2])[0], su("H", data[2:4])[0])) print "[SW][IN] <recv_data_middleware> => len({}), kind({})".format( su("H", data[:2])[0], su("H", data[2:4])[0]) except: pass ### PUBLISH if int(su("H", data[2:4])[0]) == 2: mid_log( "[SW][IN] <rcv_mw_sock({})>".format( str(int(su("H", data[6:8])[0]))), "PUBLISH packet") if int(su("H", data[6:8])[0]) in VNF_subscriptions.keys( ): # if there is internal subscriptions on this Variable_ID for dest in VNF_subscriptions[int(su("H", data[6:8])[0])]: print "[INFO] <rcv_mw_sock({})>".format( str(int(su("H", data[6:8])[0]))) print "PUBLISH : len({}), kind({}), G_id({})".format( int(su("H", data[:2])[0]), int(su("H", data[2:4])[0]), int(su("H", data[4:6])[0])) ## msg = Data_length(2B)+Kind(2B)+Global_ID(4B)+tot_var(2B) msg_copy = copy.deepcopy(data) VNF_sock_input_queues[VNF_local_global_id.index( dest)].append(msg_copy)
def send_data_middleware(): # sending packets to network global OUT_2_queue, thr_rcv_pub_multi, rcv_mw_socks, all_mcast_groups, mcast_groups, system_default_max # Create the datagram socket send_mw_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ## Set the time-to-live for messages ttl = struct.pack('b', 2) send_mw_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl) group_num = 0 mcast_groups[group_num] = [] while True: try: out_msg = OUT_2_queue.pop(0) mid_log( "[SW][OUT] <send_data_middleware>", "MSG len({}), kind({})".format( su("H", out_msg[:2])[0], su("H", out_msg[2:4])[0])) print "[SW][OUT] <send_data_middleware> => len({}), kind({})".format( su("H", out_msg[:2])[0], su("H", out_msg[2:4])[0]) kind = int(su("H", out_msg[2:4])[0]) # SUB_register if kind == 3: var_id = int(su("H", out_msg[6:8])[0]) # Building the multicast group related to the variable_id mcast_group = pubSubIP(var_id, 2) # Tell the operating system to add the socket to the multicast group # on all interfaces. group = socket.inet_aton(mcast_group) mreq = struct.pack('4sL', group, socket.INADDR_ANY) all_mcast_groups.append(mcast_group) try: rcv_mw_socks[group_num].setsockopt( socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) except: group_num += 1 mcast_groups[group_num] = [] ## building a new thread responcible for making a new socket for that var_id, ## but not receiving, just letting us do more IP_multicast_membersip rcv_mw_socks[group_num] = threading.Thread( target=pub_mcast_membership_maker, args=[group_num]) print "[INFO] send_data_middleware: buiding...", rcv_mw_socks rcv_mw_socks[group_num].start() print "[INFO] send_data_middleware: starting...", rcv_mw_socks with open("error_mreq_report.txt", "a") as f: f.write( "handled membership error due to OS limit,receiver thread for: %s ,group: %s\n" % (str(var_id), mcast_group)) pass mcast_groups[group_num].append(mcast_group) elif kind in [2, 4, 6]: # publish, sub_remove, recover var_id = int(su("H", out_msg[6:8])[0]) elif kind in [ 0, 1, 5 ]: # init_VNF, pub_variable_id_request, sub_variable_id_request var_id = 0 ## Making proper destination dest_addr = (pubSubIP(var_id, kind), 65432) # Due to some inconsistency between the switch and the embedded controller we send 2 packets if kind in [3, 4]: out_msg_dup = copy.deepcopy(out_msg) dup_send = send_mw_sock.sendto(out_msg_dup, dest_addr) ## Sending the msg sent = send_mw_sock.sendto(out_msg, dest_addr) except IndexError: time.sleep(1) pass
def sig_msg_hndlr_REPLICA(): global IN_1_queue current_data = "" # empty for started mid_log("[INIT] <REPLICA_msg_cleaner_handler>", ":[STARTED]") print "[INIT] <REPLICA_msg_cleaner_handler> :[STARTED]" while True: try: # pop the first received chunk and add to the remained bytes (if any) current_data += IN_1_queue.pop(0) # more than 2 bytes to know the lenght of the msg and enough bytes to rebuild a msg while (len(current_data) > 2 and len(current_data) >= int(su("H", current_data[:2])[0])): # we extract the msg from Data_length(2B) in_msg = current_data[:int(su("H", current_data[:2])[0])] ### INIT VNF_ID REPLY #### => (kind = 0) if int( su("H", in_msg[2:4])[0] ) == 0: # it is an initializing response from the REPLICA controller => send to the VNF INT module try: mid_log("[INFO] <sig_msg_hndlr_REPLICA>", "INIT VNF_ID REPLY:len({}), kind({}), l_ID({}), G_id({})"\ .format(int(su("H", in_msg[:2])[0]),int(su("H", in_msg[2:4])[0]),int(su("H", in_msg[4:6])[0]),int(su("H", in_msg[6:8])[0]))) print "[INFO] <sig_msg_hndlr_REPLICA> " print "INIT VNF_ID REPLY: len({}), kind({}), l_ID({}), G_id({})".format( int(su("H", in_msg[:2])[0]), int(su("H", in_msg[2:4])[0]), int(su("H", in_msg[4:6])[0]), int(su("H", in_msg[6:8])[0])) VNF_local_global_id[int(su( "H", in_msg[4:6])[0])] = int( su("H", in_msg[6:8])[0] ) # update the mapping of Local_ID : Global_ID print "[INFO] <sig_msg_hndlr_REPLICA> VNF_local_global_id: {} ".format( VNF_local_global_id) ## append msg to the input queue of the related VNF socket VNF_sock_input_queues[int(su( "H", in_msg[4:6])[0])].append(in_msg) #### CUT PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg except: raise ### INIT PUB_ID REPLY #### => (kind = 1) elif int( su("H", in_msg[2:4])[0] ) == 1: # it is a PUB_ID reply from the REPLICA controller => send to the send to the VNF INT module try: mid_log("[INFO] <recv_data_middleware>", "INIT PUB_ID REPLY:len({}), kind({}), G_id({})"\ .format(int(su("H", in_msg[:2])[0]),int(su("H", in_msg[2:4])[0]),int(su("H", in_msg[4:6])[0]))) print "[INFO] <recv_data_middleware> " print "INIT PUB_ID REPLY: len({}), kind({}), G_id({})".format( int(su("H", in_msg[:2])[0]), int(su("H", in_msg[2:4])[0]), int(su("H", in_msg[4:6])[0])) tmp_var_ID = int(su( "H", in_msg[6:8])[0]) # extracting the Variable_ID ## append var_ID to the published list of the related VNF socket if int(su("H", in_msg[4:6])[0]) in VNF_publishes.keys(): VNF_publishes[int(su( "H", in_msg[4:6])[0])].append(tmp_var_ID) else: VNF_publishes[int(su( "H", in_msg[4:6])[0])] = [tmp_var_ID] print "[INFO] <recv_data_middleware> check the VNF_publishes: ", VNF_publishes print "INIT PUB_ID REPLY: len({}), kind({}), G_id({})".format( int(su("H", in_msg[:2])[0]), int(su("H", in_msg[2:4])[0]), int(su("H", in_msg[4:6])[0])) ## append msg to the input queue of the related VNF socket VNF_sock_input_queues[VNF_local_global_id.index( int(su("H", in_msg[4:6])[0]))].append(in_msg) #### CUT PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg except: raise ### INIT SUB_ID REPLY #### => (kind = 5) elif int( su("H", in_msg[2:4])[0] ) == 5: # it is a SUB_ID reply from the REPLICA controller => send to the send to the VNF INT module try: mid_log("[INFO] <recv_data_middleware>", "VARIABLE_ID_REPLY:len({}), kind({}), G_id({}), Var_ID({})"\ .format(int(su("H", in_msg[:2])[0]),int(su("H", in_msg[2:4])[0]), int(su("H", in_msg[4:6])[0]),int(su("H", in_msg[6:8])[0]))) print "[INFO] <recv_data_middleware>" print "VARIABLE_ID_REPLY: len({}), kind({}), G_id({}), v_ID({})".format( int(su("H", in_msg[:2])[0]), int(su("H", in_msg[2:4])[0]), int(su("H", in_msg[4:6])[0]), int(su("H", in_msg[6:8])[0])) ## append msg to the input queue of the related VNF socket VNF_sock_input_queues[VNF_local_global_id.index( int(su("H", in_msg[4:6])[0]))].append(in_msg) #### CUT PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg except: raise except IndexError: time.sleep(1) pass
def VNF_sock_data_cleaner_handlr( VNF_ID ): # rebuild the msgs coming from the VNF and send to needed queues in the Middle_Ware global VNF_sock_input_queues, VNF_sock_output_queues, VNF_subscriptions global VNF_publishes, OUT_2_queue, VNF_local_global_id current_data = "" # empty for started print "[INFO] <VNF_sock_data_cleaner_handlr> for VNF({}) :[STARTED]".format( VNF_ID) mid_log("[INFO] <VNF_sock_data_cleaner_handlr>", "for VNF({}) :[STARTED]".format(VNF_ID)) while True: try: # pop the first received chunk and add to the remained bytes (if any) current_data = current_data + VNF_sock_output_queues[VNF_ID].pop(0) # more than 2 bytes to know the lenght of the msg and enough bytes to rebuild a msg while (len(current_data) > 2 and len(current_data) >= int(su("H", current_data[:2])[0])): in_msg = current_data[:int( su("H", current_data[:2]) [0])] # we extract the msg from Data_length(2B) mid_log( "[MW][IN] <VNF_sock_data_cleaner_handlr>", "MSG len({}), kind({})".format( su("H", in_msg[:2])[0], su("H", in_msg[2:4])[0])) print "[MW][IN] <VNF_sock_data_cleaner_handlr> => len({}), kind({})".format( su("H", in_msg[:2])[0], su("H", in_msg[2:4])[0]) #### INITIALIZING VNF_ID REQUEST #### => (kind = 0) if int( su("H", in_msg[2:4])[0] ) == 0: # it is an initializing request from the VNF => send to the SDN controller try: ## msg = Data_length(2B)+Kind(2B)+local_ID(2B)+Global_ID(2B)+VNF_NAME(nB) in_msg_tmp = in_msg[2:4] + sp("H", VNF_ID) + in_msg[6:] in_msg_tmp = sp("H", len(in_msg_tmp) + 2) + in_msg_tmp OUT_1_queue.append(in_msg_tmp) #### CUT PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg except: raise #### PUB_ID, SUB_ID or RECOVER REQUEST #### => (kind = 1, 5 and 6) elif int(su("H", in_msg[2:4])[0]) in [ 1, 5, 6 ]: # it is an initializing request from the VNF => send to the SDN controller try: ## msg = Data_length(2B)+Kind(2B)+Global_ID(2B)+VNF_NAME(nB) OUT_1_queue.append(in_msg) #### CUT THE PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg except: raise #### PUBLISH #### => (kind = 2) elif int(su( "H", in_msg[2:4])[0]) == 2: # it is a publish msg from VNF try: tmp_var_ID = int(su( "H", in_msg[6:8])[0]) # extracting the Variable_ID ## append var_ID to the published list of the related VNF socket if tmp_var_ID in VNF_subscriptions.keys( ): # if there is internal subscriptions on this Variable_ID for dest in VNF_subscriptions[tmp_var_ID]: ## msg = Data_length(2B)+Kind(2B)+Local_ID(2B)+Global_ID(4B)+tot_var(2B) msg_copy = copy.deepcopy(in_msg) VNF_sock_input_queues[ VNF_local_global_id.index(dest)].append( msg_copy) OUT_2_queue.append(in_msg) #### CUT THE PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg except: raise #### SUBSCRIBE REGISTER #### => (kind = 3) elif int(su("H", in_msg[2:4]) [0]) == 3: # it is a subscribe-register request if int( su("H", in_msg[6:8])[0] ) not in VNF_subscriptions.keys( ): # If variable_ID is NOT in VNF_subscription as a key e.g. var_id:[.....] NOT exists VNF_subscriptions[int(su("H", in_msg[6:8])[0])] = [ int(su("H", in_msg[4:6])[0]) ] # add VNF_GLOBAL_ID to subscriptions of var_id:[] internal_publish = 0 print "[INFO] <VNF_sock_data_cleaner_handlr> check before subscribe in SW" print "VNF_publishes: ", VNF_publishes print "VNF_subscriptions: ", VNF_subscriptions for VNF in VNF_publishes.keys(): # check internal registered publishes for the var_id if int(su("H", in_msg[6:8])[0]) in VNF_publishes[VNF]: internal_publish = 1 break if not internal_publish: # if no internal publish on that var_id exist OUT_2_queue.append( in_msg) # try to send request to the switch else: # If variable_ID is in VNF_subscription as a key if int(su( "H", in_msg[4:6])[0]) not in VNF_subscriptions[int( su("H", in_msg[6:8]) [0])]: # if VNF_ID is not in the var_id:[] VNF_subscriptions[int(su( "H", in_msg[6:8])[0])].append( int(su("H", in_msg[4:6])[0]) ) # add VNF_ID to subscriptions of var_id #### CUT THE PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg #### SUBSCRIBE REMOVE #### => (KIND = 4) elif int(su("H", in_msg[2:4]) [0]) == 4: # it is a subscribe-remove request if (int(su("H", in_msg[6:8])[0]) in VNF_subscriptions.keys() and int(su( "H", in_msg[4:6])[0]) in VNF_subscriptions[int( su("H", in_msg[6:8])[0])]): VNF_subscriptions[int(su("H", in_msg[6:8])[0])].remove( int(su("H", in_msg[4:6])[0])) if not VNF_subscriptions[int(su("H", in_msg[6:8])[0])]: internal_publish = 0 for VNF in VNF_publishes.keys(): if VNF_subscriptions[int( su("H", in_msg[6:8])[0])] in VNF_publishes[VNF]: internal_publish = 1 break if not internal_publish: OUT_2_queue.append(in_msg) #### CUT THE PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg else: print "WHY? ;)" except IndexError: time.sleep(1) pass except: raise
def MW_sock_data_cleaner_handlr(MW_ID): global MW_sock_input_queues, MW_sock_output_queues global nxt_NF_global_id, nxt_variable_global_id global NF_pub_global_ids, global_name_NF_id current_data = "" # empty for started print "[INFO] <MW_sock_data_cleaner_handlr> for MW({}) :[STARTED]".format( MW_ID) REPLICA_log("[INFO] <MW_sock_data_cleaner_handlr>", "for MW({}) :[STARTED]".format(MW_ID)) while True: try: # pop the first received chunk and add to the remained bytes (if any) current_data += MW_sock_output_queues[MW_ID].pop(0) # more than 2 bytes to know the lenght of the msg and enough bytes to rebuild a msg while (len(current_data) > 2 and len(current_data) >= int(su("H", current_data[:2])[0])): in_msg = current_data[:int( su("H", current_data[:2]) [0])] # we extract the msg from Data_length(2B) REPLICA_log( "[MW][IN] <MW_sock_data_cleaner_handlr>", "MSG len({}), kind({})".format( su("H", in_msg[:2])[0], su("H", in_msg[2:4])[0])) print "[MW][IN] <MW_sock_data_cleaner_handlr> => len({}), kind({})".format( su("H", in_msg[:2])[0], su("H", in_msg[2:4])[0]) #### INITIALIZING NF_ID REQUEST #### => (kind = 0) if int(su("H", in_msg[2:4])[0]) == 0: REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ", "INIT_NF_ID request msg received.") print "INIT_NF_ID REQUEST msg received." global_name_NF_id["".join([ su("c", x)[0] for x in in_msg[8:] ])] = nxt_NF_global_id # mapping NF_NAME : NF_ID NF_pub_global_ids[nxt_NF_global_id] = [] tmp_msg = in_msg[2:6] + sp("H", nxt_NF_global_id) + in_msg[8:] tmp_msg = sp("H", len(tmp_msg) + 2) + tmp_msg MW_sock_input_queues[MW_ID].append(tmp_msg) REPLICA_log("[MW][IN] <handle_pkt_REPLICA> ", "INIT_NF_ID reply msg sent.") print "INIT_NF_ID REPLY msg sent." nxt_NF_global_id += 1 #### CUT THE PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg ### INIT PUB_ID MSG ### (kind = 1) elif int(su("H", in_msg[2:4])[0]) == 1: REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ", "INIT_PUB_ID request msg received.") print "INIT_PUB_ID request msg received." global_name_variable_id["".join([ su("c", x)[0] for x in in_msg[6:] ])] = nxt_variable_global_id NF_pub_global_ids[int(su( "H", in_msg[4:6])[0])].append(nxt_variable_global_id) tmp_msg = in_msg[2:6] + sp( "H", nxt_variable_global_id) + in_msg[6:] tmp_msg = sp("H", len(tmp_msg) + 2) + tmp_msg MW_sock_input_queues[MW_ID].append(tmp_msg) REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ", "INIT_PUB_ID reply msg sent.") print "INIT_PUB_ID REPLY msg sent." nxt_variable_global_id += 1 #### CUT THE PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg ### VARIABLE_ID request ### (kind = 5) elif int(su("H", in_msg[2:4])[0]) == 5: REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ", "Variable_ID request msg received.") print "Variable_ID request msg received." var_name = "".join([su("c", x)[0] for x in in_msg[6:]]) if var_name in global_name_variable_id.keys(): tmp_msg = in_msg[2:6] + sp( "H", global_name_variable_id[var_name]) + in_msg[6:] tmp_msg = sp("H", len(tmp_msg) + 2) + tmp_msg REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ", "Variable_ID reply msg sent.") print "Variable_ID reply msg sent." else: tmp_msg = in_msg[2:6] + sp("H", 0) + in_msg[6:] tmp_msg = sp("H", len(tmp_msg) + 2) + tmp_msg REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ", "Variable_ID reply (ERROR) msg sent.") print "Variable_ID reply (ERROR) msg sent." MW_sock_input_queues[MW_ID].append(tmp_msg) #### CUT THE PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg ### RECOVER msg ### (kind = 6) elif int(su("H", in_msg[2:4])[0]) == 6: REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ", "RECOVER msg received.") print "RECOVER msg : " print in_msg #### CUT THE PROCESSED MSG FROM current_data current_data = current_data[int( su("H", current_data[:2]) [0]):] # continue from begining of the next msg except: time.sleep(1) pass
def handle_pkt_REPLICA(): global recv_REPLICA_sock, send_REPLICA_sock global nxt_NF_global_id, nxt_variable_global_id global NF_pub_global_ids, global_name_NF_id while True: msg, msg_address = recv_REPLICA_sock.recvfrom(2048) REPLICA_log("\n[SW][IN] <handle_pkt_REPLICA> ", " => len({}), kind({})".format(su("H",msg[:2])[0],msg_kind(int(su("H",msg[2:4])[0])))) print "\nGot msg => kind({})".format(msg_kind(int(su("H",msg[2:4])[0]))) ### INIT NF_ID MSG ### (kind = 0) if int(su("H",msg[2:4])[0])==0: REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ", "INIT_NF_ID request msg received.") print "INIT_NF_ID REQUEST msg received." global_name_NF_id["".join([su("c", x)[0] for x in msg[8:]])] = nxt_NF_global_id # mapping NF_NAME : NF_ID NF_pub_global_ids[nxt_NF_global_id] = [] tmp_msg = msg[2:6]+sp("H",nxt_NF_global_id)+msg[8:] tmp_msg = sp("H",len(tmp_msg)+2) + tmp_msg try: dest_addr = (msg_address[0],65432) sent = send_REPLICA_sock.sendto(tmp_msg, dest_addr) except: raise REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ", "INIT_NF_ID reply msg sent.") print "INIT_NF_ID REPLY msg sent." nxt_NF_global_id += 1 ### INIT PUB_ID MSG ### (kind = 1) elif int(su("H",msg[2:4])[0])==1: REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ", "INIT_PUB_ID request msg received.") print "INIT_PUB_ID request msg received." global_name_variable_id["".join([su("c", x)[0] for x in msg[6:]])] = nxt_variable_global_id NF_pub_global_ids[int(su("H",msg[4:6])[0])].append(nxt_variable_global_id) tmp_msg = msg[2:6]+sp("H",nxt_variable_global_id)+msg[6:] tmp_msg = sp("H",len(tmp_msg)+2) + tmp_msg try: dest_addr = (msg_address[0],65432) sent = send_REPLICA_sock.sendto(tmp_msg, dest_addr) except: raise REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ", "INIT_PUB_ID reply msg sent.") print "INIT_PUB_ID REPLY msg sent." nxt_variable_global_id += 1 ### VARIABLE_ID request ### (kind = 5) elif int(su("H",msg[2:4])[0])==5: REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ","Variable_ID request msg received.") print "Variable_ID request msg received." var_name = "".join([su("c", x)[0] for x in msg[6:]]) if var_name in global_name_variable_id.keys(): tmp_msg = msg[2:6]+sp("H",global_name_variable_id[var_name])+msg[6:] tmp_msg = sp("H",len(tmp_msg)+2) + tmp_msg REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ","Variable_ID reply msg sent.") print "Variable_ID reply msg sent." else: tmp_msg = msg[2:6]+sp("H", 0)+msg[6:] tmp_msg = sp("H",len(tmp_msg)+2) + tmp_msg REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ","Variable_ID reply (ERROR) msg sent.") print "Variable_ID reply (ERROR) msg sent." try: dest_addr = (msg_address[0],65432) sent = send_REPLICA_sock.sendto(tmp_msg, dest_addr) except: raise ### RECOVER msg ### (kind = 6) elif int(su("H",msg[2:4])[0])==6: REPLICA_log("[SW][IN] <handle_pkt_REPLICA> ", "RECOVER msg received.") print "RECOVER msg : \n" print msg
def recv_data_middleware(): global NF_local_global_id, NF_local_global_id, NF_publishes, NF_sock_input_queues, rcv_mw_sock global NF_subscriptions, rcv_mw_socks # Create the socket rcv_mw_socks[0] = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) rcv_mw_socks[0].setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) # Bind to the server address rcv_mw_socks[0].bind(('', 65432)) while True: data, addr_uni = rcv_mw_socks[0].recvfrom(2048) mid_log( "[SW][IN] <recv_data_middleware>", "MSG len({}), kind({})".format( su("H", data[:2])[0], su("H", data[2:4])[0])) print "[SW][IN] <recv_data_middleware> => len({}), kind({})".format( su("H", data[:2])[0], su("H", data[2:4])[0]) ### INIT NF_ID REPLY if int(su("H", data[2:4])[0]) == 0: mid_log("\n[INFO] <recv_data_middleware>", "INIT NF_ID REPLY:len({}), kind({}), l_ID({}), G_id({})\n"\ .format(int(su("H", data[:2])[0]),int(su("H", data[2:4])[0]),int(su("H", data[4:6])[0]),int(su("H", data[6:8])[0]))) print "\n[INFO] <recv_data_middleware> " print "INIT NF_ID REPLY: len({}), kind({}), l_ID({}), G_id({})\n".format( int(su("H", data[:2])[0]), int(su("H", data[2:4])[0]), int(su("H", data[4:6])[0]), int(su("H", data[6:8])[0])) NF_local_global_id[int(su("H", data[4:6])[0])] = int( su("H", data[6:8])[0]) # update the mapping of Local_ID : Global_ID print "\n[INFO] <recv_data_middleware> NF_local_global_id: {} \n".format( NF_local_global_id) NF_sock_input_queues[int(su("H", data[4:6])[0])].append( data ) ## append msg to the input queue of the related NF socket ### INIT PUB_ID REPLY elif int(su("H", data[2:4])[0]) == 1: mid_log("\n[INFO] <recv_data_middleware>", "INIT PUB_ID REPLY:len({}), kind({}), G_id({})\n"\ .format(int(su("H", data[:2])[0]),int(su("H", data[2:4])[0]),int(su("H", data[4:6])[0]))) print "\n[INFO] <recv_data_middleware> " print "INIT PUB_ID REPLY: len({}), kind({}), G_id({})\n".format( int(su("H", data[:2])[0]), int(su("H", data[2:4])[0]), int(su("H", data[4:6])[0])) tmp_var_ID = int(su("H", data[6:8])[0]) # extracting the Variable_ID ## append var_ID to the published list of the related NF socket if int(su("H", data[4:6])[0]) in NF_publishes.keys(): NF_publishes[int(su("H", data[4:6])[0])].append(tmp_var_ID) else: NF_publishes[int(su("H", data[4:6])[0])] = [tmp_var_ID] print "\n[INFO] <recv_data_middleware> check the NF_publishes: ", NF_publishes print "INIT PUB_ID REPLY: len({}), kind({}), G_id({})\n".format( int(su("H", data[:2])[0]), int(su("H", data[2:4])[0]), int(su("H", data[4:6])[0])) ## append msg to the input queue of the related NF socket NF_sock_input_queues[NF_local_global_id.index( int(su("H", data[4:6])[0]))].append(data) ### PUBLISH elif int(su("H", data[2:4])[0]) == 2: mid_log( "[SW][IN] <rcv_mw_sock({})>".format( str(int(su("H", data[6:8])[0]))), "PUBLISH packet") if int(su("H", data[6:8])[0]) in NF_subscriptions.keys( ): # if there is internal subscriptions on this Variable_ID for dest in NF_subscriptions[int(su("H", data[6:8])[0])]: print "\n[INFO] <rcv_mw_sock({})>".format( str(int(su("H", data[6:8])[0]))) print "PUBLISH : len({}), kind({}), G_id({})".format( int(su("H", data[:2])[0]), int(su("H", data[2:4])[0]), int(su("H", data[4:6])[0])) ## msg = Data_length(2B)+Kind(2B)+Global_ID(4B)+tot_var(2B) msg_copy = copy.deepcopy(data) NF_sock_input_queues[NF_local_global_id.index( dest)].append(msg_copy) ### VARIABLE_ID_REPLY elif int(su("H", data[2:4])[0]) == 5: mid_log("\n[INFO] <recv_data_middleware>", "VARIABLE_ID_REPLY:len({}), kind({}), G_id({}), Var_ID({})\n"\ .format(int(su("H", data[:2])[0]),int(su("H", data[2:4])[0]), int(su("H", data[4:6])[0]),int(su("H", data[6:8])[0]))) print "\n[INFO] <recv_data_middleware>" print "VARIABLE_ID_REPLY: len({}), kind({}), G_id({}), v_ID({})\n".format( int(su("H", data[:2])[0]), int(su("H", data[2:4])[0]), int(su("H", data[4:6])[0]), int(su("H", data[6:8])[0])) ## append msg to the input queue of the related NF socket NF_sock_input_queues[NF_local_global_id.index( int(su("H", data[4:6])[0]))].append(data)
def main(p4info_file_path, bmv2_file_path, sw_num): # Instantiate a P4Runtime helper from the p4info file p4info_helper = helper.P4InfoHelper(p4info_file_path) s_name = 's' + str(sw_num) print "switch name: ", s_name try: ''' Create a switch connection object for s1 This is backed by a P4Runtime gRPC connection. Also, dump all P4Runtime messages sent to switch to given txt files. In the P4 package here, port no starts from 50051 ''' switch = p4runtime_lib.bmv2.Bmv2SwitchConnection( name=s_name, address='127.0.0.1:5005' + str(sw_num), device_id=0, proto_dump_file='logs/' + s_name + '-p4runtime-requests.txt') ''' Send master arbitration update message to establish this controller as master (required by P4Runtime before performing any other write operation) ''' switch.MasterArbitrationUpdate() print "Master arbitration done..." # readTableRules(p4info_helper, switch, None) # print print "<<<< CONTROLLER READEY! WAITING FOR PACKET_IN >>>>" while True: ''' USING P4RUNTIME AS RECEIVER FOR PACKET_IN IN THE EMBEDDED CONTROLLER ''' packetin = switch.PacketIn() if packetin.WhichOneof('update') == 'packet': packet, pkt_in_metadata, input_port, var_id = packet_in_metadata( packetin) input_port_mask = port_mask(input_port) print ">>>> Reading current entries in \"MyIngress.L2_publish\" table before updating >>>>" current_table = readTableRules(p4info_helper, switch, "MyIngress.L2_publish") print if len(current_table) == 0: try: writeL2Publish(p4info_helper, switch, var_id, input_port_mask) except: print "\nproblem writing table for them!\n" raise else: found = False for tbl_entry in current_table: tmp_match_value = '\x00' + tbl_entry['match'][ 'local_metadata.pubsub_indx'][0] if su("!I", tmp_match_value)[0] == var_id: old_mc_grp_id = su( "!H", tbl_entry['action_params']['st_mc_grp']) new_mc_grp_id = int( old_mc_grp_id[0]) | input_port_mask try: ## DELETE and WRITE print "MODIFY(Delete and Write) for ", var_id, " from ", old_mc_grp_id, " to ", new_mc_grp_id deleteL2Publish(p4info_helper, switch, var_id, old_mc_grp_id) writeL2Publish(p4info_helper, switch, var_id, new_mc_grp_id) ## OR MODIFY # modifyL2Publish(p4info_helper, switch, var_id, new_mc_grp_id) except: print "\nproblem writing table for them!\n" # raise found = True break if not found: try: writeL2Publish(p4info_helper, switch, var_id, input_port_mask) except: print "\nproblem writing table for them!\n" raise ''' USING P4RUNTIME FOR PACKET_OUT IN THE CONTROLLER ''' my_packet_out = p4info_helper.buildPacketOut( payload=packet, metadata={1: pkt_in_metadata[1]}) print "Donig PacketOut.\n" # my_packet_out_dup=copy.deepcopy(my_packet_out) # switch.PacketOut(my_packet_out_dup) switch.PacketOut(my_packet_out) print "PacketOut Done." print "==============================================\n" except KeyboardInterrupt: # using ctrl + c to exit # Then close all the connections print " Shutting down....." except grpc.RpcError as e: printGrpcError(e) ShutdownAllSwitchConnections()