From: Eli Britstein <[email protected]>

Introduce eth-type field to tunnel metadata that is internally matched
for tunnels, for robust detection of the IP type.

Signed-off-by: Eli Britstein <[email protected]>
---
 include/openvswitch/match.h     |  1 +
 include/openvswitch/meta-flow.h | 14 +++++++++++
 include/openvswitch/packets.h   |  3 ++-
 lib/dpif.c                      |  6 +++++
 lib/dpif.h                      |  1 +
 lib/match.c                     | 10 ++++++++
 lib/meta-flow.c                 | 18 +++++++++++++++
 lib/meta-flow.xml               |  1 +
 lib/netdev-native-tnl.c         | 20 ++++++++++++++++
 lib/netdev-offload-dpdk.c       | 41 +++++++++++++++++++++++++++++----
 lib/odp-util.h                  |  5 +++-
 ofproto/ofproto-dpif-xlate.c    | 16 +++++++++++++
 ofproto/ofproto-dpif.c          |  3 +++
 ofproto/tunnel.c                |  1 +
 tests/bfd.at                    |  2 +-
 tests/tunnel.at                 | 40 ++++++++++++++++----------------
 16 files changed, 154 insertions(+), 28 deletions(-)

diff --git a/include/openvswitch/match.h b/include/openvswitch/match.h
index 2e8812048e86..b962badfcfd3 100644
--- a/include/openvswitch/match.h
+++ b/include/openvswitch/match.h
@@ -127,6 +127,7 @@ void match_set_tun_gtpu_flags_masked(struct match *match, 
uint8_t flags,
 void match_set_tun_gtpu_msgtype(struct match *match, uint8_t msgtype);
 void match_set_tun_gtpu_msgtype_masked(struct match *match, uint8_t msgtype,
                                        uint8_t mask);
+void match_set_tun_eth_type(struct match *, ovs_be16);
 void match_set_in_port(struct match *, ofp_port_t ofp_port);
 void match_set_pkt_mark(struct match *, uint32_t pkt_mark);
 void match_set_pkt_mark_masked(struct match *, uint32_t pkt_mark, uint32_t 
mask);
diff --git a/include/openvswitch/meta-flow.h b/include/openvswitch/meta-flow.h
index 875f122c5f55..e644c684bbf0 100644
--- a/include/openvswitch/meta-flow.h
+++ b/include/openvswitch/meta-flow.h
@@ -304,6 +304,20 @@ enum OVS_PACKED_ENUM mf_field_id {
      */
     MFF_TUN_ID,
 
+    /* "tun_eth_type".
+     *
+     * Packet's Tunnel Ethernet type.
+     *
+     * Type: be16.
+     * Maskable: no.
+     * Formatting: decimal.
+     * Prerequisites: none.
+     * Access: read-only.
+     * NXM: none.
+     * OXM: none.
+     */
+    MFF_TUN_ETH_TYPE,
+
     /* "tun_src".
      *
      * The IPv4 source address in the outer IP header of a tunneled packet.
diff --git a/include/openvswitch/packets.h b/include/openvswitch/packets.h
index a65cb0d04e77..c9af1b6ceca6 100644
--- a/include/openvswitch/packets.h
+++ b/include/openvswitch/packets.h
@@ -45,7 +45,8 @@ struct flow_tnl {
     uint8_t erspan_hwid;
     uint8_t gtpu_flags;
     uint8_t gtpu_msgtype;
-    uint8_t pad1[4];     /* Pad to 64 bits. */
+    ovs_be16 eth_type;
+    uint8_t pad1[2];     /* Pad to 64 bits. */
     struct tun_metadata metadata;
 };
 
diff --git a/lib/dpif.c b/lib/dpif.c
index 070fc0131ffb..dbec240cc9c8 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1945,6 +1945,12 @@ dpif_may_support_psample(const struct dpif *dpif)
     return !dpif_is_netdev(dpif);
 }
 
