/*********************************************************************** * The task function of send task * Form: static void pofdp_send_raw_task(void *arg) * Input: NONE * Output: NONE * Return: VOID * Discribe: This is the task function of send task, which is infinite * loop running. It reads the send queue to get the packet data * and the sending port infomation. Then it sends the packet * out by binding the socket to the local physical net port * spicified in the port infomation. * NOTE: This task will be terminated if any ERRORs occur. ***********************************************************************/ static uint32_t pofdp_send_raw_task(void *arg){ struct pofdp_packet *dpp = malloc(sizeof *dpp); struct sockaddr_ll sll; int sock; /* Create socket. */ if((sock = socket(PF_PACKET, SOCK_RAW, POF_HTONS(ETH_P_ALL))) == -1){ POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_CREATE_SOCKET_FAILURE, g_upward_xid++); /* Delay 0.1s to send error message upward to the Controller. */ pofbf_task_delay(100); terminate_handler(); } memset(&sll, 0, sizeof(struct sockaddr_ll)); while(1){ /* Read the message from the queue. */ if(pofbf_queue_read(g_pofdp_send_q_id, dpp, sizeof *dpp, POF_WAIT_FOREVER) != POF_OK){ POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_READ_MSG_QUEUE_FAILURE, g_upward_xid++); /* Delay 0.1s to send error message upward to the Controller. */ pofbf_task_delay(100); terminate_handler(); } /* Send the packet data out through the port. */ sll.sll_ifindex = dpp->output_port_id; sll.sll_family = AF_PACKET; sll.sll_protocol = POF_HTONS(ETH_P_ALL); if(sendto(sock, dpp->buf_out, dpp->output_whole_len, 0, (struct sockaddr *)&sll, sizeof(sll)) == -1){ free(dpp->buf_out); POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_SEND_MSG_FAILURE, g_upward_xid++); /* Delay 0.1s to send error message upward to the Controller. */ pofbf_task_delay(100); terminate_handler(); } free(dpp->buf_out); } close(sock); return POF_OK; }
void sighandler(int sig, short event, void *arg) { switch (sig) { case SIGTERM: case SIGINT: (void)event_loopexit(NULL); terminate_handler(); } }
static uint32_t pofsc_performance_after_ctrl_disconn(){ #if (POF_PERFORM_AFTER_CTRL_DISCONN == POF_AFTER_CTRL_DISCONN_SHUT_DOWN) terminate_handler(); #elif (POF_PERFORM_AFTER_CTRL_DISCONN == POF_AFTER_CTRL_DISCONN_RECONN) pofsc_conn_desc.conn_status.state = POFCS_CHANNEL_INVALID; if(pof_auto_clear()){ poflr_clear_resource(); } #endif // POF_PERFORM_AFTER_CTRL_DISCONN return POF_OK; }
/*********************************************************************** * The endless function which control module is running. * Form: static void pofsc_wait_exit() * Input: NONE * Output: NONE * Return: VOID * Discribe: After all of the initialization function, the main task will * keep running in this function until "quit" is inputed by * user command line. ***********************************************************************/ static uint32_t pofsc_wait_exit(){ char s[20]; #ifdef POF_COMMAND_ON sleep(1); pof_runing_command(s, 20); #else // POF_COMMAND_ON char s_quit[] = "quit"; fgets(s,20,stdin); while(memcmp(s,s_quit,sizeof(s_quit)-1) != 0){ printf("Pleas input 'quit' to quit!\n"); fgets(s,20,stdin); } #endif terminate_handler(); return POF_OK; }
/*********************************************************************** * The task function of the datapath task * Form: static void pofdp_main_task(void *arg_ptr) * Input: NONE * Output: NONE * Return: VOID * Discribe: This is the main function of the datapath task, which is * infinite loop running. It receive the RAW packet, and forward. * The next RAW packet will be not proceeded until the forward * process of the last packet is over. * NOTE: The datapath task will be terminated if some ERROR occurs * during the receive process and the datapath process. ***********************************************************************/ static uint32_t pofdp_main_task(void *arg_ptr){ uint8_t recv_buf[POFDP_PACKET_RAW_MAX_LEN] = {0}; struct pofdp_packet dpp[1] = {0}; struct pof_instruction first_ins[1] = {0}; uint32_t len_B = 0, port_id = 0; uint32_t ret; /* Set GOTO_TABLE instruction to go to the first flow table. */ set_goto_first_table_instruction(first_ins); while(1){ /* Receive raw packet through local physical OpenFlow-enabled ports. */ ret = pofdp_recv_raw(dpp); if(ret != POF_OK){ POF_CHECK_RETVALUE_NO_RETURN_NO_UPWARD(ret); /* Delay 0.1s to send error message upward to the Controller. */ pofbf_task_delay(100); terminate_handler(); } /* Check the packet length. */ if(dpp->ori_len > POFDP_PACKET_RAW_MAX_LEN){ free_packet_data(dpp); POF_ERROR_HANDLE_NO_RETURN_NO_UPWARD(POFET_SOFTWARE_FAILED, POF_PACKET_LEN_ERROR); continue; } /* Check whether the first flow table exist. */ if(POF_OK != poflr_check_flow_table_exist(POFDP_FIRST_TABLE_ID)){ POF_DEBUG_CPRINT_FL(1,RED,"Received a packet, but the first flow table does NOT exist."); free_packet_data(dpp); continue; } /* Forward the packet. */ ret = pofdp_forward(dpp, first_ins); POF_CHECK_RETVALUE_NO_RETURN_NO_UPWARD(ret); free_packet_data(dpp); POF_DEBUG_CPRINT_FL(1,GREEN,"one packet_raw has been processed!\n"); } return POF_OK; }
/*********************************************************************** * The task function for connection and state machine task. * Form: void pofsc_main_task(void *arg_ptr) * Input: NONE * Output: NONE * Return: VOID * Discribe: This task function keeps running the state machine of Soft * Switch. The Soft Switch always works on one of states. * Before the POFCS_CHANNEL_RUN state, this function * builds the connection with the Cntroller by sending and * receiving the "Hello" packet, replying the requests from the * Controller, and so on. During the POFCS_CHANNEL_RUN state, * it receive OpenFlow messages from the Controller and send * them to the other modules to handle. ***********************************************************************/ static uint32_t pofsc_main_task(void *arg_ptr){ pofsc_dev_conn_desc *conn_desc_ptr = (pofsc_dev_conn_desc *)&pofsc_conn_desc; pof_header *head_ptr, head; int total_len = 0, tmp_len, left_len, rcv_len = 0, process_len = 0, packet_len = 0; int socket_fd; uint32_t ret; /* Clear error record. */ pofsc_protocol_error.type = 0xffff; /* State machine of the control module in Soft Switch. */ while(1) { if(conn_desc_ptr->conn_status.state != POFCS_CHANNEL_RUN && !conn_desc_ptr->conn_retry_count){ POF_DEBUG_CPRINT_FL(1,BLUE, ">>Openflow Channel State: %s", pofsc_state_str[conn_desc_ptr->conn_status.state]); } switch(conn_desc_ptr->conn_status.state){ case POFCS_CHANNEL_INVALID: /* Create openflow channel socket. */ ret = pofsc_create_socket(&socket_fd); if(ret == POF_OK){ conn_desc_ptr->sfd = socket_fd; conn_desc_ptr->conn_status.state = POFCS_CHANNEL_CONNECTING; }else{ POF_ERROR_CPRINT_FL(1,RED,">>Create socket FAIL!"); terminate_handler(); } break; case POFCS_CHANNEL_CONNECTING: /* Connect controller. */ if(!conn_desc_ptr->conn_retry_count){ POF_PRINT(1,GREEN,">>Connecting to POFController...\n"); } ret = pofsc_connect(conn_desc_ptr->sfd, conn_desc_ptr->controller_ip, conn_desc_ptr->controller_port); if(ret == POF_OK){ POF_DEBUG_CPRINT_FL(1,GREEN,">>Connect to controler SUC! %s: %u", \ pofsc_controller_ip_addr, POF_CONTROLLER_PORT_NUM); conn_desc_ptr->conn_status.state = POFCS_CHANNEL_CONNECTED; conn_desc_ptr->conn_retry_count = 0; }else{ if(!conn_desc_ptr->conn_retry_count){ POF_DEBUG_CPRINT_FL(1,RED,">>Connect to controler FAIL!"); } /* Delay several seconds. */ pofbf_task_delay(conn_desc_ptr->conn_retry_interval * 1000); conn_desc_ptr->conn_retry_count++; conn_desc_ptr->conn_status.last_error = (uint8_t)(POF_CONNECT_SERVER_FAILURE); /**/ conn_desc_ptr->sfd = 0; conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID; } break; case POFCS_CHANNEL_CONNECTED: /* Send hello to controller. Hello message has no body. */ pofsc_build_header(&head, \ POFT_HELLO, \ sizeof(pof_header), \ g_upward_xid++); /* send hello message. */ ret = pofsc_send(conn_desc_ptr->sfd, (char*)&head, sizeof(pof_header)); if(ret == POF_OK){ conn_desc_ptr->conn_status.state = POFCS_HELLO; }else{ POF_ERROR_CPRINT_FL(1,RED,"Send HELLO FAIL!"); } break; case POFCS_HELLO: /* Receive hello from controller. */ total_len = 0; left_len = 0; rcv_len = 0; process_len = 0; ret = pofsc_recv(conn_desc_ptr->sfd, conn_desc_ptr->recv_buf , POF_RECV_BUF_MAX_SIZE, &total_len); if(ret == POF_OK){ POF_DEBUG_CPRINT_FL(1,GREEN,">>Recevie HELLO packet SUC!"); poflr_clear_resource(); conn_desc_ptr->conn_status.state = POFCS_REQUEST_FEATURE; }else{ POF_ERROR_CPRINT_FL(1,RED,"Recv HELLO FAILE!"); break; } rcv_len += total_len; /* Parse. */ head_ptr = (pof_header *)conn_desc_ptr->recv_buf; while(total_len < POF_NTOHS(head_ptr->length)){ ret = pofsc_recv(conn_desc_ptr->sfd, conn_desc_ptr->recv_buf + rcv_len, POF_RECV_BUF_MAX_SIZE -rcv_len, &tmp_len); if(ret != POF_OK){ POF_ERROR_CPRINT_FL(1,RED,"Recv HELLO FAILE!"); break; } total_len += tmp_len; rcv_len += tmp_len; } if(conn_desc_ptr->conn_status.state == POFCS_CHANNEL_INVALID){ break; } /* Check any error. */ if(head_ptr->version > POF_VERSION){ POF_ERROR_CPRINT_FL(1,RED,"Version of recv-packet is higher than support!"); pofsc_set_error(POFET_HELLO_FAILED, POFHFC_INCOMPATIBLE); close(conn_desc_ptr->sfd); conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID; }else if(head_ptr->type != POFT_HELLO){ POF_ERROR_CPRINT_FL(1,RED,"Type of recv-packet is not HELLO, which we want to recv!"); pofsc_set_error(POFET_BAD_REQUEST, POFBRC_BAD_TYPE); close(conn_desc_ptr->sfd); conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID; } process_len += POF_NTOHS(head_ptr->length); left_len = rcv_len - process_len; if(left_len == 0){ rcv_len = 0; process_len = 0; } break; case POFCS_REQUEST_FEATURE: /* Wait to receive feature request from controller. */ head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len); if(!((left_len >= sizeof(pof_header))&&(left_len >= POF_NTOHS(head_ptr->length)))){ ret = pofsc_recv(conn_desc_ptr->sfd, (conn_desc_ptr->recv_buf + rcv_len), POF_RECV_BUF_MAX_SIZE - rcv_len, &total_len); if(ret == POF_OK){ conn_desc_ptr->conn_status.state = POFCS_SET_CONFIG; }else{ POF_ERROR_CPRINT_FL(1,RED,"Feature request FAIL!"); break; } rcv_len += total_len; total_len += left_len; head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len); while(total_len < POF_NTOHS(head_ptr->length)){ ret = pofsc_recv(conn_desc_ptr->sfd, ((conn_desc_ptr->recv_buf + rcv_len)), POF_RECV_BUF_MAX_SIZE-rcv_len ,&tmp_len); if(ret != POF_OK){ POF_ERROR_CPRINT_FL(1,RED,"Feature request FAIL!"); break; } total_len += tmp_len; rcv_len += tmp_len; } } if(conn_desc_ptr->conn_status.state == POFCS_CHANNEL_INVALID){ break; } head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len); /* Check any error. */ if(head_ptr->type != POFT_FEATURES_REQUEST){ pofsc_set_error(POFET_BAD_REQUEST, POFBRC_BAD_TYPE); close(conn_desc_ptr->sfd); conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID; break; } POF_DEBUG_CPRINT_FL(1,GREEN,">>Recevie FEATURE_REQUEST packet SUC!"); conn_desc_ptr->conn_status.state = POFCS_SET_CONFIG; packet_len = POF_NTOHS(head_ptr->length); ret = pof_parse_msg_from_controller(conn_desc_ptr->recv_buf + process_len); if(ret != POF_OK){ POF_ERROR_CPRINT_FL(1,RED,"Features request FAIL!"); terminate_handler(); break; } process_len += packet_len; left_len = rcv_len - process_len; if(left_len == 0){ rcv_len = 0; process_len = 0; } break; case POFCS_SET_CONFIG: /* Receive set_config message from controller. */ head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len); if(!((left_len >= sizeof(pof_header))&&(left_len >= POF_NTOHS(head_ptr->length)))){ ret = pofsc_recv(conn_desc_ptr->sfd, (conn_desc_ptr->recv_buf + rcv_len), POF_RECV_BUF_MAX_SIZE - rcv_len, &total_len); if(ret == POF_OK){ conn_desc_ptr->conn_status.state = POFCS_REQUEST_GET_CONFIG; }else{ POF_ERROR_CPRINT_FL(1,RED,"Set config FAIL!"); break; } rcv_len += total_len; total_len += left_len; head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len); while(total_len < POF_NTOHS(head_ptr->length)){ ret = pofsc_recv(conn_desc_ptr->sfd, ((conn_desc_ptr->recv_buf + rcv_len)), POF_RECV_BUF_MAX_SIZE-rcv_len ,&tmp_len); if(ret != POF_OK){ POF_ERROR_CPRINT_FL(1,RED,"Set config FAIL!"); break; } total_len += tmp_len; rcv_len += tmp_len; } } if(conn_desc_ptr->conn_status.state == POFCS_CHANNEL_INVALID){ break; } head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len); /* Check any error. */ if(head_ptr->version > POF_VERSION){ POF_ERROR_CPRINT_FL(1,RED,"Version of recv-packet is higher than support!"); pofsc_set_error(POFET_BAD_REQUEST, POFHFC_INCOMPATIBLE); POF_ERROR_CPRINT_FL(1,RED,"Set config FAIL!"); close(conn_desc_ptr->sfd); conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID; break; }else if(head_ptr->type != POFT_SET_CONFIG){ POF_ERROR_CPRINT_FL(1,RED,"Type of recv-packet is not SET_CONFIG, which we want to recv!"); pofsc_set_error(POFET_BAD_REQUEST, POFBRC_BAD_TYPE); POF_ERROR_CPRINT_FL(1,RED,"Set config FAIL!"); close(conn_desc_ptr->sfd); conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID; break; } POF_DEBUG_CPRINT_FL(1,BLUE,">>Recevie SET_CONFIG packet SUC!"); conn_desc_ptr->conn_status.state = POFCS_REQUEST_GET_CONFIG; packet_len = POF_NTOHS(head_ptr->length); ret = pof_parse_msg_from_controller(conn_desc_ptr->recv_buf + process_len); if(ret != POF_OK){ POF_ERROR_CPRINT_FL(1,RED,"Set config FAIL!"); terminate_handler(); break; } process_len += packet_len; left_len = rcv_len - process_len; if(left_len == 0){ rcv_len = 0; process_len = 0; } break; case POFCS_REQUEST_GET_CONFIG: /* Wait to receive feature request from controller. */ head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len); if(!((left_len >= sizeof(pof_header)) && (left_len >= POF_NTOHS(head_ptr->length)))){ ret = pofsc_recv(conn_desc_ptr->sfd, (conn_desc_ptr->recv_buf + rcv_len), POF_RECV_BUF_MAX_SIZE - rcv_len, &total_len); if(ret == POF_OK){ conn_desc_ptr->conn_status.state = POFCS_CHANNEL_RUN; }else{ POF_ERROR_CPRINT_FL(1,RED,"Get config FAIL!"); break; } rcv_len += total_len; total_len += left_len; head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len); while(total_len < POF_NTOHS(head_ptr->length)){ ret = pofsc_recv(conn_desc_ptr->sfd, ((conn_desc_ptr->recv_buf + rcv_len)), POF_RECV_BUF_MAX_SIZE-rcv_len ,&tmp_len); if(ret != POF_OK){ POF_ERROR_CPRINT_FL(1,RED,"Get config FAIL!"); break; } total_len += tmp_len; rcv_len += tmp_len; } } if(conn_desc_ptr->conn_status.state == POFCS_CHANNEL_INVALID){ break; } head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len); /* Check any error. */ if(head_ptr->type != POFT_GET_CONFIG_REQUEST){ pofsc_set_error(POFET_BAD_REQUEST, POFBRC_BAD_TYPE); POF_ERROR_CPRINT_FL(1,RED,"Get config FAIL!"); close(conn_desc_ptr->sfd); conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID; break; } POF_DEBUG_CPRINT_FL(1,GREEN,">>Recevie GET_CONFIG_REQUEST packet SUC!"); packet_len = POF_NTOHS(head_ptr->length); ret = pof_parse_msg_from_controller(conn_desc_ptr->recv_buf + process_len); if(ret != POF_OK){ POF_ERROR_CPRINT_FL(1,RED,"Get config FAIL!"); terminate_handler(); break; } process_len += packet_len; left_len = rcv_len - process_len; if(left_len == 0){ rcv_len = 0; process_len = 0; } sleep(1); conn_desc_ptr->conn_status.state = POFCS_CHANNEL_RUN; POF_PRINT(1,GREEN,">>Connect to POFController successfully!\n"); break; case POFCS_CHANNEL_RUN: /* Wait to receive feature request from controller. */ head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len); if(!((left_len >= sizeof(pof_header))&&(left_len >= POF_NTOHS(head_ptr->length)))){ /* Resv_buf has no space, so should move the left data to the head of the buf. */ if(POF_RECV_BUF_MAX_SIZE == rcv_len){ memcpy(conn_desc_ptr->recv_buf, conn_desc_ptr->recv_buf + process_len, left_len); rcv_len = left_len; process_len = 0; } ret = pofsc_recv(conn_desc_ptr->sfd, (conn_desc_ptr->recv_buf + rcv_len), POF_RECV_BUF_MAX_SIZE - rcv_len, &total_len); if(ret != POF_OK){ break; } rcv_len += total_len; total_len += left_len; head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len); while(total_len < POF_NTOHS(head_ptr->length)){ ret = pofsc_recv(conn_desc_ptr->sfd, ((conn_desc_ptr->recv_buf + rcv_len)), POF_RECV_BUF_MAX_SIZE-rcv_len ,&tmp_len); if(ret != POF_OK){ break; } total_len += tmp_len; rcv_len += tmp_len; } } if(conn_desc_ptr->conn_status.state == POFCS_CHANNEL_INVALID){ break; } head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len); packet_len = POF_NTOHS(head_ptr->length); /* Handle the message. Echo messages will be processed here and other messages will be forwarded to LUP. */ ret = pofsc_run_process(conn_desc_ptr->recv_buf + process_len, packet_len); process_len += packet_len; left_len = rcv_len - process_len; if(left_len == 0){ rcv_len = 0; process_len = 0; } break; default: conn_desc_ptr->conn_status.last_error = (uint8_t)POF_WRONG_CHANNEL_STATE; break; } /* If any error is detected, reply to controller immediately. */ if(pofsc_protocol_error.type != 0xffff){ tmp_len = 0; /* Build error message. */ (void)pofsc_build_error_msg(conn_desc_ptr->send_buf, (uint16_t*)&tmp_len); /* Write error message in queue for sending. */ ret = pofbf_queue_write(pofsc_send_q_id, conn_desc_ptr->send_buf, (uint32_t)tmp_len, POF_WAIT_FOREVER); POF_CHECK_RETVALUE_TERMINATE(ret); } } return; }
int main(int argc, char **argv) { char linebuf[MAXLINE]; char input_file[MAXLINE]; system_t *system; time_t t = time(NULL); struct tm tm = *localtime(&t); /* set the default rank */ rank = 0; size = 1; /* check args */ if(argc < 2) usage(argv[0]); /* start up the MPI chain */ #ifdef MPI MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); #endif /* MPI */ if( !rank ) { sprintf(linebuf, "MPMC (Massively Parallel Monte Carlo) r%d - 2012-2017 GNU Public License\n", VERSION); output(linebuf); sprintf(linebuf, "MAIN: processes started on %d cores @ %d-%d-%d %d:%d:%d\n", size, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); output(linebuf); } #ifndef MPI FILE *procfile; FILE *host; char nodename[MAXLINE]; char cpu[MAXLINE]; struct stat info; // These system calls were causing a fork() that does not play nice with some // MPI implementations (causing some processes to never end... ) /* Collect and output hostname & processor info */ if(access("/proc/cpuinfo",R_OK)!=-1) { // Linux host = popen("hostname","r"); fgets(nodename, MAXLINE, host); sprintf(linebuf, "MAIN: Job running on node -> %s", nodename); output(linebuf); pclose(host); procfile = fopen("/proc/cpuinfo", "r"); while (!feof(procfile)) { fgets(cpu, MAXLINE, procfile); if(strncasecmp(cpu,"model name",10)==0) { sprintf(linebuf, "MAIN: CPU -> %s", cpu); output(linebuf); break; } } fclose(procfile); } else if (stat("/Applications",&info)==0) { // Mac OS output("MAIN: Mac OS detected\n"); host = popen("hostname", "r"); fgets(nodename, MAXLINE, host); sprintf(linebuf, "MAIN: Job running on node -> %s", nodename); output(linebuf); pclose(host); procfile = popen("sysctl -n machdep.cpu.brand_string","r"); fgets(cpu, MAXLINE, procfile); sprintf(linebuf, "MAIN: CPU -> %s", cpu); output(linebuf); pclose(procfile); } #endif // !MPI /* get the config file arg */ strcpy(input_file, argv[1]); sprintf(linebuf, "MAIN: running parameters found in %s\n", input_file); output(linebuf); /* read the input files and setup the simulation */ system = setup_system(input_file); if(!system) { error("MAIN: could not initialize the simulation\n"); die(1); } else { output("MAIN: the simulation has been initialized\n"); } /* install the signal handler to catch SIGTERM cleanly */ terminate_handler(-1, system); signal(SIGTERM, ((void *)(terminate_handler))); signal(SIGUSR1, ((void *)(terminate_handler))); signal(SIGUSR2, ((void *)(terminate_handler))); output("MAIN: signal handler installed\n"); /* allocate space for the statistics */ system->nodestats = calloc(1, sizeof(nodestats_t)); memnullcheck(system->nodestats,sizeof(nodestats_t), __LINE__-1, __FILE__); system->avg_nodestats = calloc(1, sizeof(avg_nodestats_t)); memnullcheck(system->avg_nodestats,sizeof(avg_nodestats_t), __LINE__-1, __FILE__); system->observables = calloc(1, sizeof(observables_t)); memnullcheck(system->observables,sizeof(observables_t), __LINE__-1, __FILE__); system->avg_observables = calloc(1, sizeof(avg_observables_t)); memnullcheck(system->avg_observables,sizeof(avg_observables_t), __LINE__-1, __FILE__); system->checkpoint = calloc(1, sizeof(checkpoint_t)); memnullcheck(system->checkpoint,sizeof(checkpoint_t), __LINE__-1, __FILE__); system->checkpoint->observables = calloc(1, sizeof(observables_t)); memnullcheck(system->checkpoint->observables,sizeof(observables_t), __LINE__-1, __FILE__); system->grids = calloc(1,sizeof(grid_t)); memnullcheck(system->grids,sizeof(grid_t), __LINE__-1, __FILE__); system->grids->histogram = calloc(1,sizeof(histogram_t)); memnullcheck(system->grids->histogram,sizeof(histogram_t), __LINE__-1, __FILE__); system->grids->avg_histogram = calloc(1,sizeof(histogram_t)); memnullcheck(system->grids->avg_histogram,sizeof(histogram_t), __LINE__-1, __FILE__); /* if polarization active, allocate the necessary matrices */ if(system->polarization && !system->cuda && !system->polar_zodid) thole_resize_matrices(system); /* if histogram calculation flag is set, allocate grid */ if(system->calc_hist){ setup_histogram(system); allocate_histogram_grid(system); } /* seed the rng if neccessary */ if ( system->ensemble != ENSEMBLE_TE && system->ensemble != ENSEMBLE_REPLAY ) seed_rng(system, rank); #ifdef MPI MPI_Barrier(MPI_COMM_WORLD); sprintf(linebuf, "MAIN: all %d cores are in sync\n", size); output(linebuf); #endif /* MPI */ /* start the MC simulation */ if(system->ensemble == ENSEMBLE_UVT) { output("MAIN: *******************************************************\n"); output("MAIN: *** starting Grand Canonical Monte Carlo simulation ***\n"); output("MAIN: *******************************************************\n"); } else if(system->ensemble == ENSEMBLE_NVT) { output("MAIN: *************************************************\n"); output("MAIN: *** starting Canonical Monte Carlo simulation ***\n"); output("MAIN: *************************************************\n"); } else if(system->ensemble == ENSEMBLE_NVE) { output("MAIN: ******************************************************\n"); output("MAIN: *** starting Microcanonical Monte Carlo simulation ***\n"); output("MAIN: ******************************************************\n"); } else if(system->ensemble == ENSEMBLE_SURF) { /* surface run */ output("MAIN: *****************************************************\n"); output("MAIN: *** starting potential energy surface calculation ***\n"); output("MAIN: *****************************************************\n"); } else if(system->ensemble == ENSEMBLE_REPLAY) { /* surface fitting run */ output("MAIN: **********************************\n"); output("MAIN: *** starting trajectory replay ***\n"); output("MAIN: **********************************\n"); } else if(system->ensemble == ENSEMBLE_SURF_FIT) { /* surface fitting run */ output("MAIN: *************************************************************\n"); output("MAIN: *** starting potential energy surface fitting calculation ***\n"); output("MAIN: *************************************************************\n"); } else if(system->ensemble == ENSEMBLE_TE) { /* surface fitting run */ output("MAIN: *************************************************\n"); output("MAIN: *** starting single-point energy calculation ***\n"); output("MAIN: *************************************************\n"); } if(system->ensemble == ENSEMBLE_SURF) { /* surface */ if(surface(system) < 0) { error("MAIN: surface module failed on error, exiting\n"); die(1); } } else if(system->ensemble == ENSEMBLE_SURF_FIT) { /* surface fitting */ if( system->surf_fit_arbitrary_configs ) { if( surface_fit_arbitrary( system ) < 0 ) { error("MAIN: surface fitting module (for arbitrary configurations) failed on error, exiting\n"); die(1); } } else if(surface_fit(system) < 0) { error("MAIN: surface fitting module failed on error, exiting\n"); die(1); } } else if(system->ensemble == ENSEMBLE_REPLAY) { /* replay trajectory and recalc energies, etc. */ if(replay_trajectory(system) < 0) { error("MAIN: trajectory replay failed, exiting\n"); die(1); } } else if(system->ensemble == ENSEMBLE_TE) { if(calculate_te(system) < 0) { error("MAIN: single-point energy calculation failed, exiting\n"); die(1); } } else { //else run monte carlo if(mc(system) < 0) { error("MAIN: MC failed on error, exiting\n"); die(1); } } /* cleanup */ output("MAIN: freeing all data structures...."); cleanup(system); output("...done\n"); output("MAIN: simulation exiting successfully\n\n"); die(0); return 0; }
/*********************************************************************** * The task function of receive task * Form: static void pofdp_recv_raw_task(void *arg_ptr) * Input: port infomation * Output: NONE * Return: VOID * Discribe: This is the task function of receive task, which is infinite * loop running. It receives RAW packet by binding socket to the * local physical net port spicified in the port infomation. * After filtering, the packet data and port infomation will be * assembled with format of struct pofdp_packet, and be send * into the receive queue. The only parameter arg_ptr is the * pointer of the local physical net port infomation which has * been assembled with format of struct pof_port. * NOTE: This task will be terminated if any ERRORs occur. * If the openflow function of this physical port is disable, * it will be still loop running but nothing will be received. ***********************************************************************/ static uint32_t pofdp_recv_raw_task(void *arg_ptr){ pof_port *port_ptr = (pof_port *)arg_ptr; struct pofdp_packet *dpp = malloc(sizeof *dpp); struct sockaddr_ll sockadr, from; uint32_t from_len, len_B; uint8_t buf[POFDP_PACKET_RAW_MAX_LEN]; int sock; from_len = sizeof(struct sockaddr_ll); /* Create socket, and bind it to the specific port. */ if((sock = socket(AF_PACKET, SOCK_RAW, POF_HTONS(ETH_P_ALL))) == -1){ POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_CREATE_SOCKET_FAILURE, g_upward_xid++); /* Delay 0.1s to send error message upward to the Controller. */ pofbf_task_delay(100); terminate_handler(); } sockadr.sll_family = AF_PACKET; sockadr.sll_protocol = POF_HTONS(ETH_P_ALL); sockadr.sll_ifindex = port_ptr->port_id; if(bind(sock, (struct sockaddr *)&sockadr, sizeof(struct sockaddr_ll)) != 0){ POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_BIND_SOCKET_FAILURE, g_upward_xid++); /* Delay 0.1s to send error message upward to the Controller. */ pofbf_task_delay(100); terminate_handler(); } /* Receive the raw packet through the specific port. */ while(1){ pthread_testcancel(); /* Receive the raw packet. */ if((len_B = recvfrom(sock, buf, POFDP_PACKET_RAW_MAX_LEN, 0, (struct sockaddr *)&from, &from_len)) <=0){ POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_RECEIVE_MSG_FAILURE, g_upward_xid++); continue; } /* Check whether the OpenFlow-enabled of the port is on or not. */ if(port_ptr->of_enable == POFLR_PORT_DISABLE){ continue; } /* Check the packet length. */ if(len_B > POF_MTU_LENGTH){ POF_DEBUG_CPRINT_FL(1,RED,"The packet received is longer than MTU. DROP!"); continue; } /* Filter the received raw packet by some rules. */ if(pofdp_packet_raw_filter(buf, port_ptr) != POF_OK){ continue; } /* Store packet data, length, received port infomation into the message queue. */ memset(dpp, 0, sizeof *dpp); dpp->ori_port_id = port_ptr->port_id; malloc_packet_data(dpp, len_B); memcpy(dpp->buf, buf, len_B); if(pofbf_queue_write(g_pofdp_recv_q_id, dpp, sizeof *dpp, POF_WAIT_FOREVER) != POF_OK){ POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_WRITE_MSG_QUEUE_FAILURE, g_upward_xid++); free_packet_data(dpp); pofbf_task_delay(100); terminate_handler(); } } close(sock); return POF_OK; }