Please ignore this patch,  the baseline of the patch is incorrect.

Thanks,
            Yunjian

> -----Original Message-----
> From: wangyunjian
> Sent: Wednesday, January 16, 2019 2:28 PM
> To: [email protected]
> Cc: [email protected]; xudingke <[email protected]>; wangyunjian
> <[email protected]>
> Subject: [ovs-dev] [PATCH] odp-util: Fix parsing QinQ packet in
> parse_8021q_onward.
> 
> From: Yunjian Wang <[email protected]>
> 
> A problem the userspace datapath failed to create a new datapath flow
> when dealing with QinQ packets(the flow includeing ip,udp,etc). L2-L5
> header should be considered before parsing the second 802.1Q header.
> 
> Fixes: f0fb825a3785 ("Add support for 802.1ad (QinQ tunneling)")
> Signed-off-by: Yunjian Wang <[email protected]>
> ---
>  lib/odp-util.c | 72 
> +++++++++++++++++++++++-----------------------------------
>  1 file changed, 29 insertions(+), 43 deletions(-)
> 
> diff --git a/lib/odp-util.c b/lib/odp-util.c
> index 1e8c5f1..089023b 100644
> --- a/lib/odp-util.c
> +++ b/lib/odp-util.c
> @@ -6325,9 +6325,9 @@ parse_ethertype(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>  static enum odp_key_fitness
>  parse_l2_5_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1],
>                    uint64_t present_attrs, int out_of_range_attr,
> -                  uint64_t expected_attrs, struct flow *flow,
> +                  uint64_t *expected_attrs, struct flow *flow,
>                    const struct nlattr *key, size_t key_len,
> -                  const struct flow *src_flow)
> +                  const struct flow *src_flow, bool need_check)
>  {
>      static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
>      bool is_mask = src_flow != flow;
> @@ -6337,7 +6337,7 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
> 
>      if (eth_type_mpls(src_flow->dl_type)) {
>          if (!is_mask || present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_MPLS))
> {
> -            expected_attrs |= (UINT64_C(1) << OVS_KEY_ATTR_MPLS);
> +            *expected_attrs |= (UINT64_C(1) << OVS_KEY_ATTR_MPLS);
>          }
>          if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_MPLS)) {
>              size_t size = nl_attr_get_size(attrs[OVS_KEY_ATTR_MPLS]);
> @@ -6378,7 +6378,7 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>          goto done;
>      } else if (src_flow->dl_type == htons(ETH_TYPE_IP)) {
>          if (!is_mask) {
> -            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IPV4;
> +            *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IPV4;
>          }
>          if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IPV4)) {
>              const struct ovs_key_ipv4 *ipv4_key;
> @@ -6396,7 +6396,7 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>          }
>      } else if (src_flow->dl_type == htons(ETH_TYPE_IPV6)) {
>          if (!is_mask) {
> -            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IPV6;
> +            *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IPV6;
>          }
>          if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IPV6)) {
>              const struct ovs_key_ipv6 *ipv6_key;
> @@ -6415,7 +6415,7 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>      } else if (src_flow->dl_type == htons(ETH_TYPE_ARP) ||
>                 src_flow->dl_type == htons(ETH_TYPE_RARP)) {
>          if (!is_mask) {
> -            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ARP;
> +            *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ARP;
>          }
>          if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ARP)) {
>              const struct ovs_key_arp *arp_key;
> @@ -6433,18 +6433,6 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>                  expected_bit = OVS_KEY_ATTR_ARP;
>              }
>          }
> -    } else if (src_flow->dl_type == htons(ETH_TYPE_NSH)) {
> -        if (!is_mask) {
> -            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_NSH;
> -        }
> -        if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_NSH)) {
> -            odp_nsh_key_from_attr(attrs[OVS_KEY_ATTR_NSH], &flow->nsh,
> NULL);
> -            if (is_mask) {
> -                check_start = nl_attr_get(attrs[OVS_KEY_ATTR_NSH]);
> -                check_len = nl_attr_get_size(attrs[OVS_KEY_ATTR_NSH]);
> -                expected_bit = OVS_KEY_ATTR_NSH;
> -            }
> -        }
>      } else {
>          goto done;
>      }
> @@ -6453,7 +6441,7 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>              flow->dl_type != htons(0xffff)) {
>              return ODP_FIT_ERROR;
>          } else {
> -            expected_attrs |= UINT64_C(1) << expected_bit;
> +            *expected_attrs |= UINT64_C(1) << expected_bit;
>          }
>      }
> 
> @@ -6463,7 +6451,7 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>              src_flow->dl_type == htons(ETH_TYPE_IPV6))
>          && !(src_flow->nw_frag & FLOW_NW_FRAG_LATER)) {
>          if (!is_mask) {
> -            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_TCP;
> +            *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_TCP;
>          }
>          if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_TCP)) {
>              const union ovs_key_tp *tcp_key;
> @@ -6473,7 +6461,7 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>              expected_bit = OVS_KEY_ATTR_TCP;
>          }
>          if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_TCP_FLAGS)) {
> -            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_TCP_FLAGS;
> +            *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_TCP_FLAGS;
>              flow->tcp_flags =
> nl_attr_get_be16(attrs[OVS_KEY_ATTR_TCP_FLAGS]);
>          }
>      } else if (src_flow->nw_proto == IPPROTO_UDP
> @@ -6481,7 +6469,7 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>                     src_flow->dl_type == htons(ETH_TYPE_IPV6))
>                 && !(src_flow->nw_frag & FLOW_NW_FRAG_LATER)) {
>          if (!is_mask) {
> -            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_UDP;
> +            *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_UDP;
>          }
>          if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_UDP)) {
>              const union ovs_key_tp *udp_key;
> @@ -6495,7 +6483,7 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>                     src_flow->dl_type == htons(ETH_TYPE_IPV6))
>                 && !(src_flow->nw_frag & FLOW_NW_FRAG_LATER)) {
>          if (!is_mask) {
> -            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_SCTP;
> +            *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_SCTP;
>          }
>          if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_SCTP)) {
>              const union ovs_key_tp *sctp_key;
> @@ -6508,7 +6496,7 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>                 && src_flow->dl_type == htons(ETH_TYPE_IP)
>                 && !(src_flow->nw_frag & FLOW_NW_FRAG_LATER)) {
>          if (!is_mask) {
> -            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ICMP;
> +            *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ICMP;
>          }
>          if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ICMP)) {
>              const struct ovs_key_icmp *icmp_key;
> @@ -6522,7 +6510,7 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>                 && src_flow->dl_type == htons(ETH_TYPE_IPV6)
>                 && !(src_flow->nw_frag & FLOW_NW_FRAG_LATER)) {
>          if (!is_mask) {
> -            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ICMPV6;
> +            *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ICMPV6;
>          }
>          if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ICMPV6)) {
>              const struct ovs_key_icmpv6 *icmpv6_key;
> @@ -6533,7 +6521,7 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>              expected_bit = OVS_KEY_ATTR_ICMPV6;
>              if (is_nd(src_flow, NULL)) {
>                  if (!is_mask) {
> -                    expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ND;
> +                    *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ND;
>                  }
>                  if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ND)) {
>                      const struct ovs_key_nd *nd_key;
> @@ -6553,29 +6541,24 @@ parse_l2_5_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>                               flow->tp_dst != htons(0xff))) {
>                              return ODP_FIT_ERROR;
>                          } else {
> -                            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ND;
> +                            *expected_attrs |= UINT64_C(1) << 
> OVS_KEY_ATTR_ND;
>                          }
>                      }
>                  }
>              }
>          }
> -    } else if (src_flow->nw_proto == IPPROTO_IGMP
> -               && src_flow->dl_type == htons(ETH_TYPE_IP)) {
> -        /* OVS userspace parses the IGMP type, code, and group, but its
> -         * datapaths do not, so there is always missing information. */
> -        return ODP_FIT_TOO_LITTLE;
>      }
>      if (is_mask && expected_bit != OVS_KEY_ATTR_UNSPEC) {
>          if ((flow->tp_src || flow->tp_dst) && flow->nw_proto != 0xff) {
>              return ODP_FIT_ERROR;
>          } else {
> -            expected_attrs |= UINT64_C(1) << expected_bit;
> +            *expected_attrs |= UINT64_C(1) << expected_bit;
>          }
>      }
> 
>  done:
> -    return check_expectations(present_attrs, out_of_range_attr,
> expected_attrs,
> -                              key, key_len);
> +    return need_check ? check_expectations(present_attrs,
> out_of_range_attr,
> +                            *expected_attrs, key, key_len) : ODP_FIT_PERFECT;
>  }
> 
>  /* Parse 802.1Q header then encapsulated L3 attributes. */
> @@ -6658,16 +6641,18 @@ parse_8021q_onward(const struct nlattr
> *attrs[OVS_KEY_ATTR_MAX + 1],
>                               flow, src_flow)) {
>              return ODP_FIT_ERROR;
>          }
> -
> +        encap_fitness = parse_l2_5_onward(attrs, present_attrs,
> +                                          out_of_range_attr,
> +                                          &expected_attrs,
> +                                          flow, key, key_len,
> +                                          src_flow, false);
> +        if (encap_fitness != ODP_FIT_PERFECT) {
> +            return encap_fitness;
> +        }
>          encaps++;
>      }
> 
> -    encap_fitness = parse_l2_5_onward(attrs, present_attrs,
> out_of_range_attr,
> -                                      expected_attrs, flow, key, key_len,
> -                                      src_flow);
> -
> -    /* The overall fitness is the worse of the outer and inner attributes. */
> -    return MAX(fitness, encap_fitness);
> +    return ODP_FIT_PERFECT;
>  }
> 
>  static enum odp_key_fitness
> @@ -6820,7 +6805,8 @@ odp_flow_key_to_flow__(const struct nlattr *key,
> size_t key_len,
>          }
>      }
>      return parse_l2_5_onward(attrs, present_attrs, out_of_range_attr,
> -                             expected_attrs, flow, key, key_len, src_flow);
> +                             &expected_attrs, flow, key, key_len,
> +                             src_flow, true);
>  }
> 
>  /* Converts the 'key_len' bytes of OVS_KEY_ATTR_* attributes in 'key' to a
> flow
> --
> 1.8.3.1
> 

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to