+ if ((src_port_mask == 0) && (dst_port_mask == 0))
+ {
+ item->spec = NULL;
+ item->mask = NULL;
+ }
+ else
+ {
+ tcp[0].hdr.src_port = clib_host_to_net_u16 (src_port);
+ tcp[1].hdr.src_port = clib_host_to_net_u16 (src_port_mask);
+ tcp[0].hdr.dst_port = clib_host_to_net_u16 (dst_port);
+ tcp[1].hdr.dst_port = clib_host_to_net_u16 (dst_port_mask);
+ item->spec = tcp;
+ item->mask = tcp + 1;
+ }
+ break;
+
+ case IP_PROTOCOL_UDP:
+ item->type = RTE_FLOW_ITEM_TYPE_UDP;
+ if ((src_port_mask == 0) && (dst_port_mask == 0))
+ {
+ item->spec = NULL;
+ item->mask = NULL;
+ }
+ else
+ {
+ udp[0].hdr.src_port = clib_host_to_net_u16 (src_port);
+ udp[1].hdr.src_port = clib_host_to_net_u16 (src_port_mask);
+ udp[0].hdr.dst_port = clib_host_to_net_u16 (dst_port);
+ udp[1].hdr.dst_port = clib_host_to_net_u16 (dst_port_mask);
+ item->spec = udp;
+ item->mask = udp + 1;
+ }
+
+ /* handle the UDP tunnels */
+ if (f->type == VNET_FLOW_TYPE_IP4_GTPC)
+ {
+ gtp[0].teid = clib_host_to_net_u32 (f->ip4_gtpc.teid);
+ gtp[1].teid = ~0;
+
+ vec_add2 (items, item, 1);
+ item->type = RTE_FLOW_ITEM_TYPE_GTPC;
+ item->spec = gtp;
+ item->mask = gtp + 1;
+ }
+ else if (f->type == VNET_FLOW_TYPE_IP4_GTPU)
+ {
+ gtp[0].teid = clib_host_to_net_u32 (f->ip4_gtpu.teid);
+ gtp[1].teid = ~0;
+
+ vec_add2 (items, item, 1);
+ item->type = RTE_FLOW_ITEM_TYPE_GTPU;
+ item->spec = gtp;
+ item->mask = gtp + 1;
+ }
+ else if (f->type == VNET_FLOW_TYPE_IP4_VXLAN)
+ {
+ u32 vni = f->ip4_vxlan.vni;
+
+ vxlan_header_t spec_hdr = {
+ .flags = VXLAN_FLAGS_I,
+ .vni_reserved = clib_host_to_net_u32 (vni << 8)
+ };
+ vxlan_header_t mask_hdr = {
+ .flags = 0xff,
+ .vni_reserved = clib_host_to_net_u32 (((u32) - 1) << 8)
+ };
+
+ clib_memset (raw, 0, sizeof raw);
+ raw[0].item.relative = 1;
+ raw[0].item.length = vxlan_hdr_sz;
+
+ clib_memcpy_fast (raw[0].val + raw_sz, &spec_hdr, vxlan_hdr_sz);
+ raw[0].item.pattern = raw[0].val + raw_sz;
+ clib_memcpy_fast (raw[1].val + raw_sz, &mask_hdr, vxlan_hdr_sz);
+ raw[1].item.pattern = raw[1].val + raw_sz;
+
+ vec_add2 (items, item, 1);
+ item->type = RTE_FLOW_ITEM_TYPE_RAW;
+ item->spec = raw;
+ item->mask = raw + 1;
+ }
+ break;
+
+ default: