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) {
354 vlan_item[0] = pst->pattern->spec;
356 info.len = sizeof(vlan_item[0]->hdr);
357 lt = NPC_LT_LB_STAG_QINQ;
358 lflags = NPC_F_STAG_CTAG;
359 if (vlan_item[0] && vlan_item[0]->has_more_vlan) {
360 lflags = NPC_F_LB_L_WITH_QINQ_CTAG &
361 NPC_F_LB_L_WITH_QINQ_QINQ;
363 } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_RAW) {
364 raw_spec = pst->pattern->spec;
365 if (raw_spec->relative)
367 len = raw_spec->length + raw_spec->offset;
368 if (len > NPC_MAX_RAW_ITEM_LEN)
371 if (pst->npc->switch_header_type == ROC_PRIV_FLAGS_VLAN_EXDSA) {
372 lt = NPC_LT_LB_VLAN_EXDSA;
373 } else if (pst->npc->switch_header_type ==
374 ROC_PRIV_FLAGS_EXDSA) {
375 lt = NPC_LT_LB_EXDSA;
380 npc_flow_raw_item_prepare((const struct roc_npc_flow_item_raw *)
382 (const struct roc_npc_flow_item_raw *)
384 &info, raw_spec_buf, raw_mask_buf);
391 info.hw_mask = &hw_mask;
392 npc_get_hw_supp_mask(pst, &info, lid, lt);
394 rc = npc_parse_item_basic(pst->pattern, &info);
398 /* Point pattern to last item consumed */
399 pst->pattern = last_pattern;
400 return npc_update_parse_state(pst, &info, lid, lt, lflags);
404 npc_parse_mpls_label_stack(struct npc_parse_state *pst, int *flag)
406 uint8_t flag_list[] = {0, NPC_F_MPLS_2_LABELS, NPC_F_MPLS_3_LABELS,
407 NPC_F_MPLS_4_LABELS};
408 const struct roc_npc_item_info *pattern = pst->pattern;
409 struct npc_parse_item_info info;
414 * pst->pattern points to first MPLS label. We only check
415 * that subsequent labels do not have anything to match.
417 info.def_mask = NULL;
419 info.len = pattern->size;
424 while (pattern->type == ROC_NPC_ITEM_TYPE_MPLS) {
427 /* Basic validation of Second/Third/Fourth mpls item */
429 rc = npc_parse_item_basic(pattern, &info);
433 pst->last_pattern = pattern;
435 pattern = npc_parse_skip_void_and_any_items(pattern);
438 if (nr_labels < 1 || nr_labels > 4)
439 return NPC_ERR_PATTERN_NOTSUP;
441 *flag = flag_list[nr_labels - 1];
446 npc_parse_mpls(struct npc_parse_state *pst, int lid)
448 /* Find number of MPLS labels */
449 uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
450 struct npc_parse_item_info info;
456 if (lid == NPC_LID_LC)
458 else if (lid == NPC_LID_LD)
459 lt = NPC_LT_LD_TU_MPLS_IN_IP;
461 lt = NPC_LT_LE_TU_MPLS_IN_UDP;
463 /* Prepare for parsing the first item */
464 info.hw_mask = &hw_mask;
465 info.len = pst->pattern->size;
468 info.def_mask = NULL;
471 npc_get_hw_supp_mask(pst, &info, lid, lt);
472 rc = npc_parse_item_basic(pst->pattern, &info);
477 * Parse for more labels.
478 * This sets lflags and pst->last_pattern correctly.
480 rc = npc_parse_mpls_label_stack(pst, &lflags);
485 pst->pattern = pst->last_pattern;
487 return npc_update_parse_state(pst, &info, lid, lt, lflags);
491 npc_check_lc_ip_tunnel(struct npc_parse_state *pst)
493 const struct roc_npc_item_info *pattern = pst->pattern + 1;
495 pattern = npc_parse_skip_void_and_any_items(pattern);
496 if (pattern->type == ROC_NPC_ITEM_TYPE_MPLS ||
497 pattern->type == ROC_NPC_ITEM_TYPE_IPV4 ||
498 pattern->type == ROC_NPC_ITEM_TYPE_IPV6)
503 npc_handle_ipv6ext_attr(const struct roc_npc_flow_item_ipv6 *ipv6_spec,
504 struct npc_parse_state *pst, uint8_t *flags)
508 if (ipv6_spec->has_hop_ext) {
509 *flags = NPC_F_LC_L_EXT_HOP;
512 if (ipv6_spec->has_route_ext) {
513 *flags = NPC_F_LC_L_EXT_ROUT;
516 if (ipv6_spec->has_frag_ext) {
517 *flags = NPC_F_LC_U_IP6_FRAG;
520 if (ipv6_spec->has_dest_ext) {
521 *flags = NPC_F_LC_L_EXT_DEST;
524 if (ipv6_spec->has_mobil_ext) {
525 *flags = NPC_F_LC_L_EXT_MOBILITY;
528 if (ipv6_spec->has_hip_ext) {
529 *flags = NPC_F_LC_L_EXT_HOSTID;
532 if (ipv6_spec->has_shim6_ext) {
533 *flags = NPC_F_LC_L_EXT_SHIM6;
536 if (ipv6_spec->has_auth_ext) {
537 pst->lt[NPC_LID_LD] = NPC_LT_LD_AH;
540 if (ipv6_spec->has_esp_ext) {
541 pst->lt[NPC_LID_LE] = NPC_LT_LE_ESP;
549 pst->set_ipv6ext_ltype_mask = true;
555 npc_parse_lc(struct npc_parse_state *pst)
557 const struct roc_npc_flow_item_ipv6 *ipv6_spec;
558 const struct roc_npc_flow_item_raw *raw_spec;
559 uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN];
560 uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN];
561 uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
562 struct npc_parse_item_info info;
563 int rc, lid, lt, len = 0;
566 if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
567 return npc_parse_mpls(pst, NPC_LID_LC);
569 info.def_mask = NULL;
570 info.hw_mask = &hw_mask;
576 switch (pst->pattern->type) {
577 case ROC_NPC_ITEM_TYPE_IPV4:
579 info.len = pst->pattern->size;
581 case ROC_NPC_ITEM_TYPE_IPV6:
582 ipv6_spec = pst->pattern->spec;
586 rc = npc_handle_ipv6ext_attr(ipv6_spec, pst, &flags);
590 info.len = sizeof(ipv6_spec->hdr);
592 case ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4:
594 info.len = pst->pattern->size;
596 case ROC_NPC_ITEM_TYPE_IPV6_EXT:
598 lt = NPC_LT_LC_IP6_EXT;
599 info.len = pst->pattern->size;
600 info.hw_hdr_len = 40;
602 case ROC_NPC_ITEM_TYPE_L3_CUSTOM:
603 lt = NPC_LT_LC_CUSTOM0;
604 info.len = pst->pattern->size;
606 case ROC_NPC_ITEM_TYPE_RAW:
607 raw_spec = pst->pattern->spec;
608 if (!raw_spec->relative)
611 len = raw_spec->length + raw_spec->offset;
612 if (len > NPC_MAX_RAW_ITEM_LEN)
615 npc_flow_raw_item_prepare((const struct roc_npc_flow_item_raw *)
617 (const struct roc_npc_flow_item_raw *)
619 &info, raw_spec_buf, raw_mask_buf);
623 info.hw_mask = &hw_mask;
624 npc_get_hw_supp_mask(pst, &info, lid, lt);
627 /* No match at this layer */
631 /* Identify if IP tunnels MPLS or IPv4/v6 */
632 npc_check_lc_ip_tunnel(pst);
634 npc_get_hw_supp_mask(pst, &info, lid, lt);
635 rc = npc_parse_item_basic(pst->pattern, &info);
640 return npc_update_parse_state(pst, &info, lid, lt, flags);
644 npc_parse_ld(struct npc_parse_state *pst)
646 char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
647 struct npc_parse_item_info info;
652 /* We have already parsed MPLS or IPv4/v6 followed
653 * by MPLS or IPv4/v6. Subsequent TCP/UDP etc
654 * would be parsed as tunneled versions. Skip
655 * this layer, except for tunneled MPLS. If LC is
656 * MPLS, we have anyway skipped all stacked MPLS
659 if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
660 return npc_parse_mpls(pst, NPC_LID_LD);
663 info.def_mask = NULL;
664 info.hw_mask = &hw_mask;
673 switch (pst->pattern->type) {
674 case ROC_NPC_ITEM_TYPE_ICMP:
675 if (pst->lt[NPC_LID_LC] == NPC_LT_LC_IP6)
676 lt = NPC_LT_LD_ICMP6;
679 info.len = pst->pattern->size;
681 case ROC_NPC_ITEM_TYPE_UDP:
683 info.len = pst->pattern->size;
685 case ROC_NPC_ITEM_TYPE_IGMP:
687 info.len = pst->pattern->size;
689 case ROC_NPC_ITEM_TYPE_TCP:
691 info.len = pst->pattern->size;
693 case ROC_NPC_ITEM_TYPE_SCTP:
695 info.len = pst->pattern->size;
697 case ROC_NPC_ITEM_TYPE_GRE:
699 info.len = pst->pattern->size;
701 case ROC_NPC_ITEM_TYPE_GRE_KEY:
703 info.len = pst->pattern->size;
706 case ROC_NPC_ITEM_TYPE_NVGRE:
707 lt = NPC_LT_LD_NVGRE;
708 lflags = NPC_F_GRE_NVGRE;
709 info.len = pst->pattern->size;
710 /* Further IP/Ethernet are parsed as tunneled */
717 npc_get_hw_supp_mask(pst, &info, lid, lt);
718 rc = npc_parse_item_basic(pst->pattern, &info);
722 return npc_update_parse_state(pst, &info, lid, lt, lflags);
726 npc_parse_le(struct npc_parse_state *pst)
728 const struct roc_npc_item_info *pattern = pst->pattern;
729 char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
730 struct npc_parse_item_info info;
737 if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
738 return npc_parse_mpls(pst, NPC_LID_LE);
743 info.def_mask = NULL;
749 /* Ensure we are not matching anything in UDP */
750 rc = npc_parse_item_basic(pattern, &info);
754 info.hw_mask = &hw_mask;
755 pattern = npc_parse_skip_void_and_any_items(pattern);
756 switch (pattern->type) {
757 case ROC_NPC_ITEM_TYPE_VXLAN:
758 lflags = NPC_F_UDP_VXLAN;
759 info.len = pattern->size;
760 lt = NPC_LT_LE_VXLAN;
762 case ROC_NPC_ITEM_TYPE_GTPC:
763 lflags = NPC_F_UDP_GTP_GTPC;
764 info.len = pattern->size;
767 case ROC_NPC_ITEM_TYPE_GTPU:
768 lflags = NPC_F_UDP_GTP_GTPU_G_PDU;
769 info.len = pattern->size;
772 case ROC_NPC_ITEM_TYPE_GENEVE:
773 lflags = NPC_F_UDP_GENEVE;
774 info.len = pattern->size;
775 lt = NPC_LT_LE_GENEVE;
777 case ROC_NPC_ITEM_TYPE_VXLAN_GPE:
778 lflags = NPC_F_UDP_VXLANGPE;
779 info.len = pattern->size;
780 lt = NPC_LT_LE_VXLANGPE;
782 case ROC_NPC_ITEM_TYPE_ESP:
784 info.len = pst->pattern->size;
792 npc_get_hw_supp_mask(pst, &info, lid, lt);
793 rc = npc_parse_item_basic(pattern, &info);
797 return npc_update_parse_state(pst, &info, lid, lt, lflags);
801 npc_parse_lf(struct npc_parse_state *pst)
803 const struct roc_npc_item_info *pattern, *last_pattern;
804 char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
805 struct npc_parse_item_info info;
810 /* We hit this layer if there is a tunneling protocol */
814 if (pst->pattern->type != ROC_NPC_ITEM_TYPE_ETH)
818 lt = NPC_LT_LF_TU_ETHER;
821 /* No match support for vlan tags */
822 info.def_mask = NULL;
824 info.len = pst->pattern->size;
829 /* Look ahead and find out any VLAN tags. These can be
830 * detected but no data matching is available.
832 last_pattern = pst->pattern;
833 pattern = pst->pattern + 1;
834 pattern = npc_parse_skip_void_and_any_items(pattern);
835 while (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) {
837 last_pattern = pattern;
839 pattern = npc_parse_skip_void_and_any_items(pattern);
845 lflags = NPC_F_TU_ETHER_CTAG;
848 lflags = NPC_F_TU_ETHER_STAG_CTAG;
851 return NPC_ERR_PATTERN_NOTSUP;
854 info.hw_mask = &hw_mask;
855 info.len = pst->pattern->size;
857 npc_get_hw_supp_mask(pst, &info, lid, lt);
861 rc = npc_parse_item_basic(pst->pattern, &info);
865 pst->pattern = last_pattern;
867 return npc_update_parse_state(pst, &info, lid, lt, lflags);
871 npc_parse_lg(struct npc_parse_state *pst)
873 char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
874 struct npc_parse_item_info info;
881 info.def_mask = NULL;
882 info.hw_mask = &hw_mask;
888 if (pst->pattern->type == ROC_NPC_ITEM_TYPE_IPV4) {
889 lt = NPC_LT_LG_TU_IP;
890 info.len = pst->pattern->size;
891 } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_IPV6) {
892 lt = NPC_LT_LG_TU_IP6;
893 info.len = pst->pattern->size;
895 /* There is no tunneled IP header */
899 npc_get_hw_supp_mask(pst, &info, lid, lt);
900 rc = npc_parse_item_basic(pst->pattern, &info);
904 return npc_update_parse_state(pst, &info, lid, lt, 0);
908 npc_parse_lh(struct npc_parse_state *pst)
910 char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
911 struct npc_parse_item_info info;
918 info.def_mask = NULL;
919 info.hw_mask = &hw_mask;
925 switch (pst->pattern->type) {
926 case ROC_NPC_ITEM_TYPE_UDP:
927 lt = NPC_LT_LH_TU_UDP;
928 info.len = pst->pattern->size;
930 case ROC_NPC_ITEM_TYPE_TCP:
931 lt = NPC_LT_LH_TU_TCP;
932 info.len = pst->pattern->size;
934 case ROC_NPC_ITEM_TYPE_SCTP:
935 lt = NPC_LT_LH_TU_SCTP;
936 info.len = pst->pattern->size;
938 case ROC_NPC_ITEM_TYPE_ESP:
939 lt = NPC_LT_LH_TU_ESP;
940 info.len = pst->pattern->size;
946 npc_get_hw_supp_mask(pst, &info, lid, lt);
947 rc = npc_parse_item_basic(pst->pattern, &info);
951 return npc_update_parse_state(pst, &info, lid, lt, 0);