1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2021 Marvell.
7 const struct roc_npc_item_info *
8 npc_parse_skip_void_and_any_items(const struct roc_npc_item_info *pattern)
10 while ((pattern->type == ROC_NPC_ITEM_TYPE_VOID) ||
11 (pattern->type == ROC_NPC_ITEM_TYPE_ANY))
18 npc_parse_meta_items(struct npc_parse_state *pst)
25 npc_parse_mark_item(struct npc_parse_state *pst)
27 if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MARK) {
28 if (pst->flow->nix_intf != NIX_INTF_RX)
31 pst->is_second_pass_rule = true;
39 npc_flow_raw_item_prepare(const struct roc_npc_flow_item_raw *raw_spec,
40 const struct roc_npc_flow_item_raw *raw_mask,
41 struct npc_parse_item_info *info, uint8_t *spec_buf,
45 memset(spec_buf, 0, NPC_MAX_RAW_ITEM_LEN);
46 memset(mask_buf, 0, NPC_MAX_RAW_ITEM_LEN);
48 memcpy(spec_buf + raw_spec->offset, raw_spec->pattern,
51 if (raw_mask && raw_mask->pattern) {
52 memcpy(mask_buf + raw_spec->offset, raw_mask->pattern,
55 memset(mask_buf + raw_spec->offset, 0xFF, raw_spec->length);
58 info->len = NPC_MAX_RAW_ITEM_LEN;
59 info->spec = spec_buf;
60 info->mask = mask_buf;
65 npc_parse_pre_l2(struct npc_parse_state *pst)
67 uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN] = {0};
68 uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN] = {0};
69 uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN] = {0};
70 const struct roc_npc_flow_item_raw *raw_spec;
71 struct npc_parse_item_info info;
75 if (pst->npc->switch_header_type != ROC_PRIV_FLAGS_PRE_L2)
78 /* Identify the pattern type into lid, lt */
79 if (pst->pattern->type != ROC_NPC_ITEM_TYPE_RAW)
83 lt = NPC_LT_LA_CUSTOM_PRE_L2_ETHER;
86 raw_spec = pst->pattern->spec;
87 len = raw_spec->length + raw_spec->offset;
88 if (len > NPC_MAX_RAW_ITEM_LEN)
91 if (raw_spec->relative == 0 || raw_spec->search || raw_spec->limit ||
95 npc_flow_raw_item_prepare(
96 (const struct roc_npc_flow_item_raw *)pst->pattern->spec,
97 (const struct roc_npc_flow_item_raw *)pst->pattern->mask, &info,
98 raw_spec_buf, raw_mask_buf);
100 info.hw_mask = &hw_mask;
101 npc_get_hw_supp_mask(pst, &info, lid, lt);
103 /* Basic validation of item parameters */
104 rc = npc_parse_item_basic(pst->pattern, &info);
108 /* Update pst if not validate only? clash check? */
109 return npc_update_parse_state(pst, &info, lid, lt, 0);
113 npc_parse_cpt_hdr(struct npc_parse_state *pst)
115 uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
116 struct npc_parse_item_info info;
120 /* Identify the pattern type into lid, lt */
121 if (pst->pattern->type != ROC_NPC_ITEM_TYPE_CPT_HDR)
125 lt = NPC_LT_LA_CPT_HDR;
128 /* Prepare for parsing the item */
129 info.def_mask = NULL;
130 info.hw_mask = &hw_mask;
131 info.len = pst->pattern->size;
132 npc_get_hw_supp_mask(pst, &info, lid, lt);
136 /* Basic validation of item parameters */
137 rc = npc_parse_item_basic(pst->pattern, &info);
141 /* Update pst if not validate only? clash check? */
142 return npc_update_parse_state(pst, &info, lid, lt, 0);
146 npc_parse_higig2_hdr(struct npc_parse_state *pst)
148 uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
149 struct npc_parse_item_info info;
153 /* Identify the pattern type into lid, lt */
154 if (pst->pattern->type != ROC_NPC_ITEM_TYPE_HIGIG2)
158 lt = NPC_LT_LA_HIGIG2_ETHER;
161 if (pst->flow->nix_intf == NIX_INTF_TX) {
162 lt = NPC_LT_LA_IH_NIX_HIGIG2_ETHER;
163 info.hw_hdr_len = NPC_IH_LENGTH;
166 /* Prepare for parsing the item */
167 info.def_mask = NULL;
168 info.hw_mask = &hw_mask;
169 info.len = pst->pattern->size;
170 npc_get_hw_supp_mask(pst, &info, lid, lt);
174 /* Basic validation of item parameters */
175 rc = npc_parse_item_basic(pst->pattern, &info);
179 /* Update pst if not validate only? clash check? */
180 return npc_update_parse_state(pst, &info, lid, lt, 0);
184 npc_parse_la(struct npc_parse_state *pst)
186 const struct roc_npc_flow_item_eth *eth_item;
187 uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
188 struct npc_parse_item_info info;
192 /* Identify the pattern type into lid, lt */
193 if (pst->pattern->type != ROC_NPC_ITEM_TYPE_ETH)
196 eth_item = pst->pattern->spec;
199 lt = NPC_LT_LA_ETHER;
202 if (pst->flow->nix_intf == NIX_INTF_TX) {
203 lt = NPC_LT_LA_IH_NIX_ETHER;
204 info.hw_hdr_len = NPC_IH_LENGTH;
205 if (pst->npc->switch_header_type == ROC_PRIV_FLAGS_HIGIG) {
206 lt = NPC_LT_LA_IH_NIX_HIGIG2_ETHER;
207 info.hw_hdr_len += NPC_HIGIG2_LENGTH;
210 if (pst->npc->switch_header_type == ROC_PRIV_FLAGS_HIGIG) {
211 lt = NPC_LT_LA_HIGIG2_ETHER;
212 info.hw_hdr_len = NPC_HIGIG2_LENGTH;
216 /* Prepare for parsing the item */
217 info.def_mask = NULL;
218 info.hw_mask = &hw_mask;
219 info.len = sizeof(eth_item->hdr);
220 npc_get_hw_supp_mask(pst, &info, lid, lt);
224 /* Basic validation of item parameters */
225 rc = npc_parse_item_basic(pst->pattern, &info);
229 rc = npc_update_parse_state(pst, &info, lid, lt, 0);
233 if (eth_item && eth_item->has_vlan)
234 pst->set_vlan_ltype_mask = true;
239 #define NPC_MAX_SUPPORTED_VLANS 3
242 npc_parse_lb(struct npc_parse_state *pst)
244 const struct roc_npc_flow_item_vlan *vlan_item[NPC_MAX_SUPPORTED_VLANS];
245 const struct roc_npc_item_info *pattern = pst->pattern;
246 const struct roc_npc_item_info *last_pattern;
247 const struct roc_npc_flow_item_raw *raw_spec;
248 uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN];
249 uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN];
250 char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
251 struct npc_parse_item_info info;
252 int lid, lt, lflags, len = 0;
256 info.def_mask = NULL;
259 info.def_mask = NULL;
260 info.hw_hdr_len = NPC_TPID_LENGTH;
264 last_pattern = pattern;
266 if (pst->pattern->type == ROC_NPC_ITEM_TYPE_VLAN) {
267 /* RTE vlan is either 802.1q or 802.1ad,
268 * this maps to either CTAG/STAG. We need to decide
269 * based on number of VLANS present. Matching is
270 * supported on first tag only.
273 info.len = sizeof(vlan_item[0]->hdr);
275 pattern = pst->pattern;
276 while (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) {
277 if (nr_vlans > NPC_MAX_SUPPORTED_VLANS - 1)
278 return NPC_ERR_PATTERN_NOTSUP;
280 vlan_item[nr_vlans] = pattern->spec;
283 /* Basic validation of Second/Third vlan item */
285 rc = npc_parse_item_basic(pattern, &info);
289 last_pattern = pattern;
291 pattern = npc_parse_skip_void_and_any_items(pattern);
297 if (vlan_item[0] && vlan_item[0]->has_more_vlan)
298 lt = NPC_LT_LB_STAG_QINQ;
301 if (vlan_item[1] && vlan_item[1]->has_more_vlan) {
302 if (!(pst->npc->keyx_supp_nmask[pst->nix_intf] &
303 0x3ULL << NPC_LFLAG_LB_OFFSET))
304 return NPC_ERR_PATTERN_NOTSUP;
306 /* This lflag value will match either one of
307 * NPC_F_LB_L_WITH_STAG_STAG,
308 * NPC_F_LB_L_WITH_QINQ_CTAG,
309 * NPC_F_LB_L_WITH_QINQ_QINQ and
310 * NPC_F_LB_L_WITH_ITAG (0b0100 to 0b0111). For
311 * NPC_F_LB_L_WITH_ITAG, ltype is NPC_LT_LB_ETAG
312 * hence will not match.
315 lflags = NPC_F_LB_L_WITH_QINQ_CTAG &
316 NPC_F_LB_L_WITH_QINQ_QINQ &
317 NPC_F_LB_L_WITH_STAG_STAG;
319 lflags = NPC_F_LB_L_WITH_CTAG;
321 lt = NPC_LT_LB_STAG_QINQ;
324 if (vlan_item[2] && vlan_item[2]->has_more_vlan)
325 return NPC_ERR_PATTERN_NOTSUP;
326 lt = NPC_LT_LB_STAG_QINQ;
327 lflags = NPC_F_STAG_STAG_CTAG;
330 return NPC_ERR_PATTERN_NOTSUP;
332 } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_E_TAG) {
333 /* we can support ETAG and match a subsequent CTAG
334 * without any matching support.
339 last_pattern = pst->pattern;
340 pattern = npc_parse_skip_void_and_any_items(pst->pattern + 1);
341 if (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) {
342 /* set supported mask to NULL for vlan tag */
344 info.len = pattern->size;
345 rc = npc_parse_item_basic(pattern, &info);
349 lflags = NPC_F_ETAG_CTAG;
350 last_pattern = pattern;
352 info.len = pattern->size;
353 } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_QINQ) {
355 info.len = pattern->size;
356 lt = NPC_LT_LB_STAG_QINQ;
357 lflags = NPC_F_STAG_CTAG;
358 } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_RAW) {
359 raw_spec = pst->pattern->spec;
360 if (raw_spec->relative)
362 len = raw_spec->length + raw_spec->offset;
363 if (len > NPC_MAX_RAW_ITEM_LEN)
366 if (pst->npc->switch_header_type == ROC_PRIV_FLAGS_VLAN_EXDSA) {
367 lt = NPC_LT_LB_VLAN_EXDSA;
368 } else if (pst->npc->switch_header_type ==
369 ROC_PRIV_FLAGS_EXDSA) {
370 lt = NPC_LT_LB_EXDSA;
375 npc_flow_raw_item_prepare((const struct roc_npc_flow_item_raw *)
377 (const struct roc_npc_flow_item_raw *)
379 &info, raw_spec_buf, raw_mask_buf);
386 info.hw_mask = &hw_mask;
387 npc_get_hw_supp_mask(pst, &info, lid, lt);
389 rc = npc_parse_item_basic(pst->pattern, &info);
393 /* Point pattern to last item consumed */
394 pst->pattern = last_pattern;
395 return npc_update_parse_state(pst, &info, lid, lt, lflags);
399 npc_parse_mpls_label_stack(struct npc_parse_state *pst, int *flag)
401 uint8_t flag_list[] = {0, NPC_F_MPLS_2_LABELS, NPC_F_MPLS_3_LABELS,
402 NPC_F_MPLS_4_LABELS};
403 const struct roc_npc_item_info *pattern = pst->pattern;
404 struct npc_parse_item_info info;
409 * pst->pattern points to first MPLS label. We only check
410 * that subsequent labels do not have anything to match.
412 info.def_mask = NULL;
414 info.len = pattern->size;
419 while (pattern->type == ROC_NPC_ITEM_TYPE_MPLS) {
422 /* Basic validation of Second/Third/Fourth mpls item */
424 rc = npc_parse_item_basic(pattern, &info);
428 pst->last_pattern = pattern;
430 pattern = npc_parse_skip_void_and_any_items(pattern);
433 if (nr_labels < 1 || nr_labels > 4)
434 return NPC_ERR_PATTERN_NOTSUP;
436 *flag = flag_list[nr_labels - 1];
441 npc_parse_mpls(struct npc_parse_state *pst, int lid)
443 /* Find number of MPLS labels */
444 uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
445 struct npc_parse_item_info info;
451 if (lid == NPC_LID_LC)
453 else if (lid == NPC_LID_LD)
454 lt = NPC_LT_LD_TU_MPLS_IN_IP;
456 lt = NPC_LT_LE_TU_MPLS_IN_UDP;
458 /* Prepare for parsing the first item */
459 info.hw_mask = &hw_mask;
460 info.len = pst->pattern->size;
463 info.def_mask = NULL;
466 npc_get_hw_supp_mask(pst, &info, lid, lt);
467 rc = npc_parse_item_basic(pst->pattern, &info);
472 * Parse for more labels.
473 * This sets lflags and pst->last_pattern correctly.
475 rc = npc_parse_mpls_label_stack(pst, &lflags);
480 pst->pattern = pst->last_pattern;
482 return npc_update_parse_state(pst, &info, lid, lt, lflags);
486 npc_check_lc_ip_tunnel(struct npc_parse_state *pst)
488 const struct roc_npc_item_info *pattern = pst->pattern + 1;
490 pattern = npc_parse_skip_void_and_any_items(pattern);
491 if (pattern->type == ROC_NPC_ITEM_TYPE_MPLS ||
492 pattern->type == ROC_NPC_ITEM_TYPE_IPV4 ||
493 pattern->type == ROC_NPC_ITEM_TYPE_IPV6)
498 npc_handle_ipv6ext_attr(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
499 struct npc_parse_state *pst, uint8_t *flags)
503 if (ipv6_spec->has_hop_ext) {
504 *flags = NPC_F_LC_L_EXT_HOP;
507 if (ipv6_spec->has_route_ext) {
508 *flags = NPC_F_LC_L_EXT_ROUT;
511 if (ipv6_spec->has_frag_ext) {
512 *flags = NPC_F_LC_U_IP6_FRAG;
515 if (ipv6_spec->has_dest_ext) {
516 *flags = NPC_F_LC_L_EXT_DEST;
519 if (ipv6_spec->has_mobil_ext) {
520 *flags = NPC_F_LC_L_EXT_MOBILITY;
523 if (ipv6_spec->has_hip_ext) {
524 *flags = NPC_F_LC_L_EXT_HOSTID;
527 if (ipv6_spec->has_shim6_ext) {
528 *flags = NPC_F_LC_L_EXT_SHIM6;
531 if (ipv6_spec->has_auth_ext) {
532 pst->lt[NPC_LID_LD] = NPC_LT_LD_AH;
535 if (ipv6_spec->has_esp_ext) {
536 pst->lt[NPC_LID_LE] = NPC_LT_LE_ESP;
544 pst->set_ipv6ext_ltype_mask = true;
550 npc_parse_lc(struct npc_parse_state *pst)
552 const struct roc_npc_flow_item_ipv6 *ipv6_spec;
553 const struct roc_npc_flow_item_raw *raw_spec;
554 uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN];
555 uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN];
556 uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
557 struct npc_parse_item_info info;
558 int rc, lid, lt, len = 0;
561 if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
562 return npc_parse_mpls(pst, NPC_LID_LC);
564 info.def_mask = NULL;
565 info.hw_mask = &hw_mask;
571 switch (pst->pattern->type) {
572 case ROC_NPC_ITEM_TYPE_IPV4:
574 info.len = pst->pattern->size;
576 case ROC_NPC_ITEM_TYPE_IPV6:
577 ipv6_spec = pst->pattern->spec;
581 rc = npc_handle_ipv6ext_attr(ipv6_spec, pst, &flags);
585 info.len = sizeof(ipv6_spec->hdr);
587 case ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4:
589 info.len = pst->pattern->size;
591 case ROC_NPC_ITEM_TYPE_IPV6_EXT:
593 lt = NPC_LT_LC_IP6_EXT;
594 info.len = pst->pattern->size;
595 info.hw_hdr_len = 40;
597 case ROC_NPC_ITEM_TYPE_L3_CUSTOM:
598 lt = NPC_LT_LC_CUSTOM0;
599 info.len = pst->pattern->size;
601 case ROC_NPC_ITEM_TYPE_RAW:
602 raw_spec = pst->pattern->spec;
603 if (!raw_spec->relative)
606 len = raw_spec->length + raw_spec->offset;
607 if (len > NPC_MAX_RAW_ITEM_LEN)
610 npc_flow_raw_item_prepare((const struct roc_npc_flow_item_raw *)
612 (const struct roc_npc_flow_item_raw *)
614 &info, raw_spec_buf, raw_mask_buf);
618 info.hw_mask = &hw_mask;
619 npc_get_hw_supp_mask(pst, &info, lid, lt);
622 /* No match at this layer */
626 /* Identify if IP tunnels MPLS or IPv4/v6 */
627 npc_check_lc_ip_tunnel(pst);
629 npc_get_hw_supp_mask(pst, &info, lid, lt);
630 rc = npc_parse_item_basic(pst->pattern, &info);
635 return npc_update_parse_state(pst, &info, lid, lt, flags);
639 npc_parse_ld(struct npc_parse_state *pst)
641 char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
642 struct npc_parse_item_info info;
647 /* We have already parsed MPLS or IPv4/v6 followed
648 * by MPLS or IPv4/v6. Subsequent TCP/UDP etc
649 * would be parsed as tunneled versions. Skip
650 * this layer, except for tunneled MPLS. If LC is
651 * MPLS, we have anyway skipped all stacked MPLS
654 if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
655 return npc_parse_mpls(pst, NPC_LID_LD);
658 info.def_mask = NULL;
659 info.hw_mask = &hw_mask;
668 switch (pst->pattern->type) {
669 case ROC_NPC_ITEM_TYPE_ICMP:
670 if (pst->lt[NPC_LID_LC] == NPC_LT_LC_IP6)
671 lt = NPC_LT_LD_ICMP6;
674 info.len = pst->pattern->size;
676 case ROC_NPC_ITEM_TYPE_UDP:
678 info.len = pst->pattern->size;
680 case ROC_NPC_ITEM_TYPE_IGMP:
682 info.len = pst->pattern->size;
684 case ROC_NPC_ITEM_TYPE_TCP:
686 info.len = pst->pattern->size;
688 case ROC_NPC_ITEM_TYPE_SCTP:
690 info.len = pst->pattern->size;
692 case ROC_NPC_ITEM_TYPE_GRE:
694 info.len = pst->pattern->size;
696 case ROC_NPC_ITEM_TYPE_GRE_KEY:
698 info.len = pst->pattern->size;
701 case ROC_NPC_ITEM_TYPE_NVGRE:
702 lt = NPC_LT_LD_NVGRE;
703 lflags = NPC_F_GRE_NVGRE;
704 info.len = pst->pattern->size;
705 /* Further IP/Ethernet are parsed as tunneled */
712 npc_get_hw_supp_mask(pst, &info, lid, lt);
713 rc = npc_parse_item_basic(pst->pattern, &info);
717 return npc_update_parse_state(pst, &info, lid, lt, lflags);
721 npc_parse_le(struct npc_parse_state *pst)
723 const struct roc_npc_item_info *pattern = pst->pattern;
724 char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
725 struct npc_parse_item_info info;
732 if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
733 return npc_parse_mpls(pst, NPC_LID_LE);
738 info.def_mask = NULL;
744 /* Ensure we are not matching anything in UDP */
745 rc = npc_parse_item_basic(pattern, &info);
749 info.hw_mask = &hw_mask;
750 pattern = npc_parse_skip_void_and_any_items(pattern);
751 switch (pattern->type) {
752 case ROC_NPC_ITEM_TYPE_VXLAN:
753 lflags = NPC_F_UDP_VXLAN;
754 info.len = pattern->size;
755 lt = NPC_LT_LE_VXLAN;
757 case ROC_NPC_ITEM_TYPE_GTPC:
758 lflags = NPC_F_UDP_GTP_GTPC;
759 info.len = pattern->size;
762 case ROC_NPC_ITEM_TYPE_GTPU:
763 lflags = NPC_F_UDP_GTP_GTPU_G_PDU;
764 info.len = pattern->size;
767 case ROC_NPC_ITEM_TYPE_GENEVE:
768 lflags = NPC_F_UDP_GENEVE;
769 info.len = pattern->size;
770 lt = NPC_LT_LE_GENEVE;
772 case ROC_NPC_ITEM_TYPE_VXLAN_GPE:
773 lflags = NPC_F_UDP_VXLANGPE;
774 info.len = pattern->size;
775 lt = NPC_LT_LE_VXLANGPE;
777 case ROC_NPC_ITEM_TYPE_ESP:
779 info.len = pst->pattern->size;
787 npc_get_hw_supp_mask(pst, &info, lid, lt);
788 rc = npc_parse_item_basic(pattern, &info);
792 return npc_update_parse_state(pst, &info, lid, lt, lflags);
796 npc_parse_lf(struct npc_parse_state *pst)
798 const struct roc_npc_item_info *pattern, *last_pattern;
799 char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
800 struct npc_parse_item_info info;
805 /* We hit this layer if there is a tunneling protocol */
809 if (pst->pattern->type != ROC_NPC_ITEM_TYPE_ETH)
813 lt = NPC_LT_LF_TU_ETHER;
816 /* No match support for vlan tags */
817 info.def_mask = NULL;
819 info.len = pst->pattern->size;
824 /* Look ahead and find out any VLAN tags. These can be
825 * detected but no data matching is available.
827 last_pattern = pst->pattern;
828 pattern = pst->pattern + 1;
829 pattern = npc_parse_skip_void_and_any_items(pattern);
830 while (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) {
832 last_pattern = pattern;
834 pattern = npc_parse_skip_void_and_any_items(pattern);
840 lflags = NPC_F_TU_ETHER_CTAG;
843 lflags = NPC_F_TU_ETHER_STAG_CTAG;
846 return NPC_ERR_PATTERN_NOTSUP;
849 info.hw_mask = &hw_mask;
850 info.len = pst->pattern->size;
852 npc_get_hw_supp_mask(pst, &info, lid, lt);
856 rc = npc_parse_item_basic(pst->pattern, &info);
860 pst->pattern = last_pattern;
862 return npc_update_parse_state(pst, &info, lid, lt, lflags);
866 npc_parse_lg(struct npc_parse_state *pst)
868 char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
869 struct npc_parse_item_info info;
876 info.def_mask = NULL;
877 info.hw_mask = &hw_mask;
883 if (pst->pattern->type == ROC_NPC_ITEM_TYPE_IPV4) {
884 lt = NPC_LT_LG_TU_IP;
885 info.len = pst->pattern->size;
886 } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_IPV6) {
887 lt = NPC_LT_LG_TU_IP6;
888 info.len = pst->pattern->size;
890 /* There is no tunneled IP header */
894 npc_get_hw_supp_mask(pst, &info, lid, lt);
895 rc = npc_parse_item_basic(pst->pattern, &info);
899 return npc_update_parse_state(pst, &info, lid, lt, 0);
903 npc_parse_lh(struct npc_parse_state *pst)
905 char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
906 struct npc_parse_item_info info;
913 info.def_mask = NULL;
914 info.hw_mask = &hw_mask;
920 switch (pst->pattern->type) {
921 case ROC_NPC_ITEM_TYPE_UDP:
922 lt = NPC_LT_LH_TU_UDP;
923 info.len = pst->pattern->size;
925 case ROC_NPC_ITEM_TYPE_TCP:
926 lt = NPC_LT_LH_TU_TCP;
927 info.len = pst->pattern->size;
929 case ROC_NPC_ITEM_TYPE_SCTP:
930 lt = NPC_LT_LH_TU_SCTP;
931 info.len = pst->pattern->size;
933 case ROC_NPC_ITEM_TYPE_ESP:
934 lt = NPC_LT_LH_TU_ESP;
935 info.len = pst->pattern->size;
941 npc_get_hw_supp_mask(pst, &info, lid, lt);
942 rc = npc_parse_item_basic(pst->pattern, &info);
946 return npc_update_parse_state(pst, &info, lid, lt, 0);