Beispiel #1
0
//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;
}
Beispiel #2
0
/* 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;
}