+bool
+dpif_supports_tun_eth_type(const struct dpif *dpif)
+{
+    return dpif_is_netdev(dpif);
+}
+
 /* Meters */
 void
 dpif_meter_get_features(const struct dpif *dpif,
diff --git a/lib/dpif.h b/lib/dpif.h
index 0b685d8df133..0a410fca5bd2 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -921,6 +921,7 @@ int dpif_bond_add(struct dpif *, uint32_t bond_id, 
odp_port_t *member_map);
 int dpif_bond_del(struct dpif *, uint32_t bond_id);
 int dpif_bond_stats_get(struct dpif *, uint32_t bond_id, uint64_t *n_bytes);
 bool dpif_supports_lb_output_action(const struct dpif *);
+bool dpif_supports_tun_eth_type(const struct dpif *);
 
 
 /* Cache */
diff --git a/lib/match.c b/lib/match.c
index 9b7e06e0c7f8..bd8b21d592b1 100644
--- a/lib/match.c
+++ b/lib/match.c
@@ -402,6 +402,13 @@ match_set_tun_gtpu_msgtype(struct match *match, uint8_t 
msgtype)
     match_set_tun_gtpu_msgtype_masked(match, msgtype, UINT8_MAX);
 }
 
+void
+match_set_tun_eth_type(struct match *match, ovs_be16 eth_type)
+{
+    match->wc.masks.tunnel.eth_type = OVS_BE16_MAX;
+    match->flow.tunnel.eth_type = eth_type;
+}
+
 void
 match_set_in_port(struct match *match, ofp_port_t ofp_port)
 {
@@ -1391,6 +1398,9 @@ format_flow_tunnel(struct ds *s, const struct match 
*match)
     if (wc->masks.tunnel.gtpu_msgtype) {
         ds_put_format(s, "gtpu_msgtype=%"PRIu8",", tnl->gtpu_msgtype);
     }
+    if (wc->masks.tunnel.eth_type) {
+        ds_put_format(s, "tun_eth_type=0x%04"PRIx16",", ntohs(tnl->eth_type));
+    }
     if (wc->masks.tunnel.flags & FLOW_TNL_F_MASK) {
         format_flags_masked(s, "tun_flags", flow_tun_flag_to_string,
                             tnl->flags & FLOW_TNL_F_MASK,
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 2595fd634b4d..2a6ae129a91a 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -213,6 +213,8 @@ mf_is_all_wild(const struct mf_field *mf, const struct 
flow_wildcards *wc)
         return !wc->masks.packet_type;
     case MFF_CONJ_ID:
         return !wc->masks.conj_id;
+    case MFF_TUN_ETH_TYPE:
+        return !wc->masks.tunnel.eth_type;
     case MFF_TUN_SRC:
         return !wc->masks.tunnel.ip_src;
     case MFF_TUN_DST:
@@ -524,6 +526,7 @@ mf_is_value_valid(const struct mf_field *mf, const union 
mf_value *value)
     case MFF_PACKET_TYPE:
     case MFF_CONJ_ID:
     case MFF_TUN_ID:
+    case MFF_TUN_ETH_TYPE:
     case MFF_TUN_SRC:
     case MFF_TUN_DST:
     case MFF_TUN_IPV6_SRC:
@@ -680,6 +683,9 @@ mf_get_value(const struct mf_field *mf, const struct flow 
*flow,
     case MFF_TUN_ID:
         value->be64 = flow->tunnel.tun_id;
         break;
+    case MFF_TUN_ETH_TYPE:
+        value->be16 = flow->tunnel.eth_type;
+        break;
     case MFF_TUN_SRC:
         value->be32 = flow->tunnel.ip_src;
         break;
@@ -1017,6 +1023,9 @@ mf_set_value(const struct mf_field *mf,
     case MFF_TUN_ID:
         match_set_tun_id(match, value->be64);
         break;
+    case MFF_TUN_ETH_TYPE:
+        match_set_tun_eth_type(match, value->be16);
+        break;
     case MFF_TUN_SRC:
         match_set_tun_src(match, value->be32);
         break;
@@ -1439,6 +1448,9 @@ mf_set_flow_value(const struct mf_field *mf,
     case MFF_TUN_ID:
         flow->tunnel.tun_id = value->be64;
         break;
+    case MFF_TUN_ETH_TYPE:
+        flow->tunnel.eth_type = value->be16;
+        break;
     case MFF_TUN_SRC:
         flow->tunnel.ip_src = value->be32;
         break;
@@ -1823,6 +1835,7 @@ mf_is_any_metadata(const struct mf_field *mf)
         return true;
 
     case MFF_TUN_ID:
+    case MFF_TUN_ETH_TYPE:
     case MFF_TUN_SRC:
     case MFF_TUN_DST:
     case MFF_TUN_IPV6_SRC:
@@ -1917,6 +1930,7 @@ mf_is_pipeline_field(const struct mf_field *mf)
 {
     switch (mf->id) {
     case MFF_TUN_ID:
+    case MFF_TUN_ETH_TYPE:
     case MFF_TUN_SRC:
     case MFF_TUN_DST:
     case MFF_TUN_IPV6_SRC:
@@ -2075,6 +2089,9 @@ mf_set_wild(const struct mf_field *mf, struct match 
*match, char **err_str)
     case MFF_TUN_ID:
         match_set_tun_id_masked(match, htonll(0), htonll(0));
         break;
+    case MFF_TUN_ETH_TYPE:
+        match->flow.tunnel.eth_type = 0;
+        break;
     case MFF_TUN_SRC:
         match_set_tun_src_masked(match, htonl(0), htonl(0));
         break;
@@ -2479,6 +2496,7 @@ mf_set(const struct mf_field *mf,
     case MFF_ICMPV6_CODE:
     case MFF_ND_RESERVED:
     case MFF_ND_OPTIONS_TYPE:
+    case MFF_TUN_ETH_TYPE:
         return OFPUTIL_P_NONE;
 
     case MFF_DP_HASH:
diff --git a/lib/meta-flow.xml b/lib/meta-flow.xml
index 5c57ab08ff18..558298279b9e 100644
--- a/lib/meta-flow.xml
+++ b/lib/meta-flow.xml
@@ -1508,6 +1508,7 @@ ovs-ofctl add-flow br-int 
'in_port=3,tun_src=192.168.1.1,tun_id=5001 actions=1'
       </diagram>
     </field>
 
+    <field id="MFF_TUN_ETH_TYPE" title="Tunnel Ethernet type" internal="yes"/>
     <field id="MFF_TUN_SRC" title="Tunnel IPv4 Source">
       <p>
         When a packet is received from a tunnel, this field is the
diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c
index 008b452b8a6e..92bc1d08a813 100644
--- a/lib/netdev-native-tnl.c
+++ b/lib/netdev-native-tnl.c
@@ -506,6 +506,7 @@ netdev_gre_pop_header(struct dp_packet *packet)
     struct pkt_metadata *md = &packet->md;
     struct flow_tnl *tnl = &md->tunnel;
     int hlen = sizeof(struct eth_header) + 4;
+    const struct eth_header *eth;
 
     ovs_assert(data_dp);
 
@@ -522,6 +523,11 @@ netdev_gre_pop_header(struct dp_packet *packet)
         goto err;
     }
 
+    eth = dp_packet_eth(packet);
+    if (eth) {
+        tnl->eth_type = eth->eth_type;
+    }
+
     tnl_ol_pop(packet, hlen);
 
     return packet;
@@ -1102,6 +1108,7 @@ netdev_vxlan_pop_header(struct dp_packet *packet)
     unsigned int hlen;
     ovs_be32 vx_flags;
     enum packet_type next_pt = PT_ETH;
+    const struct eth_header *eth;
 
     ovs_assert(packet->l3_ofs > 0);
     ovs_assert(packet->l4_ofs > 0);
@@ -1152,6 +1159,12 @@ netdev_vxlan_pop_header(struct dp_packet *packet)
     tnl->flags |= FLOW_TNL_F_KEY;
 
     packet->packet_type = htonl(next_pt);
+
+    eth = dp_packet_eth(packet);
+    if (eth) {
+        tnl->eth_type = eth->eth_type;
+    }
+
     tnl_ol_pop(packet, hlen + VXLAN_HLEN);
     if (next_pt != PT_ETH) {
         packet->l3_ofs = 0;
@@ -1219,6 +1232,7 @@ netdev_geneve_pop_header(struct dp_packet *packet)
     struct flow_tnl *tnl = &md->tunnel;
     struct genevehdr *gnh;
     unsigned int hlen, opts_len, ulen;
+    const struct eth_header *eth;
 
     pkt_metadata_init_tnl(md);
     if (GENEVE_BASE_HLEN > dp_packet_l4_size(packet)) {
@@ -1260,6 +1274,12 @@ netdev_geneve_pop_header(struct dp_packet *packet)
     tnl->flags |= FLOW_TNL_F_UDPIF;
 
     packet->packet_type = htonl(PT_ETH);
+
+    eth = dp_packet_eth(packet);
+    if (eth) {
+        tnl->eth_type = eth->eth_type;
+    }
+
     tnl_ol_pop(packet, hlen);
 
     return packet;
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index ca1982ccd8fb..b8942294691f 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -1184,11 +1184,32 @@ parse_tnl_ip_match(struct flow_patterns *patterns,
                    struct match *match,
                    uint8_t proto)
 {
+    ovs_be16 eth_type = match->flow.tunnel.eth_type;
     struct flow *consumed_masks;
+    bool is_ipv4, is_ipv6;
+
+    /* Determine IP version - either explicitly set via eth_type
+     * or inferred from masks.
+     */
+    if (eth_type == htons(ETH_TYPE_IP)) {
+        is_ipv4 = true;
+        is_ipv6 = false;
+    } else if (eth_type == htons(ETH_TYPE_IPV6)) {
+        is_ipv4 = false;
+        is_ipv6 = true;
+    } else {
+        /* eth_type is 0 - infer from which address masks are set */
+        is_ipv4 = (match->wc.masks.tunnel.ip_src ||
+                   match->wc.masks.tunnel.ip_dst);
+        is_ipv6 = (!is_all_zeros(&match->wc.masks.tunnel.ipv6_src,
+                   sizeof(struct in6_addr)) ||
+                   !is_all_zeros(&match->wc.masks.tunnel.ipv6_dst,
+                   sizeof(struct in6_addr)));
+    }
 
     consumed_masks = &match->wc.masks;
     /* IP v4 */
-    if (match->wc.masks.tunnel.ip_src || match->wc.masks.tunnel.ip_dst) {
+    if (is_ipv4) {
         struct rte_flow_item_ipv4 *spec, *mask;
 
         spec = xzalloc(sizeof *spec);
@@ -1212,10 +1233,7 @@ parse_tnl_ip_match(struct flow_patterns *patterns,
         consumed_masks->tunnel.ip_dst = 0;
 
         add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_IPV4, spec, mask, NULL);
-    } else if (!is_all_zeros(&match->wc.masks.tunnel.ipv6_src,
-                             sizeof(struct in6_addr)) ||
-               !is_all_zeros(&match->wc.masks.tunnel.ipv6_dst,
-                             sizeof(struct in6_addr))) {
+    } else if (is_ipv6) {
         /* IP v6 */
         struct rte_flow_item_ipv6 *spec, *mask;
 
@@ -1378,6 +1396,19 @@ parse_flow_tnl_match(struct netdev *tnldev,
         return ret;
     }
 
+    if (match->wc.masks.tunnel.eth_type) {
+        struct rte_flow_item_eth *spec, *mask;
+
+        spec = xzalloc(sizeof *spec);
+        mask = xzalloc(sizeof *mask);
+
+        spec->type = match->flow.tunnel.eth_type;
+        mask->type = match->wc.masks.tunnel.eth_type;
+        match->wc.masks.tunnel.eth_type = 0;
+
+        add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_ETH, spec, mask, NULL);
+    }
+
     if (!strcmp(netdev_get_type(tnldev), "vxlan")) {
         ret = parse_vxlan_match(patterns, match);
     }
diff --git a/lib/odp-util.h b/lib/odp-util.h
index 339ffc14f248..66b5339ed2ba 100644
--- a/lib/odp-util.h
+++ b/lib/odp-util.h
@@ -207,7 +207,10 @@ int odp_flow_from_string(const char *s, const struct simap 
*port_names,
                                                                              \
     /* If true, it means that the datapath supports the IPv6 Neigh           \
      * Discovery Extension bits. */                                          \
-    ODP_SUPPORT_FIELD(bool, nd_ext, "IPv6 ND Extension")
+    ODP_SUPPORT_FIELD(bool, nd_ext, "IPv6 ND Extension")                     \
+                                                                             \
+    /* Tunnel ethernet type matching supported. */                           \
+    ODP_SUPPORT_FIELD(bool, tun_eth_type, "Tunnel Ethernet Type")
 
 /* Indicates support for various fields. This defines how flows will be
  * serialised. */
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 2c8197fb7307..7350d141c906 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -8081,6 +8081,8 @@ xlate_wc_init(struct xlate_ctx *ctx)
 static void
 xlate_wc_finish(struct xlate_ctx *ctx)
 {
+    struct ofproto_dpif *ofproto = ctx->xbridge->ofproto;
+    struct dpif_backer *backer = ofproto->backer;
     int i;
 
     /* Clear the metadata and register wildcard masks, because we won't
@@ -8152,6 +8154,20 @@ xlate_wc_finish(struct xlate_ctx *ctx)
     if (!flow_tnl_dst_is_set(&ctx->xin->upcall_flow->tunnel)) {
         memset(&ctx->wc->masks.tunnel, 0, sizeof ctx->wc->masks.tunnel);
     }
+    /* Clear tunnel eth type if not supported. */
+    if (!backer->rt_support.odp.tun_eth_type) {
+        ctx->wc->masks.tunnel.eth_type = 0;
+    }
+    /* Clear IPv6 artifacts when eth_type explicitly indicates IPv4 */
+    if (ctx->wc->masks.tunnel.eth_type == htons(ETH_TYPE_IP)) {
+        ctx->wc->masks.tunnel.ipv6_src = in6addr_any;
+        ctx->wc->masks.tunnel.ipv6_dst = in6addr_any;
+    }
+    /* Clear IPv4 artifacts when eth_type explicitly indicates IPv6 */
+    if (ctx->wc->masks.tunnel.eth_type == htons(ETH_TYPE_IPV6)) {
+        ctx->wc->masks.tunnel.ip_src = 0;
+        ctx->wc->masks.tunnel.ip_dst = 0;
+    }
 }
 
 /* This will tweak the odp actions generated. For now, it will:
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 4a200dd08828..c1b3474a1b56 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1759,6 +1759,8 @@ check_support(struct dpif_backer *backer)
     backer->rt_support.odp.ct_orig_tuple = check_ct_orig_tuple(backer);
     backer->rt_support.odp.ct_orig_tuple6 = check_ct_orig_tuple6(backer);
     backer->rt_support.odp.nd_ext = check_nd_extensions(backer);
+    backer->rt_support.odp.tun_eth_type =
+        dpif_supports_tun_eth_type(backer->dpif);
 }
 
 /* TC does not support offloading the explicit drop action. As such we need to
@@ -5924,6 +5926,7 @@ get_datapath_cap(const char *datapath_type, struct smap 
*cap)
     smap_add(cap, "ct_orig_tuple", s->odp.ct_orig_tuple ? "true" : "false");
     smap_add(cap, "ct_orig_tuple6", s->odp.ct_orig_tuple6 ? "true" : "false");
     smap_add(cap, "nd_ext", s->odp.nd_ext ? "true" : "false");
+    smap_add(cap, "tun_eth_type", s->odp.tun_eth_type ? "true" : "false");
 
     /* DPIF_SUPPORT_FIELDS */
     smap_add(cap, "masked_set_action",
diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c
index f067a6c26c19..4adc87b91baa 100644
--- a/ofproto/tunnel.c
+++ b/ofproto/tunnel.c
@@ -381,6 +381,7 @@ tnl_wc_init(struct flow *flow, struct flow_wildcards *wc)
          * wildcarded, not to unwildcard them here. */
         wc->masks.tunnel.tp_src = 0;
         wc->masks.tunnel.tp_dst = 0;
+        wc->masks.tunnel.eth_type = OVS_BE16_MAX;
 
         if (is_ip_any(flow)
             && IP_ECN_is_ce(flow->tunnel.ip_tos)) {
diff --git a/tests/bfd.at b/tests/bfd.at
index f5c6409f6c65..aea0a3392325 100644
--- a/tests/bfd.at
+++ b/tests/bfd.at
@@ -1127,7 +1127,7 @@ bridge("br0")
      -> no learned MAC for destination, flooding
 
 Final flow: unchanged
-Megaflow: 
recirc_id=0,eth,udp,tun_id=0,tun_src=2.2.2.2,tun_dst=2.2.2.1,tun_tos=0,tun_flags=-df-csum+key,in_port=1,dl_src=00:11:22:33:44:66,dl_dst=00:23:20:00:00:77,nw_frag=no,tp_dst=3784
+Megaflow: 
recirc_id=0,eth,udp,tun_id=0,tun_src=2.2.2.2,tun_dst=2.2.2.1,tun_tos=0,tun_eth_type=0x0000,tun_flags=-df-csum+key,in_port=1,dl_src=00:11:22:33:44:66,dl_dst=00:23:20:00:00:77,nw_frag=no,tp_dst=3784
 Datapath actions: 100
 ], [])
 
diff --git a/tests/tunnel.at b/tests/tunnel.at
index e1a16138fa29..4488cde52736 100644
--- a/tests/tunnel.at
+++ b/tests/tunnel.at
@@ -82,21 +82,21 @@ AT_CHECK([ovs-appctl dpif/show | tail -n +3], [0], [dnl
 dnl Tunnel CE and encapsulated packet CE
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,ttl=64,flags()),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=3,ttl=64,frag=no),tcp(src=8,dst=9)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_flags=-df-csum-key,in_port=1,nw_ecn=3,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_eth_type=0x0000,tun_flags=-df-csum-key,in_port=1,nw_ecn=3,nw_frag=no
 Datapath actions: 2
 ])
 
 dnl Tunnel CE and encapsulated packet ECT(1)
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,ttl=64,flags()),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=1,ttl=64,frag=no),tcp(src=8,dst=9)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_flags=-df-csum-key,in_port=1,nw_ecn=1,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_eth_type=0x0000,tun_flags=-df-csum-key,in_port=1,nw_ecn=1,nw_frag=no
 Datapath actions: set(ipv4(tos=0x3/0x3)),2
 ])
 
 dnl Tunnel CE and encapsulated packet ECT(2)
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,ttl=64,flags()),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=2,ttl=64,frag=no),tcp(src=8,dst=9)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_flags=-df-csum-key,in_port=1,nw_ecn=2,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_eth_type=0x0000,tun_flags=-df-csum-key,in_port=1,nw_ecn=2,nw_frag=no
 Datapath actions: set(ipv4(tos=0x3/0x3)),2
 ])
 
@@ -104,7 +104,7 @@ dnl Tunnel CE and encapsulated packet Non-ECT
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,ttl=64,flags()),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9)'],
 [0], [stdout])
 AT_CHECK([tail -3 stdout], [0],
   [Final flow: unchanged
-Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_flags=-df-csum-key,in_port=1,nw_ecn=0,nw_frag=no
+Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_eth_type=0x0000,tun_flags=-df-csum-key,in_port=1,nw_ecn=0,nw_frag=no
 Datapath actions: drop
 ])
 OVS_VSWITCHD_STOP(["/dropping tunnel packet marked ECN CE but is not ECN 
capable/d"])
@@ -721,28 +721,28 @@ AT_CHECK([tail -1 stdout], [0],
 dnl receive packet from ERSPAN port with v1 metadata
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x1,src=1.1.1.1,dst=2.2.2.2,ttl=64,erspan(ver=1,idx=0x7),flags(df|key)),in_port(3),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0x1,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=1,tun_erspan_idx=0x7,tun_flags=+df-csum+key,in_port=3,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0x1,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=1,tun_erspan_idx=0x7,tun_eth_type=0x0000,tun_flags=+df-csum+key,in_port=3,nw_frag=no
 Datapath actions: 1
 ])
 
 dnl receive packet from ERSPAN port with wrong v1 metadata
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x1,src=1.1.1.1,dst=2.2.2.2,ttl=64,erspan(ver=1,idx=0xabcd),flags(df|key)),in_port(3),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0x1,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=1,tun_erspan_idx=0xabcd,tun_flags=+df-csum+key,in_port=3,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0x1,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=1,tun_erspan_idx=0xabcd,tun_eth_type=0x0000,tun_flags=+df-csum+key,in_port=3,nw_frag=no
 Datapath actions: drop
 ])
 
 dnl receive packet from ERSPAN port with v2 metadata
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x2,src=1.1.1.2,dst=2.2.2.2,ttl=64,erspan(ver=2,dir=1,hwid=0x7),flags(df|key)),in_port(3),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=2,tun_erspan_dir=1,tun_erspan_hwid=0x1,tun_flags=+df-csum+key,in_port=4,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=2,tun_erspan_dir=1,tun_erspan_hwid=0x1,tun_eth_type=0x0000,tun_flags=+df-csum+key,in_port=4,nw_frag=no
 Datapath actions: 2
 ])
 
 dnl receive packet from ERSPAN port with wrong v2 metadata
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x2,src=1.1.1.2,dst=2.2.2.2,ttl=64,erspan(ver=2,dir=0,hwid=0x17),flags(df|key)),in_port(3),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=2,tun_erspan_dir=0,tun_erspan_hwid=0x1,tun_flags=+df-csum+key,in_port=4,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=2,tun_erspan_dir=0,tun_erspan_hwid=0x1,tun_eth_type=0x0000,tun_flags=+df-csum+key,in_port=4,nw_frag=no
 Datapath actions: drop
 ])
 
