]> git.proxmox.com Git - mirror_ovs.git/commitdiff
Revert "tunneling: Avoid recirculation on datapath."
authorJoe Stringer <joe@ovn.org>
Mon, 8 May 2017 18:15:39 +0000 (11:15 -0700)
committerJoe Stringer <joe@ovn.org>
Wed, 10 May 2017 19:14:02 +0000 (12:14 -0700)
This reverts commit f1dac5128ce6db2e493f0d1c7a8b53fb9f34476f. When this
commit was introduced, it broke the 'make check-system-userspace'
testsuite. It appears that the new translation fails to modify the flow
in a way that would represent the flow as an encapsulated flow when the
traffic is patched through to the second bridge. As such, rather than
matching on, for example, "ip,proto=47" for gre, it would use the inner
packet's flow headers. It also results in problems reporting statistics,
as the tunnel's header is not reflected in subsequent statistics and
truncation is not properly applied during translation.

While a refreshed approach to solving the above problem is formed,
revert this patch.

Reported-at: https://mail.openvswitch.org/pipermail/ovs-dev/2017-May/331972.html
Signed-off-by: Joe Stringer <joe@ovn.org>
Acked-by: Greg Rose <gvrose8192@gmail.com>
lib/dpif-netdev.c
ofproto/ofproto-dpif-xlate.c
tests/ofproto-dpif.at
tests/ovn.at
tests/tunnel-push-pop-ipv6.at
tests/tunnel-push-pop.at

index 4ee5d058aff8b976baa45cf8aef4237282bde3e1..d21515657634297b34c1f67e2332954888df6b5a 100644 (file)
@@ -4970,8 +4970,24 @@ 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_);
-            push_tnl_action(pmd, a, packets_);
+
+            err = push_tnl_action(pmd, a, packets_);
+            if (!err) {
+                (*depth)++;
+                dp_netdev_recirculate(pmd, packets_);
+                (*depth)--;
+            }
             return;
         }
         break;
index b308f21de100c382247cbf0b00e8d7a15ef79448..bc3a310227da58f074a92d762bb2cc2088cceef5 100644 (file)
@@ -424,10 +424,6 @@ const char *xlate_strerror(enum xlate_error error)
 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)
 {
@@ -3215,17 +3211,7 @@ 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;
 }
 
@@ -3261,136 +3247,6 @@ 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)
@@ -3457,8 +3313,140 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
     }
 
     if (xport->peer) {
-       apply_nested_clone_actions(ctx, xport, xport->peer);
-       return;
+        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;
     }
 
     memcpy(flow_vlans, flow->vlans, sizeof flow_vlans);
index e52ab32b9e5fd6498792a420616e1b71a7e9e715..1f6cd8422e041ab945c2d0c03100c830b8fd1ad3 100644 (file)
@@ -6257,6 +6257,15 @@ 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
@@ -6266,7 +6275,7 @@ HEADER
        dropEvents=0
        in_ifindex=2011
        in_format=0
-       out_ifindex=2
+       out_ifindex=1
        out_format=2
        hdr_prot=1
        pkt_len=46
index e67d33b778030e42f1f3c3b27a346a0667e3389e..b30315e57034b82d61b9855f54942f5aad8a2995 100644 (file)
@@ -7140,11 +7140,7 @@ dst_ip=`ip_to_hex 192 168 1 3`
 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
 
 echo $expected >> 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_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
 
 OVN_CLEANUP([hv1],[hv2],[hv3])
 
index 593b85bf7b77330788438e8b9e8753035ca2caef..16dc571e2dd302902d8157c69287ef6ebca0b197 100644 (file)
@@ -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: clone(tnl_push(tnl_port(4789),header(size=70,type=4,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=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)
+  [Datapath actions: tnl_push(tnl_port(4789),header(size=70,type=4,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=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))
 ])
 
 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: clone(tnl_push(tnl_port(4789),header(size=70,type=4,eth(dst=f8:bc:12:44:34:b7,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=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)
+  [Datapath actions: tnl_push(tnl_port(4789),header(size=70,type=4,eth(dst=f8:bc:12:44:34:b7,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=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))
 ])
 
 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: clone(tnl_push(tnl_port(3),header(size=62,type=3,eth(dst=f8:bc:12:44:34: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)
+  [Datapath actions: tnl_push(tnl_port(3),header(size=62,type=3,eth(dst=f8:bc:12:44:34: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))
 ])
 
 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: clone(tnl_push(tnl_port(6081),header(size=70,type=5,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=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)
+  [Datapath actions: tnl_push(tnl_port(6081),header(size=70,type=5,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::92,label=0,proto=17,tclass=0x0,hlimit=64),udp(src=0,dst=6081,csum=0xffff),geneve(vni=0x7b)),out_port(100))
 ])
 
 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: clone(tnl_push(tnl_port(6081),header(size=78,type=5,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=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)
+  [Datapath actions: tnl_push(tnl_port(6081),header(size=78,type=5,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=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))
 ])
 
 dnl Check decapsulation of GRE packet
index 294d28a2416d54c31216883b978e310576f0ddac..4eeac4154dbc0fe2fd45b7cf521699c3eef3c86d 100644 (file)
@@ -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: clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=f8:bc:12:44: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)
+  [Datapath actions: tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=f8:bc:12:44: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))
 ])
 
 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: clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=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=4789,csum=0xffff),vxlan(flags=0x8000000,vni=0x7c)),out_port(100)),1)
+  [Datapath actions: tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=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=4789,csum=0xffff),vxlan(flags=0x8000000,vni=0x7c)),out_port(100))
 ])
 
 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: clone(tnl_push(tnl_port(3),header(size=42,type=3,eth(dst=f8:bc:12:44:34: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)
+  [Datapath actions: tnl_push(tnl_port(3),header(size=42,type=3,eth(dst=f8:bc:12:44:34: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))
 ])
 
 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: clone(tnl_push(tnl_port(6081),header(size=50,type=5,eth(dst=f8:bc:12:44: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)
+  [Datapath actions: tnl_push(tnl_port(6081),header(size=50,type=5,eth(dst=f8:bc:12:44: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))
 ])
 
 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)),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),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)),1)
+  [Datapath actions: set(skb_mark(0x4d2)),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),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))
 ])
 
 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: clone(tnl_push(tnl_port(6081),header(size=58,type=5,eth(dst=f8:bc:12:44: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}))),out_port(100)),1)
+  [Datapath actions: tnl_push(tnl_port(6081),header(size=58,type=5,eth(dst=f8:bc:12:44: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}))),out_port(100))
 ])
 
 dnl Check decapsulation of GRE packet