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