//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; }
of1x_match_t* of1x_init_ip4_dst_match(uint32_t value, uint32_t mask){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; // Align to pipeline convention (NBO, lower memory address) value = HTONB32(value); mask = HTONB32(mask); match->type = OF1X_MATCH_IPV4_DST; match->__tern = __init_utern32(value,mask); //Set fast validation flags match->ver_req.min_ver = OF_VERSION_10; //First supported in OF1.0 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max if( (mask&OF1X_4_BYTE_MASK) != OF1X_4_BYTE_MASK) match->has_wildcard = true; else match->has_wildcard = false; //Initialize linked-list match->prev=match->next=NULL; return match; }
/** * of1x_timer_group_init creates a new timer group and places it in * between tg_next and tg_prev, ordered by timeout values. * This function is NOT thread safe, you must lock the timer before. */ static of1x_timer_group_t* __of1x_timer_group_init(uint64_t timeout, of1x_timer_group_t* tg_next, of1x_timer_group_t* tg_prev, of1x_flow_table_t* table) { // create the new timer_group of1x_timer_group_t* new_group; new_group = platform_malloc_shared(sizeof(of1x_timer_group_t)); if(unlikely(new_group == NULL)) { ROFL_PIPELINE_DEBUG("<%s:%d> Error allocating memory\n",__func__,__LINE__); return NULL; } new_group->timeout = timeout; new_group->list.num_of_timers=0; new_group->list.head=NULL; new_group->list.tail=NULL; // place the timer group new_group->prev=tg_prev; new_group->next=tg_next; //if there is a node afterwards we place the new one before if (tg_next) tg_next->prev=new_group; //if there is a node forewards we place the new one before if (tg_prev) tg_prev->next=new_group; if(table->timers == tg_next) table->timers = new_group; return new_group; }
of1x_match_t* of1x_init_ip6_dst_match(uint128__t value, uint128__t mask){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; // Align to pipeline convention (NBO, lower memory address) HTONB128(value); HTONB128(mask); uint128__t fixed_mask = {{0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff}}; match->type = OF1X_MATCH_IPV6_DST; match->__tern = __init_utern128(value,mask); //Set fast validation flags match->ver_req.min_ver = OF_VERSION_12; //First supported in OF1.2 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max if(memcmp(&fixed_mask,&mask, sizeof(mask)) != 0) match->has_wildcard = true; else match->has_wildcard = false; //Initialize linked-list match->prev=match->next=NULL; return match; }
//ETHERNET of1x_match_t* of1x_init_eth_dst_match(uint64_t value, uint64_t mask){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; // Align to pipeline convention (NBO, lower memory address) value = HTONB64(OF1X_MAC_ALIGN(value)); mask = HTONB64(OF1X_MAC_ALIGN(mask)); match->type = OF1X_MATCH_ETH_DST; match->__tern = __init_utern64(value&OF1X_48_BITS_MASK, mask&OF1X_48_BITS_MASK); //Enforce mask bits are always 00 for the first bits //Set fast validation flags match->ver_req.min_ver = OF_VERSION_10; //First supported in OF1.0 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max if( (mask&OF1X_48_BITS_MASK) != OF1X_48_BITS_MASK) match->has_wildcard = true; else match->has_wildcard = false; //Initialize linked-list match->prev=match->next=NULL; return match; }
//8021.q of1x_match_t* of1x_init_vlan_vid_match(uint16_t value, uint16_t mask, enum of1x_vlan_present vlan_present){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; // Align to pipeline convention (NBO, lower memory address) value = HTONB16(value); mask = HTONB16(mask); match->type = OF1X_MATCH_VLAN_VID; //Setting values; note that value includes the flag HAS_VLAN in the 13th bit //The mask is set to be strictly 12 bits, so only matching the VLAN ID itself match->__tern = __init_utern16(value&OF1X_VLAN_ID_MASK,mask&OF1X_VLAN_ID_MASK); match->vlan_present = vlan_present; //Set fast validation flags match->ver_req.min_ver = OF_VERSION_10; //First supported in OF1.0 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max if( (mask&OF1X_VLAN_ID_MASK) != OF1X_VLAN_ID_MASK) match->has_wildcard = true; else match->has_wildcard = false; //Initialize linked-list match->prev=match->next=NULL; return match; }
//Copy (cloning) methods of1x_packet_action_t* __of1x_copy_packet_action(of1x_packet_action_t* action){ of1x_packet_action_t* copy; copy = platform_malloc_shared(sizeof(of1x_packet_action_t)); if( unlikely(copy==NULL) ) return NULL; *copy = *action; return copy; }
//Init&destroy platform_mutex_t* platform_mutex_init(void* params){ pthread_mutex_t* mutex = (pthread_mutex_t*)platform_malloc_shared(sizeof(pthread_mutex_t)); if(!mutex) return NULL; if( pthread_mutex_init(mutex, params) < 0){ platform_free_shared(mutex); return NULL; } return (platform_mutex_t*)mutex; }
//Init&destroy platform_rwlock_t* platform_rwlock_init(void* params){ pthread_rwlock_t* rwlock = (pthread_rwlock_t*)platform_malloc_shared(sizeof(pthread_rwlock_t)); if(!rwlock) return NULL; if(pthread_rwlock_init(rwlock, params) < 0){ platform_free_shared(rwlock); return NULL; } return (platform_rwlock_t*)rwlock; }
//Init rofl_result_t physical_switch_init(){ ROFL_PIPELINE_DEBUG("Initializing physical switch\n"); //Allocate memory for the physical switch structure psw = platform_malloc_shared(sizeof(physical_switch_t)); if( unlikely(psw==NULL) ) return ROFL_FAILURE; psw->mutex = platform_mutex_init(NULL); if(!psw->mutex) return ROFL_FAILURE; platform_memset(psw->logical_switches, 0, sizeof(psw->logical_switches)); psw->num_of_logical_switches = 0; platform_memset(psw->physical_ports, 0, sizeof(psw->physical_ports)); platform_memset(psw->tunnel_ports, 0, sizeof(psw->tunnel_ports)); platform_memset(psw->virtual_ports, 0, sizeof(psw->virtual_ports)); platform_memset(psw->meta_ports, 0, sizeof(psw->meta_ports)); //Generate metaports //Flood psw->meta_ports[META_PORT_FLOOD_INDEX].type = PORT_TYPE_META_FLOOD; strncpy(psw->meta_ports[META_PORT_FLOOD_INDEX].name, "Flood meta port", SWITCH_PORT_MAX_LEN_NAME); //In port psw->meta_ports[META_PORT_IN_PORT_INDEX].type = PORT_TYPE_META_IN_PORT; strncpy(psw->meta_ports[META_PORT_IN_PORT_INDEX].name, "In port meta port", SWITCH_PORT_MAX_LEN_NAME); //All psw->meta_ports[META_PORT_ALL_INDEX].type = PORT_TYPE_META_ALL; strncpy(psw->meta_ports[META_PORT_ALL_INDEX].name, "All meta port", SWITCH_PORT_MAX_LEN_NAME); //Set extern pointer flood_meta_port = &psw->meta_ports[META_PORT_FLOOD_INDEX]; in_port_meta_port = &psw->meta_ports[META_PORT_IN_PORT_INDEX]; all_meta_port = &psw->meta_ports[META_PORT_ALL_INDEX]; //Initialize monitoring data if(__monitoring_init(&psw->monitoring) != ROFL_SUCCESS) return ROFL_FAILURE; //Generate matching algorithm lists __physical_switch_generate_matching_algorithm_list(); return ROFL_SUCCESS; }
of1x_write_actions_t* __of1x_copy_write_actions(of1x_write_actions_t* origin){ of1x_write_actions_t* copy; if( unlikely(origin==NULL) ) return NULL; copy = platform_malloc_shared(sizeof(of1x_write_actions_t)); if( unlikely(copy==NULL) ) return NULL; //Copy Values *copy = *origin; return copy; }
/* * Try to find the largest common value among match1 and match2, being ALWAYS match2 with a more strict mask */ of1x_match_t* __of1x_get_alike_match(of1x_match_t* match1, of1x_match_t* match2){ utern_t* common_tern = NULL; if( match1->type != match2->type ) return NULL; common_tern = __utern_get_alike(*match1->__tern,*match2->__tern); if(common_tern){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); match->__tern = common_tern; match->type = match1->type; match->next = NULL; match->prev = NULL; return match; } return NULL; }
/** * of1x_entry_timer_init * adds a new entry in the list */ static of1x_entry_timer_t* __of1x_entry_timer_init(of1x_timer_group_t* tg, of1x_flow_entry_t* entry, of1x_timer_timeout_type_t is_idle) { of1x_entry_timer_t* new_entry; new_entry = platform_malloc_shared(sizeof(of1x_entry_timer_t)); if(unlikely(new_entry==NULL)) { ROFL_PIPELINE_DEBUG("<%s:%d> Error allocating memory\n",__func__,__LINE__); return NULL; } new_entry->entry = entry; new_entry->group = tg; // we add the new entries at the end new_entry->next=NULL; // we check if it is the first entry. if(tg->list.tail) //if it is not { new_entry->prev=tg->list.tail; //update the pointer OF the last entry on the list tg->list.tail->next=new_entry; } else //if it is the first one { new_entry->prev=NULL; //normally this should also apply: if(!tg->list.head) tg->list.head = new_entry; } // update the pointer TO the last entry of the list tg->list.tail = new_entry; // update the entries counter tg->list.num_of_timers++; new_entry->type=is_idle; if(is_idle) entry->timer_info.idle_timer_entry=new_entry; else entry->timer_info.hard_timer_entry=new_entry; return new_entry; }
of1x_action_group_t* __of1x_copy_action_group(of1x_action_group_t* origin){ of1x_action_group_t* copy; of1x_packet_action_t* it; if( unlikely(origin==NULL) ) return NULL; copy = platform_malloc_shared(sizeof(of1x_action_group_t)); if( unlikely(copy==NULL) ) return NULL; copy->head = copy->tail = NULL; copy->num_of_actions = origin->num_of_actions; copy->num_of_output_actions = origin->num_of_output_actions; //Copy al apply actions for(it=origin->head;it;it=it->next){ of1x_packet_action_t* act; act = __of1x_copy_packet_action(it); if(unlikely(act == NULL)){ of1x_destroy_action_group(copy); return NULL; } //Insert in the double linked-list if(!copy->tail){ copy->head = act; act->prev = NULL; }else{ act->prev = copy->tail; copy->tail->next = act; } act->next = NULL; copy->tail = act; } return copy; }
//ICMPv4 of1x_match_t* of1x_init_icmpv4_type_match(uint8_t value){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; match->type = OF1X_MATCH_ICMPV4_TYPE; match->__tern = __init_utern8(value,OF1X_1_BYTE_MASK); //no wildcard //Set fast validation flags match->ver_req.min_ver = OF_VERSION_12; //First supported in OF1.2 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max match->has_wildcard = false; //Not accepting wildcards //Initialize linked-list match->prev=match->next=NULL; return match; }
of1x_match_t* of1x_init_mpls_bos_match(uint8_t value){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; match->type = OF1X_MATCH_MPLS_BOS; match->__tern = __init_utern8(value&OF1X_BIT0_MASK,OF1X_BIT0_MASK); //Ensure only 1 bit value, no wildcard //Set fast validation flags match->ver_req.min_ver = OF_VERSION_13; //First supported in OF1.3 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max match->has_wildcard = false; //Not accepting wildcards //Initialize linked-list match->prev=match->next=NULL; return match; }
of1x_match_t* of1x_init_pppoe_session_match(uint16_t value){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; // Align to pipeline convention (NBO, lower memory address) value = HTONB16(value); match->type = OF1X_MATCH_PPPOE_SID; match->__tern = __init_utern16(value,OF1X_2_BYTE_MASK); //no wildcard //Set fast validation flags match->ver_req.min_ver = OF_VERSION_12; //First supported in OF1.2 (extensions) match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max match->has_wildcard = false; //Not accepting w //Initialize linked-list match->prev=match->next=NULL; return match; }
of1x_match_t* of1x_init_ip6_nd_tll_match(uint64_t value){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; // Align to pipeline convention (NBO, lower memory address) value = HTONB64(OF1X_MAC_ALIGN(value)); match->type = OF1X_MATCH_IPV6_ND_TLL; match->__tern = __init_utern64(value & OF1X_48_BITS_MASK, OF1X_48_BITS_MASK); //ensure 48 bits. No wildcard //Set fast validation flags match->ver_req.min_ver = OF_VERSION_12; //First supported in OF1.2 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max match->has_wildcard = false; //Not accepting wildcards //Initialize linked-list match->prev=match->next=NULL; return match; }
of1x_match_t* of1x_init_ip_dscp_match(uint8_t value){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; // Align to pipeline convention (NBO, lower memory address) value = OF1X_IP_DSCP_ALIGN(value); match->type = OF1X_MATCH_IP_DSCP; match->__tern = __init_utern8(value&OF1X_6MSBITS_MASK,OF1X_6MSBITS_MASK); //no wildcard //Set fast validation flags match->ver_req.min_ver = OF_VERSION_10; //First supported in OF1.0 (ToS) match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max match->has_wildcard = false; //Not accepting wildcards //Initialize linked-list match->prev=match->next=NULL; return match; }
//MPLS of1x_match_t* of1x_init_mpls_label_match(uint32_t value){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; // Align to pipeline convention (NBO, lower memory address) value = HTONB32(OF1X_MPLS_LABEL_ALIGN(value)); match->type = OF1X_MATCH_MPLS_LABEL; match->__tern = __init_utern32(value&OF1X_20_BITS_MASK,OF1X_20_BITS_MASK); //no wildcard?? wtf! //Set fast validation flags match->ver_req.min_ver = OF_VERSION_12; //First supported in OF1.2 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max match->has_wildcard = false; //Not accepting wildcards //Initialize linked-list match->prev=match->next=NULL; return match; }
//METADATA of1x_match_t* of1x_init_metadata_match(uint64_t value, uint64_t mask){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; match->type = OF1X_MATCH_METADATA; match->__tern = __init_utern64(value, mask); //Set fast validation flags match->ver_req.min_ver = OF_VERSION_12; //First supported in OF1.2 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max if( (mask&OF1X_8_BYTE_MASK) != OF1X_8_BYTE_MASK) match->has_wildcard = true; else match->has_wildcard = false; //Initialize linked-list match->prev=match->next=NULL; return match; }
/* Action group init and destroy */ of1x_action_group_t* of1x_init_action_group(of1x_packet_action_t* actions){ unsigned int number_of_actions=0, number_of_output_actions=0; of1x_action_group_t* action_group; action_group = platform_malloc_shared(sizeof(of1x_action_group_t)); if( unlikely(action_group==NULL) ) return NULL; if(actions){ action_group->head = actions; for(;actions;actions=actions->next, number_of_actions++){ if(actions->type == OF1X_AT_OUTPUT /*|| actions->type == OF1X_AT_GROUP*/) number_of_output_actions++; if(!actions->next){ action_group->tail = actions; break; } } }else{ action_group->head = NULL; action_group->tail = NULL; } action_group->num_of_actions = number_of_actions; action_group->num_of_output_actions = number_of_output_actions; //Fast validation, set min max action_group->ver_req.min_ver = OF1X_MIN_VERSION; action_group->ver_req.max_ver = OF1X_MAX_VERSION; bitmap128_clean(&action_group->bitmap); return action_group; }
/* * Copy match to heap. Leaves next and prev pointers to NULL */ of1x_match_t* __of1x_copy_match(of1x_match_t* match){ of1x_match_t* tmp = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(!tmp) return tmp; //Copy contents *tmp = *match; //Initialize linked-list to null tmp->prev=tmp->next=NULL; //Create a whatever type utern and copy from the orignal tern tmp->__tern = __init_utern8(0x0, 0x0); if(!tmp->__tern) return NULL; *tmp->__tern = *match->__tern; return tmp; }
of1x_match_t* of1x_init_ip6_exthdr_match(uint16_t value, uint16_t mask){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; // TODO Align to pipeline convention (NBO, lower memory address) -- currently not implemented match->type = OF1X_MATCH_IPV6_EXTHDR; match->__tern = __init_utern16(value&OF1X_9_BITS_MASK, mask & OF1X_9_BITS_MASK ); //ensure 9 bits, with Wildcard //Set fast validation flags match->ver_req.min_ver = OF_VERSION_13; //First supported in OF1.2 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max if( (mask&OF1X_9_BITS_MASK) != OF1X_9_BITS_MASK) match->has_wildcard = true; else match->has_wildcard = false; //Initialize linked-list match->prev=match->next=NULL; return match; }
of1x_match_t* of1x_init_ip6_nd_target_match(uint128__t value){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; // Align to pipeline convention (NBO, lower memory address) HTONB128(value); uint128__t mask = {{0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff}}; match->type = OF1X_MATCH_IPV6_ND_TARGET; match->__tern = __init_utern128(value,mask); //No wildcard //Set fast validation flags match->ver_req.min_ver = OF_VERSION_12; //First supported in OF1.2 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max match->has_wildcard = false; //Not accepting wildcards //Initialize linked-list match->prev=match->next=NULL; return match; }
//PBB of1x_match_t* of1x_init_pbb_isid_match(uint32_t value, uint32_t mask){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; //TODO Align to pipeline convention (NBO, lower memory address) -- currently not implemented match->type = OF1X_MATCH_PBB_ISID; match->__tern = __init_utern32(value&OF1X_3_BYTE_MASK, mask&OF1X_3_BYTE_MASK); //no wildcard //Set fast validation flags match->ver_req.min_ver = OF_VERSION_13; //First supported in OF1.3 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max if( (mask&OF1X_3_BYTE_MASK) == OF1X_3_BYTE_MASK) match->has_wildcard = false; else match->has_wildcard = false; //Initialize linked-list match->prev=match->next=NULL; return match; }
//Tunnel Id of1x_match_t* of1x_init_tunnel_id_match(uint64_t value, uint64_t mask){ of1x_match_t* match = (of1x_match_t*)platform_malloc_shared(sizeof(of1x_match_t)); if(unlikely(match == NULL)) return NULL; //TODO align? match->type = OF1X_MATCH_TUNNEL_ID; match->__tern = __init_utern64(value, mask); //no wildcard //Set fast validation flags match->ver_req.min_ver = OF_VERSION_13; //First supported in OF1.3 match->ver_req.max_ver = OF1X_MAX_VERSION; //No limitation on max if(mask != OF1X_8_BYTE_MASK) match->has_wildcard = true; else match->has_wildcard = false; //Initialize linked-list match->prev=match->next=NULL; return match; }
of1x_write_actions_t* of1x_init_write_actions(){ int i; of1x_write_actions_t* write_actions = platform_malloc_shared(sizeof(of1x_write_actions_t)); if( unlikely(write_actions==NULL) ) return NULL; //Clean actions bitmap bitmap128_clean(&write_actions->bitmap); for(i=0;i<OF1X_AT_NUMBER;i++) write_actions->actions[i].type = (of1x_packet_action_type_t)i; //num of actions and output actions write_actions->num_of_actions = 0; write_actions->num_of_output_actions = 0; //Fast validation, set min max write_actions->ver_req.min_ver = OF1X_MIN_VERSION; write_actions->ver_req.max_ver = OF1X_MAX_VERSION; return write_actions; }
/* Actions init and destroyed */ of1x_packet_action_t* of1x_init_packet_action(of1x_packet_action_type_t type, wrap_uint_t field, uint16_t output_send_len){ of1x_packet_action_t* action; if( unlikely(type==OF1X_AT_NO_ACTION) ) return NULL; action = platform_malloc_shared(sizeof(of1x_packet_action_t)); if( unlikely(action==NULL) ) return NULL; //Set type action->type = type; //Set min max action->ver_req.min_ver = OF1X_MIN_VERSION; action->ver_req.max_ver = OF1X_MAX_VERSION; //Make valgrind happy UINT128__T_HI(action->__field.u128) = UINT128__T_LO(action->__field.u128) = 0x0ULL; /* * Setting the field (for set_field actions) and fast validation flags */ switch(type){ //16 byte case OF1X_AT_SET_FIELD_IPV6_ND_TARGET: case OF1X_AT_SET_FIELD_IPV6_SRC: case OF1X_AT_SET_FIELD_IPV6_DST:{ uint128__t tmp = field.u128; HTONB128(tmp); action->__field.u128 = tmp; action->ver_req.min_ver = OF_VERSION_12; }break; //8 byte case OF1X_AT_SET_FIELD_TUNNEL_ID: action->__field.u64 = field.u64&OF1X_8_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_13; break; //6 byte values case OF1X_AT_SET_FIELD_IPV6_ND_SLL: field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64)); action->__field.u64 = field.u64&OF1X_6_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_IPV6_ND_TLL: field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64)); action->__field.u64 = field.u64&OF1X_6_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_ETH_DST: field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64)); action->__field.u64 = field.u64&OF1X_6_BYTE_MASK; break; case OF1X_AT_SET_FIELD_ETH_SRC: field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64)); action->__field.u64 = field.u64&OF1X_6_BYTE_MASK; break; case OF1X_AT_SET_FIELD_ARP_SHA: field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64)); action->__field.u64 = field.u64&OF1X_6_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_ARP_THA: field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64)); action->__field.u64 = field.u64&OF1X_6_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; /* Extensions */ case OF1X_AT_SET_FIELD_WLAN_ADDRESS_1: case OF1X_AT_SET_FIELD_WLAN_ADDRESS_2: case OF1X_AT_SET_FIELD_WLAN_ADDRESS_3: field.u64 = HTONB64(OF1X_MAC_ALIGN(field.u64)); action->__field.u64 = field.u64&OF1X_6_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; /* Extensions end */ //4 byte values case OF1X_AT_SET_FIELD_NW_DST: action->ver_req.min_ver = OF_VERSION_10; action->ver_req.max_ver = OF_VERSION_10; case OF1X_AT_SET_FIELD_IPV4_DST: field.u32 = HTONB32(field.u32); action->__field.u32 = field.u32&OF1X_4_BYTE_MASK; break; case OF1X_AT_SET_FIELD_NW_SRC: action->ver_req.min_ver = OF_VERSION_10; action->ver_req.max_ver = OF_VERSION_10; case OF1X_AT_SET_FIELD_IPV4_SRC: field.u32 = HTONB32(field.u32); action->__field.u32 = field.u32&OF1X_4_BYTE_MASK; break; case OF1X_AT_SET_FIELD_ARP_SPA: field.u32 = HTONB32(field.u32); action->__field.u32 = field.u32&OF1X_4_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_10; break; case OF1X_AT_SET_FIELD_ARP_TPA: field.u32 = HTONB32(field.u32); action->__field.u32 = field.u32&OF1X_4_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_10; break; case OF1X_AT_OUTPUT: action->send_len = output_send_len; action->__field.u32 = field.u32&OF1X_4_BYTE_MASK; break; case OF1X_AT_SET_FIELD_GTP_TEID: field.u32 = HTONB32(field.u32); action->__field.u32 = field.u32&OF1X_4_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; //3 byte case OF1X_AT_SET_FIELD_PBB_ISID: //TODO Align value action->__field.u32 = field.u32&OF1X_3_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_13; break; //20 bit values case OF1X_AT_SET_FIELD_IPV6_FLABEL: field.u32 = HTONB32(OF1X_IP6_FLABEL_ALIGN(field.u32)); action->__field.u32 = field.u32&OF1X_20_BITS_IPV6_FLABEL_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_MPLS_LABEL: field.u32 = HTONB32(OF1X_MPLS_LABEL_ALIGN(field.u32)); action->__field.u32 = field.u32&OF1X_20_BITS_MASK; action->ver_req.min_ver = OF_VERSION_12; break; //2 byte values case OF1X_AT_SET_FIELD_ETH_TYPE: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; break; case OF1X_AT_SET_FIELD_ARP_OPCODE: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; // TODO: lower 8bits of opcode only? action->ver_req.min_ver = OF_VERSION_10; break; case OF1X_AT_SET_FIELD_TP_SRC: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_10; action->ver_req.max_ver = OF_VERSION_10; break; case OF1X_AT_SET_FIELD_TP_DST: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_10; action->ver_req.max_ver = OF_VERSION_10; break; case OF1X_AT_SET_FIELD_TCP_SRC: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_TCP_DST: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_UDP_SRC: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_UDP_DST: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_SCTP_SRC: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_SCTP_DST: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_PPPOE_SID: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_PPP_PROT: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_CAPWAP_FLAGS: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_FIELD_WLAN_FC: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; /*case OF1X_AT_POP_VLAN: TODO: CHECK THIS*/ case OF1X_AT_POP_MPLS: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_POP_PPPOE: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_POP_PBB: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_13; break; /* Extensions */ case OF1X_AT_POP_WLAN: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_POP_GTP: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_POP_CAPWAP: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_PUSH_GTP: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_PUSH_CAPWAP: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_PUSH_WLAN: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; /* Extensions end */ case OF1X_AT_PUSH_PPPOE: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_PUSH_MPLS: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_PUSH_VLAN: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_PUSH_PBB: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_2_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_13; break; //12 bit values case OF1X_AT_SET_FIELD_VLAN_VID: field.u16 = HTONB16(field.u16); action->__field.u16 = field.u16&OF1X_12_BITS_MASK; break; //9 bit value case OF1X_AT_SET_FIELD_IPV6_EXTHDR: //TODO align to pipeline -- currently not implemented action->__field.u16 = field.u16&OF1X_9_BITS_MASK; action->ver_req.min_ver = OF_VERSION_13; break; //1 byte values case OF1X_AT_SET_FIELD_NW_PROTO: action->ver_req.min_ver = OF_VERSION_10; action->ver_req.max_ver = OF_VERSION_10; action->__field.u8 = field.u8&OF1X_1_BYTE_MASK; break; case OF1X_AT_SET_FIELD_ICMPV6_TYPE: case OF1X_AT_SET_FIELD_ICMPV6_CODE: case OF1X_AT_SET_FIELD_PPPOE_CODE: case OF1X_AT_SET_FIELD_PPPOE_TYPE: case OF1X_AT_SET_MPLS_TTL: case OF1X_AT_SET_NW_TTL: case OF1X_AT_SET_FIELD_IP_PROTO: case OF1X_AT_SET_FIELD_ICMPV4_TYPE: case OF1X_AT_SET_FIELD_ICMPV4_CODE: action->__field.u8 = field.u8&OF1X_1_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_10; break; /* Extensions */ case OF1X_AT_SET_FIELD_GTP_MSG_TYPE: case OF1X_AT_SET_FIELD_CAPWAP_WBID: case OF1X_AT_SET_FIELD_CAPWAP_RID: case OF1X_AT_SET_FIELD_WLAN_TYPE: case OF1X_AT_SET_FIELD_WLAN_SUBTYPE: case OF1X_AT_SET_FIELD_WLAN_DIRECTION: /* Extensions end */ action->__field.u8 = field.u8&OF1X_1_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_12; break; //6 bit values case OF1X_AT_SET_FIELD_IP_DSCP: field.u8 = OF1X_IP_DSCP_ALIGN(field.u8); action->__field.u8 = field.u8&OF1X_6MSBITS_MASK; break; //3 bit values case OF1X_AT_SET_FIELD_VLAN_PCP: field.u8 = OF1X_VLAN_PCP_ALIGN(field.u8); action->__field.u8 = field.u8&OF1X_3MSBITS_MASK; break; case OF1X_AT_SET_FIELD_MPLS_TC: field.u8 = OF1X_MPLS_TC_ALIGN(field.u8); action->__field.u8 = field.u8&OF1X_BITS_12AND3_MASK; action->ver_req.min_ver = OF_VERSION_12; break; //2 bit values case OF1X_AT_SET_FIELD_IP_ECN: action->__field.u8 = field.u8&OF1X_2LSBITS_MASK; action->ver_req.min_ver = OF_VERSION_12; break; case OF1X_AT_SET_QUEUE: action->__field.u32 = field.u32&OF1X_4_BYTE_MASK; action->ver_req.min_ver = OF_VERSION_10; break; case OF1X_AT_GROUP: action->__field.u32 = field.u32&OF1X_4_BYTE_MASK; //id of the group action->ver_req.min_ver = OF_VERSION_12; //action->group = of1x_group_search(sw->pipeline->groups, action->__field); // pointer to the group //FIXME evaluate if this can be done here or not break; //1 bit values case OF1X_AT_SET_FIELD_MPLS_BOS: action->__field.u8 = field.u8&OF1X_BIT0_MASK; //id of the group action->ver_req.min_ver = OF_VERSION_13; break; //No value case OF1X_AT_POP_VLAN: action->__field.u64 = 0x0; // action strip vlan break; case OF1X_AT_COPY_TTL_IN: case OF1X_AT_COPY_TTL_OUT: case OF1X_AT_DEC_NW_TTL: case OF1X_AT_DEC_MPLS_TTL: case OF1X_AT_EXPERIMENTER: action->__field.u64 = 0x0; action->ver_req.min_ver = OF_VERSION_12; break; //Shall never happen case OF1X_AT_NO_ACTION: assert(0); action->__field.u64 = 0x0; break; } return action; }
//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; }