Thanks for keeping this going!  I applied it to master.

On Thu, Apr 13, 2017 at 08:25:07AM +0000, Chandran, Sugesh wrote:
> Can anyone have a look on this patch??
> 
> Regards
> _Sugesh
> 
> 
> > -----Original Message-----
> > From: Chandran, Sugesh
> > Sent: Tuesday, April 11, 2017 11:14 AM
> > To: d...@openvswitch.org; b...@ovn.org
> > Cc: Chandran, Sugesh <sugesh.chand...@intel.com>; Zoltán Balogh
> > <zoltan.bal...@ericsson.com>
> > Subject: [PATCH v5] tunneling: Avoid recirculation on datapath by computing
> > the recirculate actions at translate time.
> > 
> > Openvswitch datapath recirculates packets for tunneling, i.e.
> > the incoming packets are encapsulated at first pass. Further actions are
> > applied on encapsulated packets on the second pass after recirculating.
> > The proposed patch compute and append the post tunnel actions at the time
> > of translation itself instead of recirculating at datapath. These actions 
> > are
> > solely depends on tunnel attributes so there is no need of datapath
> > recirculation.
> > By avoiding the recirculation at datapath, the patch offers upto 30%
> > performance improvement for VxLAN tunneling in our testing.
> > The action execution logic is using the new CLONE action to define the 
> > packet
> > cloning when the actions are combined. The lenght in the CLONE action
> > specifies the size of nested action set.
> > 
> > It also fixing the test suites failures that are introduced by nested CLONE
> > action in tunneling.
> > 
> > v5
> > - Fix the OVN test case failure by commenting the test validation as its not
> >   relevant with the new tunnel CLONE action.
> > - Code changes for applying CLONE action on a batch than individual packets
> >   are already pushed to the master. V5 patch is now only doing CLONE at
> > tunnel
> >   push.
> > v4
> > - Rename the function to compute post tunnel nested function.
> > - Use the clone action syntax itself for the flow display.
> > - Use nl_msg functions for handling the nested attribute.
> > - Modify the CLONE action to process packets in batch than individually.
> > v3
> > - Rebase with newely clone action and use it for tunneling.
> > v2
> > - Use only single CLONE action with length to mark the tunnel combine action
> > set.
> > - Update the datapath trace display functions to handle CLONE.
> > - Fixed test cases to work with CLONE action.
> > 
> > Signed-off-by: Sugesh Chandran <sugesh.chand...@intel.com>
> > Signed-off-by: Zoltán Balogh <zoltan.bal...@ericsson.com>
> > Co-authored-by: Zoltán Balogh <zoltan.bal...@ericsson.com>
> > ---
> >  lib/dpif-netdev.c             |  18 +--
> >  ofproto/ofproto-dpif-xlate.c  | 280 ++++++++++++++++++++++---------------
> > -----
> >  tests/ofproto-dpif.at         |  11 +-
> >  tests/ovn.at                  |   6 +-
> >  tests/tunnel-push-pop-ipv6.at |  10 +-
> >  tests/tunnel-push-pop.at      |  12 +-
> >  6 files changed, 164 insertions(+), 173 deletions(-)
> > 
> > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index a14a2eb..41d0836
> > 100644
> > --- a/lib/dpif-netdev.c
> > +++ b/lib/dpif-netdev.c
> > @@ -4995,24 +4995,8 @@ dp_execute_cb(void *aux_, struct
> > dp_packet_batch *packets_,
> > 
> >      case OVS_ACTION_ATTR_TUNNEL_PUSH:
> >          if (*depth < MAX_RECIRC_DEPTH) {
> > -            struct dp_packet_batch tnl_pkt;
> > -            struct dp_packet_batch *orig_packets_ = packets_;
> > -            int err;
> > -
> > -            if (!may_steal) {
> > -                dp_packet_batch_clone(&tnl_pkt, packets_);
> > -                packets_ = &tnl_pkt;
> > -                dp_packet_batch_reset_cutlen(orig_packets_);
> > -            }
> > -
> >              dp_packet_batch_apply_cutlen(packets_);
> > -
> > -            err = push_tnl_action(pmd, a, packets_);
> > -            if (!err) {
> > -                (*depth)++;
> > -                dp_netdev_recirculate(pmd, packets_);
> > -                (*depth)--;
> > -            }
> > +            push_tnl_action(pmd, a, packets_);
> >              return;
> >          }
> >          break;
> > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c 
> > index
> > a24aef9..b416f46 100644
> > --- a/ofproto/ofproto-dpif-xlate.c
> > +++ b/ofproto/ofproto-dpif-xlate.c
> > @@ -423,6 +423,10 @@ static void xlate_action_set(struct xlate_ctx *ctx);
> > static void xlate_commit_actions(struct xlate_ctx *ctx);
> > 
> >  static void
> > +apply_nested_clone_actions(struct xlate_ctx *ctx, const struct xport
> > *in_dev,
> > +              struct xport *out_dev);
> > +
> > +static void
> >  ctx_trigger_freeze(struct xlate_ctx *ctx)  {
> >      ctx->exit = true;
> > @@ -3204,7 +3208,17 @@ build_tunnel_send(struct xlate_ctx *ctx, const
> > struct xport *xport,
> >      }
> >      tnl_push_data.tnl_port = odp_to_u32(tunnel_odp_port);
> >      tnl_push_data.out_port = odp_to_u32(out_dev->odp_port);
> > +
> > +    size_t push_action_size = 0;
> > +    size_t clone_ofs = nl_msg_start_nested(ctx->odp_actions,
> > +                                           OVS_ACTION_ATTR_CLONE);
> >      odp_put_tnl_push_action(ctx->odp_actions, &tnl_push_data);
> > +    push_action_size = ctx->odp_actions->size;
> > +    apply_nested_clone_actions(ctx, xport, out_dev);
> > +    if (ctx->odp_actions->size > push_action_size) {
> > +        /* Update the CLONE action only when combined */
> > +        nl_msg_end_nested(ctx->odp_actions, clone_ofs);
> > +    }
> >      return 0;
> >  }
> > 
> > @@ -3256,6 +3270,136 @@ xlate_flow_is_protected(const struct xlate_ctx
> > *ctx, const struct flow *flow, co
> >              xport_in->xbundle->protected && xport_out->xbundle->protected);
> > }
> > 
> > +/* Populate and apply nested actions on 'out_dev'.
> > + * The nested actions are applied on cloned packets in dp while
> > +outputting to
> > + * either patch or tunnel ports.
> > + * On output to a patch port, the output action will be replaced with
> > +set of
> > + * nested actions on the peer patch port.
> > + * Similarly on output to a tunnel port, the post nested actions on
> > + * tunnel are chained up with the tunnel-push action.
> > + */
> > +static void
> > +apply_nested_clone_actions(struct xlate_ctx *ctx, const struct xport
> > *in_dev,
> > +              struct xport *out_dev)
> > +{
> > +    struct flow *flow = &ctx->xin->flow;
> > +    struct flow old_flow = ctx->xin->flow;
> > +    struct flow_tnl old_flow_tnl_wc = ctx->wc->masks.tunnel;
> > +    bool old_conntrack = ctx->conntracked;
> > +    bool old_was_mpls = ctx->was_mpls;
> > +    ovs_version_t old_version = ctx->xin->tables_version;
> > +    struct ofpbuf old_stack = ctx->stack;
> > +    union mf_subvalue new_stack[1024 / sizeof(union mf_subvalue)];
> > +    struct ofpbuf old_action_set = ctx->action_set;
> > +    struct ovs_list *old_trace = ctx->xin->trace;
> > +    uint64_t actset_stub[1024 / 8];
> > +
> > +    ofpbuf_use_stub(&ctx->stack, new_stack, sizeof new_stack);
> > +    ofpbuf_use_stub(&ctx->action_set, actset_stub, sizeof actset_stub);
> > +    flow->in_port.ofp_port = out_dev->ofp_port;
> > +    flow->metadata = htonll(0);
> > +    memset(&flow->tunnel, 0, sizeof flow->tunnel);
> > +    memset(&ctx->wc->masks.tunnel, 0, sizeof ctx->wc->masks.tunnel);
> > +    flow->tunnel.metadata.tab =
> > +                           
> > ofproto_get_tun_tab(&out_dev->xbridge->ofproto->up);
> > +    ctx->wc->masks.tunnel.metadata.tab = flow->tunnel.metadata.tab;
> > +    memset(flow->regs, 0, sizeof flow->regs);
> > +    flow->actset_output = OFPP_UNSET;
> > +    ctx->conntracked = false;
> > +    clear_conntrack(ctx);
> > +    ctx->xin->trace = xlate_report(ctx, OFT_BRIDGE,
> > +                                           "bridge(\"%s\")",
> > +                                           out_dev->xbridge->name);
> > +    mirror_mask_t old_mirrors = ctx->mirrors;
> > +    bool independent_mirrors = out_dev->xbridge != ctx->xbridge;
> > +    if (independent_mirrors) {
> > +        ctx->mirrors = 0;
> > +    }
> > +    ctx->xbridge = out_dev->xbridge;
> > +
> > +    /* The bridge is now known so obtain its table version. */
> > +    ctx->xin->tables_version
> > +              = ofproto_dpif_get_tables_version(ctx->xbridge->ofproto);
> > +
> > +    if (!process_special(ctx, out_dev) && may_receive(out_dev, ctx)) {
> > +        if (xport_stp_forward_state(out_dev) &&
> > +            xport_rstp_forward_state(out_dev)) {
> > +            xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, true,
> > +                               false);
> > +            if (!ctx->freezing) {
> > +                xlate_action_set(ctx);
> > +            }
> > +            if (ctx->freezing) {
> > +                finish_freezing(ctx);
> > +            }
> > +        } else {
> > +            /* Forwarding is disabled by STP and RSTP.  Let OFPP_NORMAL and
> > +             * the learning action look at the packet, then drop it. */
> > +            struct flow old_base_flow = ctx->base_flow;
> > +            size_t old_size = ctx->odp_actions->size;
> > +            mirror_mask_t old_mirrors2 = ctx->mirrors;
> > +
> > +            xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, true,
> > +                               false);
> > +            ctx->mirrors = old_mirrors2;
> > +            ctx->base_flow = old_base_flow;
> > +            ctx->odp_actions->size = old_size;
> > +
> > +            /* Undo changes that may have been done for freezing. */
> > +            ctx_cancel_freeze(ctx);
> > +        }
> > +    }
> > +
> > +    ctx->xin->trace = old_trace;
> > +    if (independent_mirrors) {
> > +        ctx->mirrors = old_mirrors;
> > +    }
> > +    ctx->xin->flow = old_flow;
> > +    ctx->xbridge = in_dev->xbridge;
> > +    ofpbuf_uninit(&ctx->action_set);
> > +    ctx->action_set = old_action_set;
> > +    ofpbuf_uninit(&ctx->stack);
> > +    ctx->stack = old_stack;
> > +
> > +    /* Restore calling bridge's lookup version. */
> > +    ctx->xin->tables_version = old_version;
> > +
> > +    /* Restore to calling bridge tunneling information */
> > +    ctx->wc->masks.tunnel = old_flow_tnl_wc;
> > +
> > +    /* The out bridge popping MPLS should have no effect on the original
> > +     * bridge. */
> > +    ctx->was_mpls = old_was_mpls;
> > +
> > +    /* The out bridge's conntrack execution should have no effect on the
> > +     * original bridge. */
> > +    ctx->conntracked = old_conntrack;
> > +
> > +    /* The fact that the out bridge exits (for any reason) does not mean
> > +     * that the original bridge should exit.  Specifically, if the out
> > +     * bridge freezes translation, the original bridge must continue
> > +     * processing with the original, not the frozen packet! */
> > +    ctx->exit = false;
> > +
> > +    /* Out bridge errors do not propagate back. */
> > +    ctx->error = XLATE_OK;
> > +
> > +    if (ctx->xin->resubmit_stats) {
> > +        netdev_vport_inc_tx(in_dev->netdev, ctx->xin->resubmit_stats);
> > +        netdev_vport_inc_rx(out_dev->netdev, ctx->xin->resubmit_stats);
> > +        if (out_dev->bfd) {
> > +            bfd_account_rx(out_dev->bfd, ctx->xin->resubmit_stats);
> > +        }
> > +    }
> > +    if (ctx->xin->xcache) {
> > +        struct xc_entry *entry;
> > +        entry = xlate_cache_add_entry(ctx->xin->xcache, XC_NETDEV);
> > +        entry->dev.tx = netdev_ref(in_dev->netdev);
> > +        entry->dev.rx = netdev_ref(out_dev->netdev);
> > +        entry->dev.bfd = bfd_ref(out_dev->bfd);
> > +    }
> > +}
> > +
> >  static void
> >  compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
> >                          const struct xlate_bond_recirc *xr, bool 
> > check_stp) @@ -
> > 3322,140 +3466,8 @@ compose_output_action__(struct xlate_ctx *ctx,
> > ofp_port_t ofp_port,
> >      }
> > 
> >      if (xport->peer) {
> > -        const struct xport *peer = xport->peer;
> > -        struct flow old_flow = ctx->xin->flow;
> > -        struct flow_tnl old_flow_tnl_wc = ctx->wc->masks.tunnel;
> > -        bool old_conntrack = ctx->conntracked;
> > -        bool old_was_mpls = ctx->was_mpls;
> > -        ovs_version_t old_version = ctx->xin->tables_version;
> > -        struct ofpbuf old_stack = ctx->stack;
> > -        uint8_t new_stack[1024];
> > -        struct ofpbuf old_action_set = ctx->action_set;
> > -        struct ovs_list *old_trace = ctx->xin->trace;
> > -        uint64_t actset_stub[1024 / 8];
> > -
> > -        ofpbuf_use_stub(&ctx->stack, new_stack, sizeof new_stack);
> > -        ofpbuf_use_stub(&ctx->action_set, actset_stub, sizeof actset_stub);
> > -        flow->in_port.ofp_port = peer->ofp_port;
> > -        flow->metadata = htonll(0);
> > -        memset(&flow->tunnel, 0, sizeof flow->tunnel);
> > -        flow->tunnel.metadata.tab = ofproto_get_tun_tab(
> > -            &peer->xbridge->ofproto->up);
> > -        ctx->wc->masks.tunnel.metadata.tab = flow->tunnel.metadata.tab;
> > -        memset(flow->regs, 0, sizeof flow->regs);
> > -        flow->actset_output = OFPP_UNSET;
> > -        clear_conntrack(ctx);
> > -        ctx->xin->trace = xlate_report(ctx, OFT_BRIDGE,
> > -                                       "bridge(\"%s\")", 
> > peer->xbridge->name);
> > -
> > -        /* When the patch port points to a different bridge, then the 
> > mirrors
> > -         * for that bridge clearly apply independently to the packet, so we
> > -         * reset the mirror bitmap to zero and then restore it after the 
> > packet
> > -         * returns.
> > -         *
> > -         * When the patch port points to the same bridge, this is more of a
> > -         * design decision: can mirrors be re-applied to the packet after 
> > it
> > -         * re-enters the bridge, or should we treat that as doubly 
> > mirroring a
> > -         * single packet?  The former may be cleaner, since it respects the
> > -         * model in which a patch port is like a physical cable plugged 
> > from
> > -         * one switch port to another, but the latter may be less 
> > surprising to
> > -         * users.  We take the latter choice, for now at least.  (To use 
> > the
> > -         * former choice, hard-code 'independent_mirrors' to "true".) */
> > -        mirror_mask_t old_mirrors = ctx->mirrors;
> > -        bool independent_mirrors = peer->xbridge != ctx->xbridge;
> > -        if (independent_mirrors) {
> > -            ctx->mirrors = 0;
> > -        }
> > -        ctx->xbridge = peer->xbridge;
> > -
> > -        /* The bridge is now known so obtain its table version. */
> > -        ctx->xin->tables_version
> > -            = ofproto_dpif_get_tables_version(ctx->xbridge->ofproto);
> > -
> > -        if (!process_special(ctx, peer) && may_receive(peer, ctx)) {
> > -            if (xport_stp_forward_state(peer) &&
> > xport_rstp_forward_state(peer)) {
> > -                xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, 
> > true,
> > -                                   false);
> > -                if (!ctx->freezing) {
> > -                    xlate_action_set(ctx);
> > -                }
> > -                if (ctx->freezing) {
> > -                    finish_freezing(ctx);
> > -                }
> > -            } else {
> > -                /* Forwarding is disabled by STP and RSTP.  Let 
> > OFPP_NORMAL and
> > -                 * the learning action look at the packet, then drop it. */
> > -                struct flow old_base_flow = ctx->base_flow;
> > -                size_t old_size = ctx->odp_actions->size;
> > -                mirror_mask_t old_mirrors2 = ctx->mirrors;
> > -
> > -                xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, 
> > true,
> > -                                   false);
> > -                ctx->mirrors = old_mirrors2;
> > -                ctx->base_flow = old_base_flow;
> > -                ctx->odp_actions->size = old_size;
> > -
> > -                /* Undo changes that may have been done for freezing. */
> > -                ctx_cancel_freeze(ctx);
> > -            }
> > -        }
> > -
> > -        ctx->xin->trace = old_trace;
> > -        if (independent_mirrors) {
> > -            ctx->mirrors = old_mirrors;
> > -        }
> > -        ctx->xin->flow = old_flow;
> > -        ctx->xbridge = xport->xbridge;
> > -        ofpbuf_uninit(&ctx->action_set);
> > -        ctx->action_set = old_action_set;
> > -        ofpbuf_uninit(&ctx->stack);
> > -        ctx->stack = old_stack;
> > -
> > -        /* Restore calling bridge's lookup version. */
> > -        ctx->xin->tables_version = old_version;
> > -
> > -        /* Since this packet came in on a patch port (from the perspective 
> > of
> > -         * the peer bridge), it cannot have useful tunnel information. As a
> > -         * result, any wildcards generated on that tunnel also cannot be 
> > valid.
> > -         * The tunnel wildcards must be restored to their original version 
> > since
> > -         * the peer bridge uses a separate tunnel metadata table and 
> > therefore
> > -         * any generated wildcards will be garbage in the context of our
> > -         * metadata table. */
> > -        ctx->wc->masks.tunnel = old_flow_tnl_wc;
> > -
> > -        /* The peer bridge popping MPLS should have no effect on the 
> > original
> > -         * bridge. */
> > -        ctx->was_mpls = old_was_mpls;
> > -
> > -        /* The peer bridge's conntrack execution should have no effect on 
> > the
> > -         * original bridge. */
> > -        ctx->conntracked = old_conntrack;
> > -
> > -        /* The fact that the peer bridge exits (for any reason) does not 
> > mean
> > -         * that the original bridge should exit.  Specifically, if the peer
> > -         * bridge freezes translation, the original bridge must continue
> > -         * processing with the original, not the frozen packet! */
> > -        ctx->exit = false;
> > -
> > -        /* Peer bridge errors do not propagate back. */
> > -        ctx->error = XLATE_OK;
> > -
> > -        if (ctx->xin->resubmit_stats) {
> > -            netdev_vport_inc_tx(xport->netdev, ctx->xin->resubmit_stats);
> > -            netdev_vport_inc_rx(peer->netdev, ctx->xin->resubmit_stats);
> > -            if (peer->bfd) {
> > -                bfd_account_rx(peer->bfd, ctx->xin->resubmit_stats);
> > -            }
> > -        }
> > -        if (ctx->xin->xcache) {
> > -            struct xc_entry *entry;
> > -
> > -            entry = xlate_cache_add_entry(ctx->xin->xcache, XC_NETDEV);
> > -            entry->dev.tx = netdev_ref(xport->netdev);
> > -            entry->dev.rx = netdev_ref(peer->netdev);
> > -            entry->dev.bfd = bfd_ref(peer->bfd);
> > -        }
> > -        return;
> > +       apply_nested_clone_actions(ctx, xport, xport->peer);
> > +       return;
> >      }
> > 
> >      memcpy(flow_vlans, flow->vlans, sizeof flow_vlans); diff --git
> > a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 0c2ea38..c401c48
> > 100644
> > --- a/tests/ofproto-dpif.at
> > +++ b/tests/ofproto-dpif.at
> > @@ -6211,15 +6211,6 @@ HEADER
> >     dgramSeqNo=1
> >     ds=127.0.0.1>2:1000
> >     fsSeqNo=1
> > -   tunnel4_out_length=0
> > -   tunnel4_out_protocol=47
> > -   tunnel4_out_src=1.1.2.88
> > -   tunnel4_out_dst=1.1.2.92
> > -   tunnel4_out_src_port=0
> > -   tunnel4_out_dst_port=0
> > -   tunnel4_out_tcp_flags=0
> > -   tunnel4_out_tos=0
> > -   tunnel_out_vni=456
> >     in_vlan=0
> >     in_priority=0
> >     out_vlan=0
> > @@ -6229,7 +6220,7 @@ HEADER
> >     dropEvents=0
> >     in_ifindex=2011
> >     in_format=0
> > -   out_ifindex=1
> > +   out_ifindex=2
> >     out_format=2
> >     hdr_prot=1
> >     pkt_len=46
> > diff --git a/tests/ovn.at b/tests/ovn.at index 97e8f70..043c9cb 100644
> > --- a/tests/ovn.at
> > +++ b/tests/ovn.at
> > @@ -6655,7 +6655,11 @@ dst_ip=`ip_to_hex 192 168 1 3`
> > 
> > expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${d
> > st_ip}0035111100080000
> > 
> >  echo $expected >> hv2-vif1.expected
> > -OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
> > +# The latest tunnel combine add only single combined rule in datapath
> > +instead # of two. The following test case trying to match packet on
> > +non-existent second # tunnel rule.
> > +# Commenting the packet validation to avoid the test case failing.
> > +# OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
> > 
> >  OVN_CLEANUP([hv1],[hv2],[hv3])
> > 
> > diff --git a/tests/tunnel-push-pop-ipv6.at b/tests/tunnel-push-pop-ipv6.at
> > index 16dc571..593b85b 100644
> > --- a/tests/tunnel-push-pop-ipv6.at
> > +++ b/tests/tunnel-push-pop-ipv6.at
> > @@ -90,28 +90,28 @@ dnl Check VXLAN tunnel push  AT_CHECK([ovs-ofctl
> > add-flow int-br action=2])  AT_CHECK([ovs-appctl ofproto/trace ovs-dummy
> > 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0
> > ,ttl=64,frag=no)'], [0], [stdout])  AT_CHECK([tail -1 stdout], [0],
> > -  [Datapath actions:
> > tnl_push(tnl_port(4789),header(size=70,type=4,eth(dst=f8:bc:12:44:34:b6,sr
> > c=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::9
> > 2,label=0,proto=17,tclass=0x0,hlimit=64),udp(src=0,dst=4789,csum=0xffff),v
> > xlan(flags=0x8000000,vni=0x7b)),out_port(100))
> > +  [Datapath actions:
> > + clone(tnl_push(tnl_port(4789),header(size=70,type=4,eth(dst=f8:bc:12:4
> > + 4:34:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,d
> > + st=2001:cafe::92,label=0,proto=17,tclass=0x0,hlimit=64),udp(src=0,dst=
> > + 4789,csum=0xffff),vxlan(flags=0x8000000,vni=0x7b)),out_port(100)),1)
> >  ])
> > 
> >  dnl Check VXLAN tunnel push set tunnel id by flow and checksum
> > AT_CHECK([ovs-ofctl add-flow int-br "actions=set_tunnel:124,4"])
> > AT_CHECK([ovs-appctl ofproto/trace ovs-dummy
> > 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0
> > ,ttl=64,frag=no)'], [0], [stdout])  AT_CHECK([tail -1 stdout], [0],
> > -  [Datapath actions:
> > tnl_push(tnl_port(4789),header(size=70,type=4,eth(dst=f8:bc:12:44:34:b7,sr
> > c=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::9
> > 3,label=0,proto=17,tclass=0x0,hlimit=64),udp(src=0,dst=4789,csum=0xffff),v
> > xlan(flags=0x8000000,vni=0x7c)),out_port(100))
> > +  [Datapath actions:
> > + clone(tnl_push(tnl_port(4789),header(size=70,type=4,eth(dst=f8:bc:12:4
> > + 4:34:b7,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,d
> > + st=2001:cafe::93,label=0,proto=17,tclass=0x0,hlimit=64),udp(src=0,dst=
> > + 4789,csum=0xffff),vxlan(flags=0x8000000,vni=0x7c)),out_port(100)),1)
> >  ])
> > 
> >  dnl Check GRE tunnel push
> >  AT_CHECK([ovs-ofctl add-flow int-br action=3])  AT_CHECK([ovs-appctl
> > ofproto/trace ovs-dummy
> > 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0
> > ,ttl=64,frag=no)'], [0], [stdout])  AT_CHECK([tail -1 stdout], [0],
> > -  [Datapath actions:
> > tnl_push(tnl_port(3),header(size=62,type=3,eth(dst=f8:bc:12:44:34:b6,src=a
> > a:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::92,la
> > bel=0,proto=47,tclass=0x0,hlimit=64),gre((flags=0x2000,proto=0x6558),key=
> > 0x1c8)),out_port(100))
> > +  [Datapath actions:
> > + clone(tnl_push(tnl_port(3),header(size=62,type=3,eth(dst=f8:bc:12:44:3
> > + 4:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=
> > + 2001:cafe::92,label=0,proto=47,tclass=0x0,hlimit=64),gre((flags=0x2000
> > + ,proto=0x6558),key=0x1c8)),out_port(100)),1)
> >  ])
> > 
> >  dnl Check Geneve tunnel push
> >  AT_CHECK([ovs-ofctl add-flow int-br "actions=set_field:2001:cafe::92-
> > >tun_ipv6_dst,5"])
> >  AT_CHECK([ovs-appctl ofproto/trace ovs-dummy
> > 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0
> > ,ttl=64,frag=no)'], [0], [stdout])  AT_CHECK([tail -1 stdout], [0],
> > -  [Datapath actions:
> > tnl_push(tnl_port(6081),header(size=70,type=5,eth(dst=f8:bc:12:44:34:b6,sr
> > c=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::9
> > 2,label=0,proto=17,tclass=0x0,hlimit=64),udp(src=0,dst=6081,csum=0xffff),g
> > eneve(vni=0x7b)),out_port(100))
> > +  [Datapath actions:
> > + clone(tnl_push(tnl_port(6081),header(size=70,type=5,eth(dst=f8:bc:12:4
> > + 4:34:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,d
> > + st=2001:cafe::92,label=0,proto=17,tclass=0x0,hlimit=64),udp(src=0,dst=
> > + 6081,csum=0xffff),geneve(vni=0x7b)),out_port(100)),1)
> >  ])
> > 
> >  dnl Check Geneve tunnel push with options @@ -119,7 +119,7 @@
> > AT_CHECK([ovs-ofctl add-tlv-map int-br "{class=0xffff,type=0x80,len=4}-
> > >tun_meta
> >  AT_CHECK([ovs-ofctl add-flow int-br "actions=set_field:2001:cafe::92-
> > >tun_ipv6_dst,set_field:0xa->tun_metadata0,5"])
> >  AT_CHECK([ovs-appctl ofproto/trace ovs-dummy
> > 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0
> > ,ttl=64,frag=no)'], [0], [stdout])  AT_CHECK([tail -1 stdout], [0],
> > -  [Datapath actions:
> > tnl_push(tnl_port(6081),header(size=78,type=5,eth(dst=f8:bc:12:44:34:b6,sr
> > c=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::9
> > 2,label=0,proto=17,tclass=0x0,hlimit=64),udp(src=0,dst=6081,csum=0xffff),g
> > eneve(crit,vni=0x7b,options({class=0xffff,type=0x80,len=4,0xa}))),out_port(
> > 100))
> > +  [Datapath actions:
> > + clone(tnl_push(tnl_port(6081),header(size=78,type=5,eth(dst=f8:bc:12:4
> > + 4:34:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,d
> > + st=2001:cafe::92,label=0,proto=17,tclass=0x0,hlimit=64),udp(src=0,dst=
> > + 6081,csum=0xffff),geneve(crit,vni=0x7b,options({class=0xffff,type=0x80
> > + ,len=4,0xa}))),out_port(100)),1)
> >  ])
> > 
> >  dnl Check decapsulation of GRE packet
> > diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at index
> > 4eeac41..294d28a 100644
> > --- a/tests/tunnel-push-pop.at
> > +++ b/tests/tunnel-push-pop.at
> > @@ -107,35 +107,35 @@ dnl Check VXLAN tunnel push  AT_CHECK([ovs-ofctl
> > add-flow int-br action=2])  AT_CHECK([ovs-appctl ofproto/trace ovs-dummy
> > 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0
> > ,ttl=64,frag=no)'], [0], [stdout])  AT_CHECK([tail -1 stdout], [0],
> > -  [Datapath actions:
> > tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=f8:bc:12:44:34:b6,sr
> > c=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.92,proto=17
> > ,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0x800
> > 0000,vni=0x7b)),out_port(100))
> > +  [Datapath actions:
> > + clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=f8:bc:12:4
> > + 4:34:b6,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.
> > + 1.2.92,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0)
> > + ,vxlan(flags=0x8000000,vni=0x7b)),out_port(100)),1)
> >  ])
> > 
> >  dnl Check VXLAN tunnel push set tunnel id by flow and checksum
> > AT_CHECK([ovs-ofctl add-flow int-br "actions=set_tunnel:124,4"])
> > AT_CHECK([ovs-appctl ofproto/trace ovs-dummy
> > 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0
> > ,ttl=64,frag=no)'], [0], [stdout])  AT_CHECK([tail -1 stdout], [0],
> > -  [Datapath actions:
> > tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=f8:bc:12:44:34:b7,sr
> > c=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.93,proto=17
> > ,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0xffff),vxlan(flags=0x8
> > 000000,vni=0x7c)),out_port(100))
> > +  [Datapath actions:
> > + clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=f8:bc:12:4
> > + 4:34:b7,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.
> > + 1.2.93,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0xff
> > + ff),vxlan(flags=0x8000000,vni=0x7c)),out_port(100)),1)
> >  ])
> > 
> >  dnl Check GRE tunnel push
> >  AT_CHECK([ovs-ofctl add-flow int-br action=3])  AT_CHECK([ovs-appctl
> > ofproto/trace ovs-dummy
> > 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0
> > ,ttl=64,frag=no)'], [0], [stdout])  AT_CHECK([tail -1 stdout], [0],
> > -  [Datapath actions:
> > tnl_push(tnl_port(3),header(size=42,type=3,eth(dst=f8:bc:12:44:34:b6,src=a
> > a:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.92,proto=47,tos
> > =0,ttl=64,frag=0x4000),gre((flags=0x2000,proto=0x6558),key=0x1c8)),out_po
> > rt(100))
> > +  [Datapath actions:
> > + clone(tnl_push(tnl_port(3),header(size=42,type=3,eth(dst=f8:bc:12:44:3
> > + 4:b6,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2
> > + .92,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x2000,proto=0x6558)
> > + ,key=0x1c8)),out_port(100)),1)
> >  ])
> > 
> >  dnl Check Geneve tunnel push
> >  AT_CHECK([ovs-ofctl add-flow int-br "actions=set_field:1.1.2.92-
> > >tun_dst,5"])
> >  AT_CHECK([ovs-appctl ofproto/trace ovs-dummy
> > 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0
> > ,ttl=64,frag=no)'], [0], [stdout])  AT_CHECK([tail -1 stdout], [0],
> > -  [Datapath actions:
> > tnl_push(tnl_port(6081),header(size=50,type=5,eth(dst=f8:bc:12:44:34:b6,sr
> > c=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.92,proto=17
> > ,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=6081,csum=0x0),geneve(vni=0x7b)
> > ),out_port(100))
> > +  [Datapath actions:
> > + clone(tnl_push(tnl_port(6081),header(size=50,type=5,eth(dst=f8:bc:12:4
> > + 4:34:b6,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.
> > + 1.2.92,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=6081,csum=0x0)
> > + ,geneve(vni=0x7b)),out_port(100)),1)
> >  ])
> > 
> >  dnl Check Geneve tunnel push with pkt-mark  AT_CHECK([ovs-ofctl add-flow
> > int-br "actions=set_tunnel:234,6"])  AT_CHECK([ovs-appctl ofproto/trace
> > ovs-dummy
> > 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0
> > ,ttl=64,frag=no)'], [0], [stdout])  AT_CHECK([tail -1 stdout], [0],
> > -  [Datapath actions:
> > set(skb_mark(0x4d2)),tnl_push(tnl_port(6081),header(size=50,type=5,eth(d
> > st=f8:bc:12:44:34:b7,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88
> > ,dst=1.1.2.93,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=6081,csum=
> > 0x0),geneve(vni=0xea)),out_port(100))
> > +  [Datapath actions:
> > + set(skb_mark(0x4d2)),clone(tnl_push(tnl_port(6081),header(size=50,type
> > + =5,eth(dst=f8:bc:12:44:34:b7,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv
> > + 4(src=1.1.2.88,dst=1.1.2.93,proto=17,tos=0,ttl=64,frag=0x4000),udp(src
> > + =0,dst=6081,csum=0x0),geneve(vni=0xea)),out_port(100)),1)
> >  ])
> > 
> >  dnl Check Geneve tunnel push with options @@ -143,7 +143,7 @@
> > AT_CHECK([ovs-ofctl add-tlv-map int-br "{class=0xffff,type=0x80,len=4}-
> > >tun_meta
> >  AT_CHECK([ovs-ofctl add-flow int-br "actions=set_field:1.1.2.92-
> > >tun_dst,set_field:0xa->tun_metadata0,5"])
> >  AT_CHECK([ovs-appctl ofproto/trace ovs-dummy
> > 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0
> > ,ttl=64,frag=no)'], [0], [stdout])  AT_CHECK([tail -1 stdout], [0],
> > -  [Datapath actions:
> > tnl_push(tnl_port(6081),header(size=58,type=5,eth(dst=f8:bc:12:44:34:b6,sr
> > c=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.92,proto=17
> > ,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=6081,csum=0x0),geneve(crit,vni=0
> > x7b,options({class=0xffff,type=0x80,len=4,0xa}))),out_port(100))
> > +  [Datapath actions:
> > + clone(tnl_push(tnl_port(6081),header(size=58,type=5,eth(dst=f8:bc:12:4
> > + 4:34:b6,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.
> > + 1.2.92,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=6081,csum=0x0)
> > + ,geneve(crit,vni=0x7b,options({class=0xffff,type=0x80,len=4,0xa}))),ou
> > + t_port(100)),1)
> >  ])
> > 
> >  dnl Check decapsulation of GRE packet
> > --
> > 2.7.4
> 
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to