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; }
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; }
/* 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; }