@@ -761,7 +761,7 @@ AT_CHECK([ovs-ofctl --sort=in_port dump-flows br0 | 
ofctl_strip],
 dnl this time it won't drop
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x2,src=1.1.1.2,dst=2.2.2.2,ttl=64,erspan(ver=2,dir=0,hwid=0x17),flags(df|key)),in_port(3),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=2,tun_flags=+df-csum+key,in_port=4,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=2,tun_eth_type=0x0000,tun_flags=+df-csum+key,in_port=4,nw_frag=no
 Datapath actions: 2
 ])
 
@@ -811,14 +811,14 @@ AT_CHECK([tail -1 stdout], [0],
 dnl Option match
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0xb}),flags(df|key)),in_port(6081),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata0=0xb/0xf,in_port=1,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_eth_type=0x0000,tun_flags=+df-csum+key,tun_metadata0=0xb/0xf,in_port=1,nw_frag=no
 Datapath actions: 2
 ])
 
 dnl Skip unknown option
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0xb}{class=0xffff,type=2,len=4,0xc}),flags(df|key)),in_port(6081),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata0=0xb/0xf,in_port=1,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_eth_type=0x0000,tun_flags=+df-csum+key,tun_metadata0=0xb/0xf,in_port=1,nw_frag=no
 Datapath actions: 2
 ])
 
