[{"id":1773042,"web_url":"http://patchwork.ozlabs.org/comment/1773042/","msgid":"<00acad09-79b0-0355-476d-c38400f88f8e@gmail.com>","list_archive_url":null,"date":"2017-09-21T18:14:28","subject":"Re: [ovs-dev] [merge native tunneling and patch port 7/7]\n\tofproto-dpif-xlate: Refactor native tunnel handling logic","submitter":{"id":69140,"url":"http://patchwork.ozlabs.org/api/people/69140/","name":"Gregory Rose","email":"gvrose8192@gmail.com"},"content":"On 09/12/2017 12:49 PM, Andy Zhou wrote:\n> Merge native tunnel handling with patch port handling\n> as much as possible.\n> \n> Current native tunnel handling logic inspects the generated actions\n> to determine if truncate has been applied to the packet. (since if\n> it is then recirculation should be used).  This logic can be\n> simplified by passing the 'truncate' boolean argument into\n> compose_output_action().\n> \n> Signed-off-by: Andy Zhou <azhou@ovn.org>\n> ---\n>   ofproto/ofproto-dpif-xlate.c | 243 +++++++++++++++++--------------------------\n>   1 file changed, 95 insertions(+), 148 deletions(-)\n> \n> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c\n> index 94aa071a37cd..d320d570b304 100644\n> --- a/ofproto/ofproto-dpif-xlate.c\n> +++ b/ofproto/ofproto-dpif-xlate.c\n> @@ -544,7 +544,7 @@ struct xlate_bond_recirc {\n>   \n>   static void compose_output_action(struct xlate_ctx *, ofp_port_t ofp_port,\n>                                     const struct xlate_bond_recirc *xr,\n> -                                  bool is_last_action);\n> +                                  bool is_last_action, bool truncate);\n>   \n>   static struct xbridge *xbridge_lookup(struct xlate_cfg *,\n>                                         const struct ofproto_dpif *);\n> @@ -2227,7 +2227,7 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle,\n>       xvlan_put(&ctx->xin->flow, &out_xvlan);\n>   \n>       compose_output_action(ctx, xport->ofp_port, use_recirc ? &xr : NULL,\n> -                          false);\n> +                          false, false);\n>       memcpy(&ctx->xin->flow.vlans, &old_vlans, sizeof(old_vlans));\n>   }\n>   \n> @@ -3241,130 +3241,10 @@ propagate_tunnel_data_to_flow(struct xlate_ctx *ctx, struct eth_addr dmac,\n>                                       is_tnl_ipv6, nw_proto);\n>   }\n>   \n> -/* Validate if the transalated combined actions are OK to proceed.\n> - * If actions consist of TRUNC action, it is not allowed to do the\n> - * tunnel_push combine as it cannot update stats correctly.\n> - */\n> -static bool\n> -is_tunnel_actions_clone_ready(struct xlate_ctx *ctx)\n> -{\n> -    struct nlattr *tnl_actions;\n> -    const struct nlattr *a;\n> -    unsigned int left;\n> -    size_t actions_len;\n> -    struct ofpbuf *actions = ctx->odp_actions;\n> -\n> -    if (!actions) {\n> -        /* No actions, no harm in doing combine. */\n> -        return true;\n> -    }\n> -\n> -    /* Cannot perform tunnel push on slow path action CONTROLLER_OUTPUT. */\n> -    if (ctx->xout->slow & SLOW_CONTROLLER) {\n> -        return false;\n> -    }\n> -    actions_len = actions->size;\n> -\n> -    tnl_actions =(struct nlattr *)(actions->data);\n> -    NL_ATTR_FOR_EACH_UNSAFE (a, left, tnl_actions, actions_len) {\n> -        int type = nl_attr_type(a);\n> -        if (type == OVS_ACTION_ATTR_TRUNC) {\n> -            VLOG_DBG(\"Cannot do tunnel action-combine on trunc action\");\n> -            return false;\n> -            break;\n> -        }\n> -    }\n> -    return true;\n> -}\n> -\n> -static bool\n> -validate_and_combine_post_tnl_actions(struct xlate_ctx *ctx,\n> -                                      const struct xport *xport,\n> -                                      struct xport *out_dev,\n> -                                      struct ovs_action_push_tnl tnl_push_data)\n> -{\n> -    const struct dpif_flow_stats *backup_resubmit_stats;\n> -    struct xlate_cache *backup_xcache;\n> -    bool nested_act_flag = false;\n> -    struct flow_wildcards tmp_flow_wc;\n> -    struct flow_wildcards *backup_flow_wc_ptr;\n> -    bool backup_side_effects;\n> -    const struct dp_packet *backup_pkt;\n> -\n> -    memset(&tmp_flow_wc, 0 , sizeof tmp_flow_wc);\n> -    backup_flow_wc_ptr = ctx->wc;\n> -    ctx->wc = &tmp_flow_wc;\n> -    ctx->xin->wc = NULL;\n> -    backup_resubmit_stats = ctx->xin->resubmit_stats;\n> -    backup_xcache = ctx->xin->xcache;\n> -    backup_side_effects = ctx->xin->allow_side_effects;\n> -    backup_pkt = ctx->xin->packet;\n> -\n> -    size_t push_action_size = 0;\n> -    size_t clone_ofs = nl_msg_start_nested(ctx->odp_actions,\n> -                                           OVS_ACTION_ATTR_CLONE);\n> -    odp_put_tnl_push_action(ctx->odp_actions, &tnl_push_data);\n> -    push_action_size = ctx->odp_actions->size;\n> -\n> -    ctx->xin->resubmit_stats =  NULL;\n> -    ctx->xin->xcache = xlate_cache_new(); /* Use new temporary cache. */\n> -    ctx->xin->allow_side_effects = false;\n> -    ctx->xin->packet = NULL;\n> -\n> -    /* Push the cache entry for the tunnel first. */\n> -    struct xc_entry *entry;\n> -    entry = xlate_cache_add_entry(ctx->xin->xcache, XC_TUNNEL_HEADER);\n> -    entry->tunnel_hdr.hdr_size = tnl_push_data.header_len;\n> -    entry->tunnel_hdr.operation = ADD;\n> -\n> -    patch_port_output(ctx, xport, out_dev);\n> -    nested_act_flag = is_tunnel_actions_clone_ready(ctx);\n> -\n> -    if (nested_act_flag) {\n> -         /* Similar to the stats update in revalidation, the x_cache entries\n> -          * are populated by the previous translation are used to update the\n> -          * stats correctly.\n> -          */\n> -        if (backup_resubmit_stats) {\n> -            struct dpif_flow_stats tmp_resubmit_stats;\n> -            memcpy(&tmp_resubmit_stats, backup_resubmit_stats,\n> -                   sizeof tmp_resubmit_stats);\n> -            xlate_push_stats(ctx->xin->xcache, &tmp_resubmit_stats);\n> -        }\n> -        xlate_cache_steal_entries(backup_xcache, ctx->xin->xcache);\n> -    } else {\n> -        /* Combine is not valid. */\n> -        nl_msg_cancel_nested(ctx->odp_actions, clone_ofs);\n> -        goto out;\n> -    }\n> -    if (ctx->odp_actions->size > push_action_size) {\n> -        /* Update the CLONE action only when combined. */\n> -        nl_msg_end_nested(ctx->odp_actions, clone_ofs);\n> -    } else {\n> -        nl_msg_cancel_nested(ctx->odp_actions, clone_ofs);\n> -        /* XXX : There is no real use-case for a tunnel push without\n> -         * any post actions. However keeping it now\n> -         * as is to make the 'make check' happy. Should remove when all the\n> -         * make check tunnel test case does something meaningful on a\n> -         * tunnel encap packets.\n> -         */\n> -        odp_put_tnl_push_action(ctx->odp_actions, &tnl_push_data);\n> -    }\n> -\n> -out:\n> -    /* Restore context status. */\n> -    ctx->xin->resubmit_stats = backup_resubmit_stats;\n> -    xlate_cache_delete(ctx->xin->xcache);\n> -    ctx->xin->xcache = backup_xcache;\n> -    ctx->xin->allow_side_effects = backup_side_effects;\n> -    ctx->xin->packet = backup_pkt;\n> -    ctx->wc = backup_flow_wc_ptr;\n> -    return nested_act_flag;\n> -}\n> -\n>   static int\n> -build_tunnel_send(struct xlate_ctx *ctx, const struct xport *xport,\n> -                  const struct flow *flow, odp_port_t tunnel_odp_port)\n> +native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport,\n> +                     const struct flow *flow, odp_port_t tunnel_odp_port,\n> +                     bool truncate)\n>   {\n>       struct netdev_tnl_build_header_params tnl_params;\n>       struct ovs_action_push_tnl tnl_push_data;\n> @@ -3449,24 +3329,83 @@ build_tunnel_send(struct xlate_ctx *ctx, const struct xport *xport,\n>        * base_flow need to be set properly, since there is not recirculation\n>        * any more when sending packet to tunnel. */\n>   \n> -    propagate_tunnel_data_to_flow(ctx, dmac, smac, s_ip6, s_ip,\n> -                                  tnl_params.is_ipv6, tnl_push_data.tnl_type);\n> +    propagate_tunnel_data_to_flow(ctx, dmac, smac, s_ip6,\n> +                                  s_ip, tnl_params.is_ipv6,\n> +                                  tnl_push_data.tnl_type);\n>   \n> +    size_t clone_ofs = 0;\n> +    size_t push_action_size;\n>   \n> -    /* Try to see if its possible to apply nested clone actions on tunnel.\n> -     * Revert the combined actions on tunnel if its not valid.\n> -     */\n> -    if (!validate_and_combine_post_tnl_actions(ctx, xport, out_dev,\n> -                                      tnl_push_data)) {\n> -        /* Datapath is not doing the recirculation now, so lets make it\n> -         * happen explicitly.\n> +    clone_ofs = nl_msg_start_nested(ctx->odp_actions, OVS_ACTION_ATTR_CLONE);\n> +    odp_put_tnl_push_action(ctx->odp_actions, &tnl_push_data);\n> +    push_action_size = ctx->odp_actions->size;\n> +\n> +    if (!truncate) {\n> +        const struct dpif_flow_stats *backup_resubmit_stats;\n> +        struct xlate_cache *backup_xcache;\n> +        struct flow_wildcards *backup_wc, wc;\n> +        bool backup_side_effects;\n> +        const struct dp_packet *backup_packet;\n> +\n> +        memset(&wc, 0 , sizeof wc);\n> +        backup_wc = ctx->wc;\n> +        ctx->wc = &wc;\n> +        ctx->xin->wc = NULL;\n> +        backup_resubmit_stats = ctx->xin->resubmit_stats;\n> +        backup_xcache = ctx->xin->xcache;\n> +        backup_side_effects = ctx->xin->allow_side_effects;\n> +        backup_packet = ctx->xin->packet;\n> +\n> +        ctx->xin->resubmit_stats =  NULL;\n> +        ctx->xin->xcache = xlate_cache_new(); /* Use new temporary cache. */\n> +        ctx->xin->allow_side_effects = false;\n> +        ctx->xin->packet = NULL;\n> +\n> +        /* Push the cache entry for the tunnel first. */\n> +        struct xc_entry *entry;\n> +        entry = xlate_cache_add_entry(ctx->xin->xcache, XC_TUNNEL_HEADER);\n> +        entry->tunnel_hdr.hdr_size = tnl_push_data.header_len;\n> +        entry->tunnel_hdr.operation = ADD;\n> +\n> +        patch_port_output(ctx, xport, out_dev);\n> +\n> +        /* Similar to the stats update in revalidation, the x_cache entries\n> +         * are populated by the previous translation are used to update the\n> +         * stats correctly.\n>            */\n> -        size_t clone_ofs = nl_msg_start_nested(ctx->odp_actions,\n> -                                        OVS_ACTION_ATTR_CLONE);\n> -        odp_put_tnl_push_action(ctx->odp_actions, &tnl_push_data);\n> +        if (backup_resubmit_stats) {\n> +            struct dpif_flow_stats stats = *backup_resubmit_stats;\n> +            xlate_push_stats(ctx->xin->xcache, &stats);\n> +        }\n> +        xlate_cache_steal_entries(backup_xcache, ctx->xin->xcache);\n> +\n> +        if (ctx->odp_actions->size > push_action_size) {\n> +            nl_msg_end_non_empty_nested(ctx->odp_actions, clone_ofs);\n> +        } else {\n> +            nl_msg_cancel_nested(ctx->odp_actions, clone_ofs);\n> +            /* XXX : There is no real use-case for a tunnel push without\n> +             * any post actions. However keeping it now\n> +             * as is to make the 'make check' happy. Should remove when all the\n> +             * make check tunnel test case does something meaningful on a\n> +             * tunnel encap packets.\n> +             */\n> +            odp_put_tnl_push_action(ctx->odp_actions, &tnl_push_data);\n> +        }\n> +\n> +        /* Restore context status. */\n> +        ctx->xin->resubmit_stats = backup_resubmit_stats;\n> +        xlate_cache_delete(ctx->xin->xcache);\n> +        ctx->xin->xcache = backup_xcache;\n> +        ctx->xin->allow_side_effects = backup_side_effects;\n> +        ctx->xin->packet = backup_packet;\n> +        ctx->wc = backup_wc;\n> +    } else {\n> +        /* In order to maintain accurate stats, use recirc for\n> +         * natvie tunneling.  */\n>           nl_msg_put_u32(ctx->odp_actions, OVS_ACTION_ATTR_RECIRC, 0);\n>           nl_msg_end_nested(ctx->odp_actions, clone_ofs);\n>       }\n> +\n>       /* Restore the flows after the translation. */\n>       memcpy(&ctx->xin->flow, &old_flow, sizeof ctx->xin->flow);\n>       memcpy(&ctx->base_flow, &old_base_flow, sizeof ctx->base_flow);\n> @@ -3727,7 +3666,7 @@ terminate_native_tunnel(struct xlate_ctx *ctx, ofp_port_t ofp_port,\n>   static void\n>   compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,\n>                           const struct xlate_bond_recirc *xr, bool check_stp,\n> -                        bool is_last_action OVS_UNUSED)\n> +                        bool is_last_action OVS_UNUSED, bool truncate)\n>   {\n>       const struct xport *xport = get_ofp_port(ctx->xbridge, ofp_port);\n>       struct flow_wildcards *wc = ctx->wc;\n> @@ -3761,6 +3700,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,\n>       }\n>   \n>       if (xport->peer) {\n> +       ovs_assert(!truncate)\n>          patch_port_output(ctx, xport, xport->peer);\n>          return;\n>       }\n> @@ -3837,7 +3777,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,\n>                              xr->recirc_id);\n>           } else if (is_native_tunnel) {\n>               /* Output to native tunnel port. */\n> -            build_tunnel_send(ctx, xport, flow, odp_port);\n> +            native_tunnel_output(ctx, xport, flow, odp_port, truncate);\n>               flow->tunnel = flow_tnl; /* Restore tunnel metadata */\n>   \n>           } else if (terminate_native_tunnel(ctx, ofp_port, flow, wc,\n> @@ -3894,9 +3834,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,\n>   static void\n>   compose_output_action(struct xlate_ctx *ctx, ofp_port_t ofp_port,\n>                         const struct xlate_bond_recirc *xr,\n> -                      bool is_last_action)\n> +                      bool is_last_action, bool truncate)\n>   {\n> -    compose_output_action__(ctx, ofp_port, xr, true, is_last_action);\n> +    compose_output_action__(ctx, ofp_port, xr, true,\n> +                            is_last_action, truncate);\n>   }\n>   \n>   static void\n> @@ -4363,9 +4304,10 @@ flood_packet_to_port(struct xlate_ctx *ctx, const struct xport *xport,\n>   \n>       if (all) {\n>           compose_output_action__(ctx, xport->ofp_port, NULL, false,\n> -                                is_last_action);\n> +                                is_last_action, false);\n>       } else {\n> -        compose_output_action(ctx, xport->ofp_port, NULL, is_last_action);\n> +        compose_output_action(ctx, xport->ofp_port, NULL, is_last_action,\n> +                              false);\n>       }\n>   }\n>   \n> @@ -4887,26 +4829,31 @@ xlate_output_action(struct xlate_ctx *ctx,\n>                       bool is_last_action)\n>   {\n>       ofp_port_t prev_nf_output_iface = ctx->nf_output_iface;\n> +    bool truncate = max_len != 0;\n>   \n>       ctx->nf_output_iface = NF_OUT_DROP;\n>   \n>       switch (port) {\n>       case OFPP_IN_PORT:\n>           compose_output_action(ctx, ctx->xin->flow.in_port.ofp_port, NULL,\n> -                              is_last_action);\n> +                              is_last_action, truncate);\n>           break;\n>       case OFPP_TABLE:\n> +        ovs_assert(!truncate);\n>           xlate_table_action(ctx, ctx->xin->flow.in_port.ofp_port,\n> -                           0, may_packet_in, true, false, is_last_action,\n> +                           0, may_packet_in, true, false, false,\n>                              do_xlate_actions);\n>           break;\n>       case OFPP_NORMAL:\n> +        ovs_assert(!truncate);\n>           xlate_normal(ctx);\n>           break;\n>       case OFPP_FLOOD:\n> +        ovs_assert(!truncate);\n>           flood_packets(ctx, false, is_last_action);\n>           break;\n>       case OFPP_ALL:\n> +        ovs_assert(!truncate);\n>           flood_packets(ctx, true, is_last_action);\n>           break;\n>       case OFPP_CONTROLLER:\n> @@ -4922,7 +4869,7 @@ xlate_output_action(struct xlate_ctx *ctx,\n>       case OFPP_LOCAL:\n>       default:\n>           if (port != ctx->xin->flow.in_port.ofp_port) {\n> -            compose_output_action(ctx, port, NULL, is_last_action);\n> +            compose_output_action(ctx, port, NULL, is_last_action, truncate);\n>           } else {\n>               xlate_report(ctx, OFT_WARN, \"skipping output to input port\");\n>           }\n> @@ -5039,7 +4986,7 @@ xlate_enqueue_action(struct xlate_ctx *ctx,\n>       /* Add datapath actions. */\n>       flow_priority = ctx->xin->flow.skb_priority;\n>       ctx->xin->flow.skb_priority = priority;\n> -    compose_output_action(ctx, ofp_port, NULL, is_last_action);\n> +    compose_output_action(ctx, ofp_port, NULL, is_last_action, false);\n>       ctx->xin->flow.skb_priority = flow_priority;\n>   \n>       /* Update NetFlow output port. */\n> @@ -7190,7 +7137,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)\n>               && xbridge->has_in_band\n>               && in_band_must_output_to_local_port(flow)\n>               && !actions_output_to_local_port(&ctx)) {\n> -            compose_output_action(&ctx, OFPP_LOCAL, NULL, false);\n> +            compose_output_action(&ctx, OFPP_LOCAL, NULL, false, false);\n>           }\n>   \n>           if (user_cookie_offset) {\n> \n\nLooks like a nice job of refactoring for this patch series.  Thanks Andy!\n\nTested-by: Greg Rose <gvrose8192@gmail.com>\nReviewed-by: Greg Rose <gvrose8192@gmail.com>","headers":{"Return-Path":"<ovs-dev-bounces@openvswitch.org>","X-Original-To":["incoming@patchwork.ozlabs.org","dev@openvswitch.org"],"Delivered-To":["patchwork-incoming@bilbo.ozlabs.org","ovs-dev@mail.linuxfoundation.org"],"Authentication-Results":["ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=openvswitch.org\n\t(client-ip=140.211.169.12; helo=mail.linuxfoundation.org;\n\tenvelope-from=ovs-dev-bounces@openvswitch.org;\n\treceiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"pSCfSX0+\"; dkim-atps=neutral"],"Received":["from mail.linuxfoundation.org (mail.linuxfoundation.org\n\t[140.211.169.12])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xylBV3TZqz9s7c\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 22 Sep 2017 04:14:40 +1000 (AEST)","from mail.linux-foundation.org (localhost [127.0.0.1])\n\tby mail.linuxfoundation.org (Postfix) with ESMTP id 39B479BA;\n\tThu, 21 Sep 2017 18:14:39 +0000 (UTC)","from smtp1.linuxfoundation.org (smtp1.linux-foundation.org\n\t[172.17.192.35])\n\tby mail.linuxfoundation.org (Postfix) with ESMTPS id 6442C266\n\tfor <dev@openvswitch.org>; Thu, 21 Sep 2017 18:14:38 +0000 (UTC)","from mail-pg0-f66.google.com (mail-pg0-f66.google.com\n\t[74.125.83.66])\n\tby smtp1.linuxfoundation.org (Postfix) with ESMTPS id 4862B4AA\n\tfor <dev@openvswitch.org>; Thu, 21 Sep 2017 18:14:37 +0000 (UTC)","by mail-pg0-f66.google.com with SMTP id i130so3842034pgc.0\n\tfor <dev@openvswitch.org>; Thu, 21 Sep 2017 11:14:37 -0700 (PDT)","from gizo.bigblue.kilchis.com (67-5-132-83.ptld.qwest.net.\n\t[67.5.132.83]) by smtp.gmail.com with ESMTPSA id\n\tx28sm4396005pfi.8.2017.09.21.11.14.34\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tThu, 21 Sep 2017 11:14:34 -0700 (PDT)"],"X-Greylist":"whitelisted by SQLgrey-1.7.6","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=subject:to:references:from:message-id:date:user-agent:mime-version\n\t:in-reply-to:content-language:content-transfer-encoding;\n\tbh=BFh6e7CXGSWfaUB28rQKSEF75gDPx0nxqvc+qCODQeQ=;\n\tb=pSCfSX0+bVUYNjb+cLpAXZCAIdqPMwIAkd7t5eEuivO4agGzgX1mb/HFx9lzPpI6Tb\n\t0ofX17soJH1yVghyGxvfATi6Kx78n7UMQiL8RT8ijJweDtFM2/AcmMq7ZknM0ZOyDv0R\n\t3WQ38NM0H4OW8zRuchF3JjBpR2SN0jjkazvqmgsDdgLSsAFCKlX4YCIaHv6VtlQW2odw\n\tmyB46FO7899SY4GP+JEbnk6NNwVb3hrvJ9hj6IGnp88qrrQ8kiuXcOV0XClAOX51TwQf\n\toKrEib66JQAyWVL8Lw0fT6giduNImxPxsIqc7TELxNYcxZYiP5EuAyIp8TEX8B+01iZJ\n\tm9jw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:subject:to:references:from:message-id:date\n\t:user-agent:mime-version:in-reply-to:content-language\n\t:content-transfer-encoding;\n\tbh=BFh6e7CXGSWfaUB28rQKSEF75gDPx0nxqvc+qCODQeQ=;\n\tb=ULiGD+Hnlh9DCokG5s5QQpK2VjcamjEDl57nyynZj9Tn6XLdOYBOSey3unwtWiAtx8\n\tnll6kuYVKFy8a0MxNPhdAjMnp7kU70g+FkrVjCnejMP2VeUu3tc+jshS57EzY2ijv2in\n\tTjtgDilk0OHTKA/A8/+dUPxTXvXfvGBc8nM5G+6pCBpuMcRfVa8SD1esTTyse4tKvvjK\n\tAyRuD1rKhyUQ5pD83Mjof41ehDBQhN/8zqRVrIhiwxhGu3mWQytAr7It/6MpG/PMPFCL\n\tSU3XVtCBeJz7SR/RvCU7Wy5omqElimysJDf+I2CxQiWrBi0Zxr0WoBeosKj2K80tPf5v\n\tNqOQ==","X-Gm-Message-State":"AHPjjUgq+QkK9zEJeXlClZaAfxZdIbdRCJENrpT3MxuJa9fDj+jcM/GL\n\tAaJg7TpMQncBH6PEgGJ8FdLSTgC4","X-Google-Smtp-Source":"AOwi7QAXHD6O0uKwFIL1apP3vdC1Z6gjglYOMeK2B4FLeVdm7OgkLJzL7u5lnnFIhg/vd7RGTzKtOg==","X-Received":"by 10.84.143.162 with SMTP id 31mr6337292plz.249.1506017676290; \n\tThu, 21 Sep 2017 11:14:36 -0700 (PDT)","To":"Andy Zhou <azhou@ovn.org>, dev@openvswitch.org","References":"<1505245749-3402-1-git-send-email-azhou@ovn.org>\n\t<1505245749-3402-7-git-send-email-azhou@ovn.org>","From":"Greg Rose <gvrose8192@gmail.com>","Message-ID":"<00acad09-79b0-0355-476d-c38400f88f8e@gmail.com>","Date":"Thu, 21 Sep 2017 11:14:28 -0700","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101\n\tThunderbird/52.1.0","MIME-Version":"1.0","In-Reply-To":"<1505245749-3402-7-git-send-email-azhou@ovn.org>","Content-Language":"en-US","X-Spam-Status":"No, score=0.7 required=5.0 tests=DKIM_SIGNED,DKIM_VALID,\n\tDKIM_VALID_AU, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,\n\tRCVD_IN_DNSWL_NONE, \n\tRCVD_IN_SORBS_SPAM autolearn=disabled version=3.3.1","X-Spam-Checker-Version":"SpamAssassin 3.3.1 (2010-03-16) on\n\tsmtp1.linux-foundation.org","Subject":"Re: [ovs-dev] [merge native tunneling and patch port 7/7]\n\tofproto-dpif-xlate: Refactor native tunnel handling logic","X-BeenThere":"ovs-dev@openvswitch.org","X-Mailman-Version":"2.1.12","Precedence":"list","List-Id":"<ovs-dev.openvswitch.org>","List-Unsubscribe":"<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n\t<mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>","List-Archive":"<http://mail.openvswitch.org/pipermail/ovs-dev/>","List-Post":"<mailto:ovs-dev@openvswitch.org>","List-Help":"<mailto:ovs-dev-request@openvswitch.org?subject=help>","List-Subscribe":"<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n\t<mailto:ovs-dev-request@openvswitch.org?subject=subscribe>","Content-Transfer-Encoding":"7bit","Content-Type":"text/plain; charset=\"us-ascii\"; Format=\"flowed\"","Sender":"ovs-dev-bounces@openvswitch.org","Errors-To":"ovs-dev-bounces@openvswitch.org"}}]