/* * usbrecords_find * check if we can recover device based on recovery queue * @param[t_token] recovery token to compare against * @ret -1 unable to recover, 0 success (token->user_data has handle) */ int usbrecords_find(transport_recovery_token_t *t_token) { int rc = -1; recovery_entry_t *item; recovery_entry_t *tmp_item; platform_mutex_lock(&recovery_lock); /* check all entries */ for (item = TAILQ_FIRST(&t_recovery_queue); item != NULL; item = tmp_item) { transport_recovery_token_t *token = item->t_token; tmp_item = TAILQ_NEXT(item, entries); if (token->len == t_token->len) { if( 0 == memcmp(token->token, t_token->token, token->len) ) { TRACEF("Matches, nduid(%s)\n", token->nduid); /* Remove the item from queue. */ TAILQ_REMOVE(&t_recovery_queue, item, entries); /* restore handle */ t_token->user_data = token->user_data; /* Free the item as we don't need it anymore. */ platform_free(item->t_token); platform_free(item); /* success */ rc = 0; break; } } } platform_mutex_unlock(&recovery_lock); return rc; }
int MQTTYield(MQTTClient* c, int timeout_ms) { int rc = MQTT_SUCCESS; Timer timer; platform_timer_init(&timer); platform_timer_countdown(&timer, timeout_ms); if (!c->isconnected) return rc; do { platform_mutex_lock(&c->mutex); rc = cycle(c, &timer); platform_mutex_unlock(&c->mutex); if (rc != MQTT_SUCCESS) break; } while (!platform_timer_isexpired(&timer)); return rc; }
//Add/remove methods rofl_result_t physical_switch_add_logical_switch(of_switch_t* sw){ int i; if(physical_switch_get_logical_switch_by_dpid(sw->dpid)) return ROFL_FAILURE; //Serialize platform_mutex_lock(psw->mutex); // check bounds if(psw->num_of_logical_switches == PHYSICAL_SWITCH_MAX_LS){ //Serialize platform_mutex_unlock(psw->mutex); return ROFL_FAILURE; } //Look for an available slot for(i=0;i<PHYSICAL_SWITCH_MAX_LS;i++){ if(!psw->logical_switches[i]) break; } psw->logical_switches[i] = sw; psw->num_of_logical_switches++; platform_mutex_unlock(psw->mutex); return ROFL_SUCCESS; }
/* * usbrecords_update * @param[elapsed] elapsed time * @ret 0 - success, -1 error */ int usbrecords_update(int elapsed) { recovery_entry_t *item; recovery_entry_t *tmp_item; LTRACEF("Update records\n"); platform_mutex_lock(&recovery_lock); /* check all entries */ for (item = TAILQ_FIRST(&t_recovery_queue); item != NULL; item = tmp_item) { tmp_item = TAILQ_NEXT(item, entries); /* update remaining recovery time */ item->timeout -= elapsed; PTRACEF(USB_RECOVERY, "Check entry(%p): timeout %d\n", item, item->timeout); /* expired? */ if(item->timeout < 0) { TRACEF("expired timeout::destroy record\n"); /* destroy handle */ novacom_usbll_destroy((novacom_usbll_handle_t)item->t_token->user_data); /* Remove the item from queue. */ TAILQ_REMOVE(&t_recovery_queue, item, entries); /* Free the item as we don't need it anymore. */ platform_free(item->t_token); platform_free(item); } } platform_mutex_unlock(&recovery_lock); return 0; }
/* * usbrecords_remove * @param[nduid] device nduid * @ret 0 - success, -1 error */ int usbrecords_remove(char *nduid) { recovery_entry_t *item; recovery_entry_t *tmp_item; LTRACEF("Update records\n"); platform_mutex_lock(&recovery_lock); /* check all entries */ for (item = TAILQ_FIRST(&t_recovery_queue); item != NULL; item = tmp_item) { tmp_item = TAILQ_NEXT(item, entries); if(0 == strncmp(item->t_token->nduid, nduid, sizeof(item->t_token->nduid)) ) { TRACEF("explicit remove::nduid(%s)\n", nduid); /* destroy handle */ novacom_usbll_destroy((novacom_usbll_handle_t)item->t_token->user_data); /* Remove the item from queue. */ TAILQ_REMOVE(&t_recovery_queue, item, entries); /* Free the item as we don't need it anymore. */ platform_free(item->t_token); platform_free(item); } } platform_mutex_unlock(&recovery_lock); return 0; }
int MQTTUnsubscribe(MQTTClient* c, const char* topicFilter) { int rc = MQTT_FAILURE; Timer timer; MQTTString topic = MQTTString_initializer; topic.cstring = (char *)topicFilter; int len = 0; platform_mutex_lock(&c->mutex); if (!c->isconnected) goto exit; platform_timer_init(&timer); platform_timer_countdown(&timer, c->command_timeout_ms); if ((len = MQTTSerialize_unsubscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic)) <= 0) goto exit; if ((rc = sendPacket(c, len, &timer)) != MQTT_SUCCESS) // send the subscribe packet goto exit; // there was a problem if (waitfor(c, UNSUBACK, &timer) == UNSUBACK) { unsigned short mypacketid; // should be the same as the packetid above if (MQTTDeserialize_unsuback(&mypacketid, c->readbuf, c->readbuf_size) == 1) rc = 0; } else { rc = MQTT_CONNECTION_LOST; } exit: platform_mutex_unlock(&c->mutex); return rc; }
//LSIs dpid_list_t* physical_switch_get_all_lsi_dpids(void){ int i,j; dpid_list_t* list; list = platform_malloc_shared(sizeof(dpid_list_t)); //Prevent management actions to screw the walk through the LSIs platform_mutex_lock(psw->mutex); //Set the number of elements list->num_of_lsis = psw->num_of_logical_switches; //Allocate the list space list->dpids = platform_malloc_shared(sizeof(uint64_t)*list->num_of_lsis); if(!list->dpids){ platform_mutex_unlock(psw->mutex); return NULL; } //Fill it with 0s platform_memset(list->dpids,0,sizeof(uint64_t)*list->num_of_lsis); for(i=0,j=0;i<PHYSICAL_SWITCH_MAX_LS;i++){ if(psw->logical_switches[i]){ list->dpids[j] = psw->logical_switches[i]->dpid; j++; } } platform_mutex_unlock(psw->mutex); return list; }
/* * Attempts to add a port to the physical switch pool port */ rofl_result_t physical_switch_add_port(switch_port_t* port){ unsigned int i, max; switch_port_t** array = NULL; if( unlikely(port==NULL) ) return ROFL_FAILURE; ROFL_PIPELINE_DEBUG("Trying to add port(%p) named %s to the physical switch\n", port, port->name); if(physical_switch_get_port_by_name(port->name)){ ROFL_PIPELINE_DEBUG("There is already a port named:%s in the physical switch\n",port->name); return ROFL_FAILURE; } //Serialize platform_mutex_lock(psw->mutex); switch(port->type){ case PORT_TYPE_PHYSICAL: max = PHYSICAL_SWITCH_MAX_NUM_PHY_PORTS; array = psw->physical_ports; break; case PORT_TYPE_VIRTUAL: max = PHYSICAL_SWITCH_MAX_NUM_VIR_PORTS; array = psw->virtual_ports; break; case PORT_TYPE_TUNNEL: max = PHYSICAL_SWITCH_MAX_NUM_TUN_PORTS; array = psw->tunnel_ports; break; default: //Invalid type platform_mutex_unlock(psw->mutex); return ROFL_FAILURE; } //Look for the first empty slot for(i=0;i<max;i++){ if(array[i] == NULL){ array[i] = port; platform_mutex_unlock(psw->mutex); return ROFL_SUCCESS; } } platform_mutex_unlock(psw->mutex); //No free slots left in the pool ROFL_PIPELINE_DEBUG("Insertion failed of port(%p); no available slots\n",port); return ROFL_FAILURE; }
STATIC_ATOMIC_INLINE__ void platform_atomic_add32(uint32_t* counter, uint32_t value, platform_mutex_t* mutex) { #if defined(__GNUC__) || defined(__INTEL_COMPILER) __sync_add_and_fetch(counter, value); #else platform_mutex_lock(mutex); (*counter)+=value; platform_mutex_unlock(mutex); #endif }
STATIC_ATOMIC_INLINE__ void platform_atomic_dec32(uint32_t* counter, platform_mutex_t* mutex) { #if defined(__GNUC__) || defined(__INTEL_COMPILER) __sync_sub_and_fetch(counter, 1); #else platform_mutex_lock(mutex); (*counter)--; platform_mutex_unlock(mutex); #endif }
/// these functins increase by one the counter STATIC_ATOMIC_INLINE__ void platform_atomic_inc64(uint64_t* counter, platform_mutex_t* mutex) { #if defined(__GNUC__) || defined(__INTEL_COMPILER) __sync_add_and_fetch(counter, 1UL); #else platform_mutex_lock(mutex); (*counter)++; platform_mutex_unlock(mutex); #endif }
/* * Removes and destroys a port from the physical_switch pool referenced by its name */ rofl_result_t physical_switch_remove_port(const char* name){ unsigned int i; switch_port_t* port; if( unlikely(name==NULL) ) return ROFL_FAILURE; //Serialize platform_mutex_lock(psw->mutex); //Looking in the physical ports list for(i=0;i<PHYSICAL_SWITCH_MAX_NUM_PHY_PORTS;i++){ if( psw->physical_ports[i] != NULL && strncmp(psw->physical_ports[i]->name, name, SWITCH_PORT_MAX_LEN_NAME) == 0 ){ port = psw->physical_ports[i]; psw->physical_ports[i] = NULL; platform_mutex_unlock(psw->mutex); switch_port_destroy(port); return ROFL_SUCCESS; } } //Looking in the virtual ports list for(i=0;i<PHYSICAL_SWITCH_MAX_NUM_VIR_PORTS;i++){ if( psw->virtual_ports[i] != NULL && strncmp(psw->virtual_ports[i]->name, name, SWITCH_PORT_MAX_LEN_NAME) == 0 ){ port = psw->virtual_ports[i]; psw->virtual_ports[i] = NULL; platform_mutex_unlock(psw->mutex); switch_port_destroy(port); return ROFL_SUCCESS; } } //Looking in the tunnel ports list for(i=0;i<PHYSICAL_SWITCH_MAX_NUM_TUN_PORTS;i++){ if( psw->tunnel_ports[i] != NULL && strncmp(psw->tunnel_ports[i]->name, name, SWITCH_PORT_MAX_LEN_NAME) == 0 ){ port = psw->tunnel_ports[i]; psw->tunnel_ports[i] = NULL; platform_mutex_unlock(psw->mutex); switch_port_destroy(port); return ROFL_SUCCESS; } } platform_mutex_unlock(psw->mutex); //Port not found return ROFL_FAILURE; }
int MQTTisConnected(MQTTClient* c) { int ret = 0; platform_mutex_lock(&c->mutex); if (c) ret = c->isconnected; platform_mutex_unlock(&c->mutex); return ret; }
/* Conveniently wraps call with mutex. */ rofl_of1x_fm_result_t of1x_add_flow_entry_loop(of1x_flow_table_t *const table, of1x_flow_entry_t *const entry, bool check_overlap, bool reset_counts){ rofl_of1x_fm_result_t return_value; //Allow single add/remove operation over the table platform_mutex_lock(table->mutex); return_value = of1x_add_flow_entry_table_imp(table, entry, check_overlap, reset_counts); //Green light to other threads platform_mutex_unlock(table->mutex); return return_value; }
rofl_result_t physical_switch_detach_port_num_from_logical_switch(unsigned int port_num, of_switch_t* sw){ rofl_result_t return_val; if( unlikely(sw==NULL) ) return ROFL_FAILURE; //Serialize platform_mutex_lock(psw->mutex); return_val = __of_detach_port_from_switch_by_port_num(sw, port_num); platform_mutex_unlock(psw->mutex); return return_val; }
rofl_result_t physical_switch_attach_port_to_logical_switch_at_port_num(switch_port_t* port, of_switch_t* sw, unsigned int port_num){ rofl_result_t return_val; if( unlikely(sw==NULL) || unlikely(port==NULL) || unlikely(port->attached_sw!=NULL) ) return ROFL_FAILURE; //Serialize platform_mutex_lock(psw->mutex); return_val = __of_attach_port_to_switch_at_port_num(sw, port_num, port); platform_mutex_unlock(psw->mutex); return return_val; }
rofl_result_t physical_switch_detach_all_ports_from_logical_switch(of_switch_t* sw){ rofl_result_t return_val; if( unlikely(sw==NULL) ) return ROFL_FAILURE; //Serialize platform_mutex_lock(psw->mutex); return_val = __of_detach_all_ports_from_switch(sw); platform_mutex_unlock(psw->mutex); return return_val; }
int MQTTConnect(MQTTClient* c, MQTTPacket_connectData* options) { Timer connect_timer; int rc = MQTT_FAILURE; MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer; int len = 0; platform_mutex_lock(&c->mutex); if (c->isconnected) /* don't send connect packet again if we are already connected */ goto exit; platform_timer_init(&connect_timer); platform_timer_countdown(&connect_timer, c->command_timeout_ms); if (options == 0) options = &default_options; /* set default options if none were supplied */ c->ping_outstanding = 0; c->keepAliveInterval = options->keepAliveInterval; platform_timer_countdown(&c->ping_timer, c->keepAliveInterval*1000); if ((len = MQTTSerialize_connect(c->buf, c->buf_size, options)) <= 0) goto exit; if ((rc = sendPacket(c, len, &connect_timer)) != MQTT_SUCCESS) // send the connect packet goto exit; // there was a problem // this will be a blocking call, wait for the connack if (waitfor(c, CONNACK, &connect_timer) == CONNACK) { unsigned char connack_rc = 255; unsigned char sessionPresent = 0; if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, c->readbuf, c->readbuf_size) == 1) rc = connack_rc; else rc = MQTT_FAILURE; } else rc = MQTT_FAILURE; exit: if (rc == MQTT_SUCCESS) c->isconnected = 1; platform_mutex_unlock(&c->mutex); return rc; }
/* * usbrecords_add * save recovery records in array * @param[t_token] recovery token * @ret 0 - success, -1 error */ int usbrecords_add(transport_recovery_token_t *t_token) { int rc = -1; recovery_entry_t *item = (recovery_entry_t *)platform_calloc(sizeof(recovery_entry_t)); if(item) { LTRACEF("* add token data(%p)\n", t_token->token); item->t_token = t_token; item->timeout = g_recovery_timeout; platform_mutex_lock(&recovery_lock); TAILQ_INSERT_TAIL(&t_recovery_queue, item, entries); platform_mutex_unlock(&recovery_lock); rc = 0; } return rc; }
/* Destructor. Table object is freed by pipeline destructor */ rofl_result_t __of1x_destroy_table(of1x_flow_table_t* table){ platform_mutex_lock(table->mutex); platform_rwlock_wrlock(table->rwlock); //Let the matching algorithm destroy its own state if(of1x_matching_algorithms[table->matching_algorithm].destroy_hook) of1x_matching_algorithms[table->matching_algorithm].destroy_hook(table); platform_mutex_destroy(table->mutex); platform_rwlock_destroy(table->rwlock); //Destroy stats __of1x_stats_table_destroy(table); //Do NOT free table, since it was allocated in a single buffer in pipeline.c return ROFL_SUCCESS; }
rofl_result_t of1x_remove_flow_entry_loop(of1x_flow_table_t *const table , of1x_flow_entry_t *const entry, of1x_flow_entry_t *const specific_entry, const enum of1x_flow_removal_strictness strict, uint32_t out_port, uint32_t out_group, of1x_flow_remove_reason_t reason, of1x_mutex_acquisition_required_t mutex_acquired){ rofl_result_t result; //Allow single add/remove operation over the table if(!mutex_acquired){ platform_mutex_lock(table->mutex); } result = of1x_remove_flow_entry_table_imp(table, entry, specific_entry, out_port, out_group,reason, strict); //Green light to other threads if(!mutex_acquired){ platform_mutex_unlock(table->mutex); } return result; }
int MQTTDisconnect(MQTTClient* c) { int rc = MQTT_FAILURE; Timer timer; // we might wait for incomplete incoming publishes to complete int len = 0; platform_mutex_lock(&c->mutex); platform_timer_init(&timer); platform_timer_countdown(&timer, c->command_timeout_ms); len = MQTTSerialize_disconnect(c->buf, c->buf_size); if (len > 0) rc = sendPacket(c, len, &timer); // send the disconnect packet c->isconnected = 0; platform_mutex_unlock(&c->mutex); return rc; }
of_switch_snapshot_t* physical_switch_get_logical_switch_snapshot(const uint64_t dpid){ of_switch_t* sw; of_switch_snapshot_t* to_return=NULL; //Serialize platform_mutex_lock(psw->mutex); //Try to find the switch sw = physical_switch_get_logical_switch_by_dpid(dpid); if(sw) to_return = __of_switch_get_snapshot(sw); platform_mutex_unlock(psw->mutex); return to_return; }
//Destroy void physical_switch_destroy(){ unsigned int i; ROFL_PIPELINE_DEBUG("Destroying physical switch\n"); //Serialize platform_mutex_lock(psw->mutex); //Destroy logical switches for(i=0;i<PHYSICAL_SWITCH_MAX_LS;i++){ if(psw->logical_switches[i]) of_destroy_switch(psw->logical_switches[i]); } //Destroying ports for(i=0;i<PHYSICAL_SWITCH_MAX_NUM_PHY_PORTS;i++){ if( psw->physical_ports[i] != NULL ){ switch_port_destroy(psw->physical_ports[i]); } } for(i=0;i<PHYSICAL_SWITCH_MAX_NUM_VIR_PORTS;i++){ if( psw->virtual_ports[i] != NULL ){ switch_port_destroy(psw->virtual_ports[i]); } } for(i=0;i<PHYSICAL_SWITCH_MAX_NUM_TUN_PORTS;i++){ if( psw->tunnel_ports[i] != NULL ){ switch_port_destroy(psw->tunnel_ports[i]); } } //Destroy monitoring __monitoring_destroy(&psw->monitoring); //Destroy mutex platform_mutex_destroy(psw->mutex); //destroy physical switch platform_free_shared(psw); }
rofl_result_t of1x_modify_flow_entry_loop(of1x_flow_table_t *const table, of1x_flow_entry_t *const entry, const enum of1x_flow_removal_strictness strict, bool reset_counts){ int moded=0; of1x_flow_entry_t *it; //Allow single add/remove operation over the table platform_mutex_lock(table->mutex); //Loop over all the table entries for(it=table->entries; it; it=it->next){ if( strict == STRICT ){ //Strict make sure they are equal if( __of1x_flow_entry_check_equal(it, entry, OF1X_PORT_ANY, OF1X_GROUP_ANY, true) ){ if(__of1x_update_flow_entry(it, entry, reset_counts) != ROFL_SUCCESS) return ROFL_FAILURE; moded++; break; } }else{ if( __of1x_flow_entry_check_contained(it, entry, strict, true, OF1X_PORT_ANY, OF1X_GROUP_ANY,false) ){ if(__of1x_update_flow_entry(it, entry, reset_counts) != ROFL_SUCCESS) return ROFL_FAILURE; moded++; } } } platform_mutex_unlock(table->mutex); //According to spec if(moded == 0){ return of1x_add_flow_entry_loop(table, entry, false, reset_counts); } //Delete the original flowmod (modify one) of1x_destroy_flow_entry(entry); return ROFL_SUCCESS; }
void __of1x_process_pipeline_tables_timeout_expirations(of1x_pipeline_t *const pipeline) { unsigned int i; struct timeval system_time; platform_gettimeofday(&system_time); uint64_t now = __of1x_get_time_ms(&system_time); for(i=0; i<pipeline->num_of_tables; i++) { of1x_flow_table_t* table = &pipeline->tables[i]; platform_mutex_lock(table->mutex); #if OF1X_TIMER_STATIC_ALLOCATION_SLOTS while(table->timers[table->current_timer_group].timeout<=now) { //rotate the timers __of1x_timer_group_rotate(pipeline,&(table->timers[table->current_timer_group]),i); } #else of1x_timer_group_t* slot_it, *next; for(slot_it=table->timers; slot_it; slot_it=next) { if(now<slot_it->timeout) //Current slot time > time_now. We are done break; //remove all entries and the timer group. if(__of1x_destroy_all_entries_from_timer_group(slot_it, table)!=ROFL_SUCCESS) { ROFL_PIPELINE_DEBUG("Error while destroying timer group\n"); platform_mutex_unlock(table->mutex); return; } next = slot_it->next; if(slot_it) __of1x_destroy_timer_group(slot_it, table); } #endif platform_mutex_unlock(table->mutex); } return; }
rofl_result_t physical_switch_remove_logical_switch_by_dpid(const uint64_t dpid){ int i; of_switch_t* sw; ROFL_PIPELINE_DEBUG("Removing logical switch with dpid: 0x%"PRIx64"\n",dpid); //Serialize platform_mutex_lock(psw->mutex); if(!physical_switch_get_logical_switch_by_dpid(dpid)){ platform_mutex_unlock(psw->mutex); ROFL_PIPELINE_WARN("Logical switch not found\n"); return ROFL_FAILURE; } for(i=0;i<PHYSICAL_SWITCH_MAX_LS;i++){ if(psw->logical_switches[i] && psw->logical_switches[i]->dpid == dpid){ sw = psw->logical_switches[i]; psw->logical_switches[i] = NULL; psw->num_of_logical_switches--; //Free the rest to do stuff with the physical sw platform_mutex_unlock(psw->mutex); //Destroy the switch of_destroy_switch(sw); return ROFL_SUCCESS; } } //This statement can never be reached platform_mutex_unlock(psw->mutex); return ROFL_FAILURE; }
int MQTTSubscribe(MQTTClient* c, const char* topicFilter, enum QoS qos) { int rc = MQTT_FAILURE; Timer timer; int len = 0; MQTTString topic = MQTTString_initializer; topic.cstring = (char *)topicFilter; platform_mutex_lock(&c->mutex); if (!c->isconnected) goto exit; platform_timer_init(&timer); platform_timer_countdown(&timer, c->command_timeout_ms); len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, (int*)&qos); if (len <= 0) goto exit; if ((rc = sendPacket(c, len, &timer)) != MQTT_SUCCESS) // send the subscribe packet goto exit; // there was a problem if (waitfor(c, SUBACK, &timer) == SUBACK) // wait for suback { int count = 0, grantedQoS = -1; unsigned short mypacketid; if (MQTTDeserialize_suback(&mypacketid, 1, &count, &grantedQoS, c->readbuf, c->readbuf_size) == 1) rc = grantedQoS; // 0, 1, 2 or 0x80 } else { rc = MQTT_CONNECTION_LOST; } exit: platform_mutex_unlock(&c->mutex); return rc; }
//Get the port snapshot switch_port_snapshot_t* physical_switch_get_port_snapshot(const char* name){ switch_port_t* port; switch_port_snapshot_t* snapshot; if(!name) return NULL; //Serialize platform_mutex_lock(psw->mutex); port = physical_switch_get_port_by_name(name); if(!port){ platform_mutex_unlock(psw->mutex); return NULL; } snapshot = __switch_port_get_snapshot(port); platform_mutex_unlock(psw->mutex); return snapshot; }
//List of ports switch_port_name_list_t* physical_switch_get_all_port_names(void){ switch_port_name_list_t* list; __switch_port_name_t* names; unsigned int num_of_ports, i; //Serialize platform_mutex_lock(psw->mutex); //Determine the number of (currenly) exisitng ports num_of_ports=0; for(i=0;i<PHYSICAL_SWITCH_MAX_NUM_PHY_PORTS;i++){ if(psw->physical_ports[i]) num_of_ports++; } for(i=0;i<PHYSICAL_SWITCH_MAX_NUM_TUN_PORTS;i++){ if(psw->tunnel_ports[i]) num_of_ports++; } for(i=0;i<PHYSICAL_SWITCH_MAX_NUM_VIR_PORTS;i++){ if(psw->virtual_ports[i]) num_of_ports++; } //Allocate memory list = platform_malloc_shared(sizeof(switch_port_name_list_t)); names = platform_malloc_shared(sizeof(__switch_port_name_t)*num_of_ports); if(!list || !names){ platform_mutex_unlock(psw->mutex); if(list) platform_free_shared(list); if(names) platform_free_shared(names); return NULL; } //Fill in list->names = names; list->num_of_ports = num_of_ports; num_of_ports=0; for(i=0;i<PHYSICAL_SWITCH_MAX_NUM_PHY_PORTS;i++){ if(psw->physical_ports[i]){ memcpy(&list->names[num_of_ports], &psw->physical_ports[i]->name, SWITCH_PORT_MAX_LEN_NAME); num_of_ports++; } } for(i=0;i<PHYSICAL_SWITCH_MAX_NUM_TUN_PORTS;i++){ if(psw->tunnel_ports[i]){ memcpy(&list->names[num_of_ports], &psw->tunnel_ports[i]->name, SWITCH_PORT_MAX_LEN_NAME); num_of_ports++; } } for(i=0;i<PHYSICAL_SWITCH_MAX_NUM_VIR_PORTS;i++){ if(psw->virtual_ports[i]){ memcpy(&list->names[num_of_ports], &psw->virtual_ports[i]->name, SWITCH_PORT_MAX_LEN_NAME); num_of_ports++; } } platform_mutex_unlock(psw->mutex); return list; }