@@ -852,7 +852,7 @@ AT_CHECK([ovs-ofctl add-tlv-map br0 
"{class=0xffff,type=3,len=8}->tun_metadata3"
 AT_CHECK([ovs-ofctl add-flow br0 tun_metadata3=0x1234567890abcdef,actions=2])
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=3,len=8,0x1234567890abcdef}),flags(df|key)),in_port(6081),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata3=0x1234567890abcdef,in_port=1,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_eth_type=0x0000,tun_flags=+df-csum+key,tun_metadata3=0x1234567890abcdef,in_port=1,nw_frag=no
 Datapath actions: 2
 ])
 
@@ -961,13 +961,13 @@ NXST_FLOW reply:
 
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0x12345678}),flags(df|key)),in_port(6081),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata0,tun_metadata1=NP,tun_metadata2=NP,in_port=1,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_eth_type=0x0000,tun_flags=+df-csum+key,tun_metadata0,tun_metadata1=NP,tun_metadata2=NP,in_port=1,nw_frag=no
 Datapath actions: 2
 ])
 
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=1,len=0}),flags(df|key)),in_port(6081),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata1,tun_metadata2=NP,in_port=1,nw_ecn=0,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_eth_type=0x0000,tun_flags=+df-csum+key,tun_metadata1,tun_metadata2=NP,in_port=1,nw_ecn=0,nw_frag=no
 Datapath actions: 
