INT4 clear_flow_entries(gn_switch_t *sw) { gn_flow_t flow; gn_flow_t *p_flow_tmp, *p_flow = sw->flow_entries; gn_instruction_actions_t instruction; gn_action_output_t action; if((NULL == sw) || (sw->conn_state == INITSTATE)) { return GN_ERR; } //删除所有流表 memset(&flow, 0, sizeof(gn_flow_t)); flow.table_id = OFPTT_ALL; flow.idle_timeout = 0; flow.hard_timeout = 0; flow.priority = 0; flow.match.type = OFPMT_OXM; send_flow_mod(sw, &flow, OFPFC_DELETE); //下发table miss流表 memset(&flow, 0, sizeof(gn_flow_t)); flow.create_time = 0; flow.table_id = 0; flow.idle_timeout = 0; flow.hard_timeout = 0; flow.priority = 0; flow.match.type = OFPMT_OXM; memset(&instruction, 0, sizeof(gn_instruction_actions_t)); instruction.type = OFPIT_APPLY_ACTIONS; instruction.next = flow.instructions; flow.instructions = (gn_instruction_t *)&instruction; memset(&action, 0, sizeof(gn_action_t)); action.port = OFPP13_CONTROLLER; action.type = OFPAT13_OUTPUT; action.next = instruction.actions; action.max_len = 0xffff; instruction.actions = (gn_action_t *)&action; send_flow_mod(sw, &flow, OFPFC_ADD); sw->flow_entries = NULL; pthread_mutex_lock(&sw->flow_entry_mutex); while(p_flow) { p_flow_tmp = p_flow->next; //recycle the memory gn_flow_free(p_flow); p_flow = p_flow_tmp; } pthread_mutex_unlock(&sw->flow_entry_mutex); return GN_OK; }
INT4 disable_flow_entry(gn_switch_t *sw, gn_flow_t *flow) { gn_flow_t *p_flow = NULL; if(sw->conn_state == INITSTATE) { return GN_ERR; } pthread_mutex_lock(&sw->flow_entry_mutex); p_flow = find_flow_entry_by_id(sw, flow); if(NULL == p_flow) { pthread_mutex_unlock(&sw->flow_entry_mutex); goto ERROR; } send_flow_mod(sw, p_flow, OFPFC_DELETE_STRICT); flow->status = ENTRY_DISABLED; pthread_mutex_unlock(&sw->flow_entry_mutex); return GN_OK; ERROR: pthread_mutex_unlock(&sw->flow_entry_mutex); return GN_ERR; }
INT4 enable_flow_entry(gn_switch_t *sw, gn_flow_t *flow) { gn_flow_t *p_flow = NULL; INT4 ret = 0; if(sw->conn_state == INITSTATE) { return GN_ERR; } pthread_mutex_lock(&sw->flow_entry_mutex); p_flow = find_flow_entry_by_id(sw, flow); if(NULL == p_flow) { p_flow = flow; } ret = send_flow_mod(sw, p_flow, OFPFC_ADD); if(GN_OK != ret) { pthread_mutex_unlock(&sw->flow_entry_mutex); return ret; } p_flow->status = ENTRY_ENABLED; pthread_mutex_unlock(&sw->flow_entry_mutex); return GN_OK; }
//该函数有疑问,需要修改 INT4 modify_flow_entry(gn_switch_t *sw, gn_flow_t *flow) { INT4 ret = 0; gn_flow_t *p_flow = NULL; if(sw->conn_state == INITSTATE) { return GN_ERR; } pthread_mutex_lock(&sw->flow_entry_mutex); p_flow = find_flow_entry_by_id(sw, flow); if(NULL == p_flow) { ret = EC_FLOW_NOT_EXIST; gn_flow_free(flow); pthread_mutex_unlock(&sw->flow_entry_mutex); return ret; } else { //modify flow entry from list gn_instruction_t *p_ins = p_flow->instructions; p_flow->instructions = flow->instructions; flow->instructions = p_ins; ret = send_flow_mod(sw, p_flow, OFPFC_MODIFY_STRICT); p_flow->status = ENTRY_ENABLED; pthread_mutex_unlock(&sw->flow_entry_mutex); return ret; } }
static void handle_packet_in( uint64_t datapath_id, packet_in message ) { UNUSED( datapath_id ); packet_info packet_info = get_packet_info( message.data ); traffic *db = message.user_data; uint8_t *macsa = packet_info.eth_macsa; uint8_t *macda = packet_info.eth_macda; learn_fdb( db->fdb, macsa, message.in_port ); add_counter( db->counter, macsa, 1, message.data->length ); uint16_t out_port = lookup_fdb( db->fdb, macda ); if ( out_port != ENTRY_NOT_FOUND_IN_FDB ) { send_packet_out( datapath_id, &message, out_port ); send_flow_mod( datapath_id, macsa, macda, out_port ); } else { do_flooding( datapath_id, &message ); } }
INT4 delete_flow_entry(gn_switch_t *sw, gn_flow_t *flow) { gn_flow_t *p_flow = NULL; if(sw->conn_state == INITSTATE) { return EC_SW_STATE_ERR; } pthread_mutex_lock(&sw->flow_entry_mutex); p_flow = find_flow_entry_by_id(sw, flow); if(NULL == p_flow) { pthread_mutex_unlock(&sw->flow_entry_mutex); return EC_FLOW_NOT_EXIST; } send_flow_mod(sw, p_flow, OFPFC_DELETE_STRICT); //delete flow entry from list if(p_flow->next) { p_flow->next->prev = p_flow->prev; } if(p_flow->prev) { p_flow->prev->next = p_flow->next; } else { sw->flow_entries = p_flow->next; } //recycle the memory gn_flow_free(p_flow); pthread_mutex_unlock(&sw->flow_entry_mutex); return GN_OK; }