set(tunnel(dst=1.1.1.1,ttl=64,tp_dst=6081,geneve({class=0xffff,type=0x1,len=0}),flags(df))),6081
 ])
 
@@ -993,19 +993,19 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0x11112222}),flags(df|key)),in_port(6081),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata0=0x11112222,tun_metadata1=NP,in_port=1,nw_ecn=0,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_eth_type=0x0000,tun_flags=+df-csum+key,tun_metadata0=0x11112222,tun_metadata1=NP,in_port=1,nw_ecn=0,nw_frag=no
 Datapath actions: 
set(tunnel(dst=1.1.1.1,ttl=64,tp_dst=6081,geneve({class=0xffff,type=0,len=4,0x11112222}{class=0xffff,type=0x1,len=4,0x55556666}),flags(df))),6081
 ])
 
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0x33334444}),flags(df|key)),in_port(6081),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata0=0x33334444,tun_metadata1=NP,in_port=1,nw_ecn=0,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_eth_type=0x0000,tun_flags=+df-csum+key,tun_metadata0=0x33334444,tun_metadata1=NP,in_port=1,nw_ecn=0,nw_frag=no
 Datapath actions: 
set(tunnel(dst=1.1.1.1,ttl=64,tp_dst=6081,geneve({class=0xffff,type=0x1,len=4,0x77778888}),flags(df))),6081
 ])
 
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0x88889999}),flags(df|key)),in_port(6081),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata0=0x88889999,in_port=1,nw_ecn=0,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_eth_type=0x0000,tun_flags=+df-csum+key,tun_metadata0=0x88889999,in_port=1,nw_ecn=0,nw_frag=no
 Datapath actions: 
set(tunnel(dst=1.1.1.1,ttl=64,tp_dst=6081,geneve({class=0xffff,type=0,len=4,0x88889999}),flags(df))),6081
 ])
 OVS_VSWITCHD_STOP
@@ -1095,7 +1095,7 @@ dnl the input packet from geneve tunnel has 
flags(-df+csum+key) flags, making
 dnl sure that the output gre tunnel has (+df-csum+key).
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0x12345678}),flags(csum|key)),in_port(6081),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=-df+csum+key,in_port=1,nw_ecn=0,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_eth_type=0x0000,tun_flags=-df+csum+key,in_port=1,nw_ecn=0,nw_frag=no
 Datapath actions: set(tunnel(tun_id=0x7b,dst=2.2.2.2,ttl=64,flags(df|key))),1
 ])
 
@@ -1109,7 +1109,7 @@ AT_CHECK([ovs-ofctl add-flows br0 flows2.txt])
 
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0x123}),flags(csum|key)),in_port(6081),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=-df+csum+key,tun_metadata0=0x123,in_port=1,nw_ecn=0,nw_frag=no
+  [Megaflow: 
recirc_id=0,eth,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_eth_type=0x0000,tun_flags=-df+csum+key,tun_metadata0=0x123,in_port=1,nw_ecn=0,nw_frag=no
 Datapath actions: set(tunnel(tun_id=0x7b,dst=2.2.2.2,ttl=64,flags(df|key))),1
 ])
 
@@ -1236,7 +1236,7 @@ AT_CHECK([tail -1 stdout], [0],
 dnl receive packet from GTP-U port, match it, and output to layer3 GRE
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 
'recirc_id(0),tunnel(tun_id=0x3,src=1.1.1.1,dst=2.2.2.2,ttl=64,gtpu(flags=0x30,msgtype=255),flags(df|key)),in_port(2152),packet_type(ns=1,id=0),skb_mark(0),ipv4(frag=no)'],
 [0], [stdout])
 AT_CHECK([tail -2 stdout], [0],
-  [Megaflow: 
recirc_id=0,packet_type=(1,0),tun_id=0x3,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0,gtpu_flags=0x30,gtpu_msgtype=255,tun_flags=+df-csum+key,in_port=3,dl_type=0x0000
+  [Megaflow: 
recirc_id=0,packet_type=(1,0),tun_id=0x3,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0,gtpu_flags=0x30,gtpu_msgtype=255,tun_eth_type=0x0000,tun_flags=+df-csum+key,in_port=3,dl_type=0x0000
 Datapath actions: push_eth(src=00:00:00:00:00:00,dst=00:00:00:00:00:00),1
 ])
 
-- 
2.47.0

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

Reply via email to