diff --git a/.openvswitch.metadata b/.openvswitch.metadata index 53d7d0a..aae65b4 100644 --- a/.openvswitch.metadata +++ b/.openvswitch.metadata @@ -1,5 +1,5 @@ 002450621b33c5690060345b0aac25bc2426d675 SOURCES/docutils-0.12.tar.gz -019c0a80416de57f0820850034e17ce2a4768910 SOURCES/openvswitch-2.17.0.tar.gz +722b63cd114c21041abda7b38d7f14e46338e3e0 SOURCES/openvswitch-2.17.0.tar.gz 8509a716f9f936526f64fb23f313c5a9baf2f123 SOURCES/pyelftools-0.27.tar.gz d34f96421a86004aa5d26ecf975edefd09f948b1 SOURCES/Pygments-1.4.tar.gz 3a11f130c63b057532ca37fe49c8967d0cbae1d5 SOURCES/Sphinx-1.2.3.tar.gz diff --git a/SOURCES/openvswitch-2.17.0.patch b/SOURCES/openvswitch-2.17.0.patch index d36876f..7720d72 100644 --- a/SOURCES/openvswitch-2.17.0.patch +++ b/SOURCES/openvswitch-2.17.0.patch @@ -50900,6 +50900,55 @@ index 228b185c3a..8e6c46a85f 100644 #ifdef __cplusplus } #endif +diff --git a/include/sparse/numa.h b/include/sparse/numa.h +index 3691a0eaf7..a185972e31 100644 +--- a/include/sparse/numa.h ++++ b/include/sparse/numa.h +@@ -18,10 +18,21 @@ + #error "Use this header only with sparse. It is not a correct implementation." + #endif + +-/* Avoid sparse warning: non-ANSI function declaration of function" */ +-#define numa_get_membind_compat() numa_get_membind_compat(void) +-#define numa_get_interleave_mask_compat() numa_get_interleave_mask_compat(void) +-#define numa_get_run_node_mask_compat() numa_get_run_node_mask_compat(void) ++#ifndef __NUMA_H_SPARSE ++#define __NUMA_H_SPARSE 1 + +-/* Get actual definitions for us to annotate and build on. */ +-#include_next ++/* Avoid sparse warning "non-ANSI function declaration of function" with ++ * libnuma < 2.0.13. */ ++ ++struct bitmask { ++ unsigned long size; ++ unsigned long *maskp; ++}; ++ ++int numa_available(void); ++struct bitmask *numa_allocate_nodemask(void); ++void numa_bitmask_free(struct bitmask *); ++void numa_set_localalloc(void); ++void numa_set_preferred(int node); ++ ++#endif /* for sparse. */ +diff --git a/include/sparse/rte_memcpy.h b/include/sparse/rte_memcpy.h +index 5cd3f013ea..ec88500242 100644 +--- a/include/sparse/rte_memcpy.h ++++ b/include/sparse/rte_memcpy.h +@@ -20,11 +20,8 @@ + #error "Use this header only with sparse. It is not a correct implementation." + #endif + +-/* Include the same headers as the real rte_memcpy(). */ +-#include ++#include + #include +-#include +-#include + + /* Declare the same functions as the real rte_memcpy.h, without defining them. + * This gives sparse the information it needs without provoking sparse's diff --git a/ipsec/ovs-monitor-ipsec.in b/ipsec/ovs-monitor-ipsec.in index a8b0705d9f..631a8fca80 100755 --- a/ipsec/ovs-monitor-ipsec.in @@ -53792,7 +53841,7 @@ index 94dc6a9b74..303b99daf4 100644 .queue = rss_data->queue, .key_len = 0, diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c -index 9845e8d3fe..057fad412a 100644 +index 9845e8d3fe..19eae7bd20 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -44,6 +44,7 @@ @@ -53803,16 +53852,130 @@ index 9845e8d3fe..057fad412a 100644 static struct hmap ufid_to_tc = HMAP_INITIALIZER(&ufid_to_tc); static struct hmap tc_to_ufid = HMAP_INITIALIZER(&tc_to_ufid); -@@ -204,7 +205,7 @@ del_filter_and_ufid_mapping(struct tcf_id *id, const ovs_u128 *ufid) +@@ -62,6 +63,12 @@ struct chain_node { + uint32_t chain; + }; + ++static void parse_tc_flower_to_stats(struct tc_flower *flower, ++ struct dpif_flow_stats *stats); ++ ++static int get_ufid_adjust_stats(const ovs_u128 *ufid, ++ struct dpif_flow_stats *stats); ++ + static bool + is_internal_port(const char *type) + { +@@ -158,6 +165,9 @@ static struct ovs_mutex ufid_lock = OVS_MUTEX_INITIALIZER; + * @ufid: ufid assigned to the flow + * @id: tc filter id (tcf_id) + * @netdev: netdev associated with the tc rule ++ * @adjust_stats: When flow gets updated with new actions, we need to adjust ++ * the reported stats to include previous values as the hardware ++ * rule is removed and re-added. This stats copy is used for it. + */ + struct ufid_tc_data { + struct hmap_node ufid_to_tc_node; +@@ -165,6 +175,7 @@ struct ufid_tc_data { + ovs_u128 ufid; + struct tcf_id id; + struct netdev *netdev; ++ struct dpif_flow_stats adjust_stats; + }; + + static void +@@ -198,13 +209,39 @@ del_ufid_tc_mapping(const ovs_u128 *ufid) + ovs_mutex_unlock(&ufid_lock); + } + ++static void ++netdev_tc_adjust_stats(struct dpif_flow_stats *stats, ++ const struct dpif_flow_stats *adjust_stats) ++{ ++ /* Do not try to restore the stats->used, as in terse mode dumps TC doesn't ++ * report TCA_ACT_OPTIONS, so the 'lastused' value is not available, hence ++ * we report used as 0. ++ * tcp_flags is not collected by tc, so no need to update it. */ ++ stats->n_bytes += adjust_stats->n_bytes; ++ stats->n_packets += adjust_stats->n_packets; ++} ++ + /* Wrapper function to delete filter and ufid tc mapping */ + static int +-del_filter_and_ufid_mapping(struct tcf_id *id, const ovs_u128 *ufid) ++del_filter_and_ufid_mapping(struct tcf_id *id, const ovs_u128 *ufid, ++ struct dpif_flow_stats *stats) { ++ struct tc_flower flower; int err; - err = tc_del_filter(id); ++ if (stats) { ++ memset(stats, 0, sizeof *stats); ++ if (!tc_get_flower(id, &flower)) { ++ struct dpif_flow_stats adjust_stats; ++ ++ parse_tc_flower_to_stats(&flower, stats); ++ if (!get_ufid_adjust_stats(ufid, &adjust_stats)) { ++ netdev_tc_adjust_stats(stats, &adjust_stats); ++ } ++ } ++ } ++ + err = tc_del_flower_filter(id); if (!err) { del_ufid_tc_mapping(ufid); } -@@ -405,7 +406,7 @@ delete_chains_from_netdev(struct netdev *netdev, struct tcf_id *id) +@@ -214,7 +251,7 @@ del_filter_and_ufid_mapping(struct tcf_id *id, const ovs_u128 *ufid) + /* Add ufid entry to ufid_to_tc hashmap. */ + static void + add_ufid_tc_mapping(struct netdev *netdev, const ovs_u128 *ufid, +- struct tcf_id *id) ++ struct tcf_id *id, struct dpif_flow_stats *stats) + { + struct ufid_tc_data *new_data = xzalloc(sizeof *new_data); + size_t ufid_hash = hash_bytes(ufid, sizeof *ufid, 0); +@@ -226,6 +263,9 @@ add_ufid_tc_mapping(struct netdev *netdev, const ovs_u128 *ufid, + new_data->ufid = *ufid; + new_data->id = *id; + new_data->netdev = netdev_ref(netdev); ++ if (stats) { ++ new_data->adjust_stats = *stats; ++ } + + ovs_mutex_lock(&ufid_lock); + hmap_insert(&ufid_to_tc, &new_data->ufid_to_tc_node, ufid_hash); +@@ -257,6 +297,30 @@ get_ufid_tc_mapping(const ovs_u128 *ufid, struct tcf_id *id) + return ENOENT; + } + ++/* Get adjust_stats from ufid_to_tc hashmap. ++ * ++ * Returns 0 if successful and fills stats with adjust_stats. ++ * Otherwise returns the error. ++*/ ++static int ++get_ufid_adjust_stats(const ovs_u128 *ufid, struct dpif_flow_stats *stats) ++{ ++ size_t ufid_hash = hash_bytes(ufid, sizeof *ufid, 0); ++ struct ufid_tc_data *data; ++ ++ ovs_mutex_lock(&ufid_lock); ++ HMAP_FOR_EACH_WITH_HASH (data, ufid_to_tc_node, ufid_hash, &ufid_to_tc) { ++ if (ovs_u128_equals(*ufid, data->ufid)) { ++ *stats = data->adjust_stats; ++ ovs_mutex_unlock(&ufid_lock); ++ return 0; ++ } ++ } ++ ovs_mutex_unlock(&ufid_lock); ++ ++ return ENOENT; ++} ++ + /* Find ufid entry in ufid_to_tc hashmap using tcf_id id. + * The result is saved in ufid. + * +@@ -405,7 +469,7 @@ delete_chains_from_netdev(struct netdev *netdev, struct tcf_id *id) */ HMAP_FOR_EACH_POP (chain_node, node, &map) { id->chain = chain_node->chain; @@ -53821,7 +53984,7 @@ index 9845e8d3fe..057fad412a 100644 free(chain_node); } } -@@ -417,16 +418,16 @@ delete_chains_from_netdev(struct netdev *netdev, struct tcf_id *id) +@@ -417,16 +481,16 @@ delete_chains_from_netdev(struct netdev *netdev, struct tcf_id *id) static int netdev_tc_flow_flush(struct netdev *netdev) { @@ -53841,7 +54004,7 @@ index 9845e8d3fe..057fad412a 100644 if (!err) { del_ufid_tc_mapping_unlocked(&data->ufid); } -@@ -481,10 +482,10 @@ netdev_tc_flow_dump_destroy(struct netdev_flow_dump *dump) +@@ -481,10 +545,10 @@ netdev_tc_flow_dump_destroy(struct netdev_flow_dump *dump) static void parse_flower_rewrite_to_netlink_action(struct ofpbuf *buf, @@ -53855,7 +54018,7 @@ index 9845e8d3fe..057fad412a 100644 for (int type = 0; type < ARRAY_SIZE(set_flower_map); type++) { char *put = NULL; -@@ -550,30 +551,42 @@ flower_tun_opt_to_match(struct match *match, struct tc_flower *flower) +@@ -550,30 +614,42 @@ flower_tun_opt_to_match(struct match *match, struct tc_flower *flower) struct geneve_opt *opt, *opt_mask; int len, cnt = 0; @@ -53905,7 +54068,7 @@ index 9845e8d3fe..057fad412a 100644 } static void -@@ -585,8 +598,10 @@ parse_tc_flower_to_stats(struct tc_flower *flower, +@@ -585,8 +661,10 @@ parse_tc_flower_to_stats(struct tc_flower *flower, } memset(stats, 0, sizeof *stats); @@ -53918,7 +54081,7 @@ index 9845e8d3fe..057fad412a 100644 stats->used = flower->lastused; } -@@ -616,7 +631,8 @@ parse_tc_flower_terse_to_match(struct tc_flower *flower, +@@ -616,7 +694,8 @@ parse_tc_flower_terse_to_match(struct tc_flower *flower, } static int @@ -53928,7 +54091,7 @@ index 9845e8d3fe..057fad412a 100644 struct match *match, struct nlattr **actions, struct dpif_flow_stats *stats, -@@ -803,18 +819,24 @@ parse_tc_flower_to_match(struct tc_flower *flower, +@@ -803,18 +882,24 @@ parse_tc_flower_to_match(struct tc_flower *flower, &flower->key.tunnel.ipv6.ipv6_src, &flower->mask.tunnel.ipv6.ipv6_src); } @@ -53958,7 +54121,7 @@ index 9845e8d3fe..057fad412a 100644 flower_tun_opt_to_match(match, flower); } } -@@ -877,7 +899,7 @@ parse_tc_flower_to_match(struct tc_flower *flower, +@@ -877,7 +962,7 @@ parse_tc_flower_to_match(struct tc_flower *flower, } break; case TC_ACT_PEDIT: { @@ -53967,7 +54130,20 @@ index 9845e8d3fe..057fad412a 100644 } break; case TC_ACT_ENCAP: { -@@ -965,13 +987,13 @@ parse_tc_flower_to_match(struct tc_flower *flower, +@@ -947,7 +1032,11 @@ parse_tc_flower_to_match(struct tc_flower *flower, + ct_offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_CT); + + if (action->ct.commit) { +- nl_msg_put_flag(buf, OVS_CT_ATTR_COMMIT); ++ if (action->ct.force) { ++ nl_msg_put_flag(buf, OVS_CT_ATTR_FORCE_COMMIT); ++ } else { ++ nl_msg_put_flag(buf, OVS_CT_ATTR_COMMIT); ++ } + } + + if (action->ct.zone) { +@@ -965,13 +1054,13 @@ parse_tc_flower_to_match(struct tc_flower *flower, struct { ovs_u128 key; ovs_u128 mask; @@ -53987,7 +54163,14 @@ index 9845e8d3fe..057fad412a 100644 } if (action->ct.nat_type) { -@@ -1054,8 +1076,8 @@ netdev_tc_flow_dump_next(struct netdev_flow_dump *dump, +@@ -1048,14 +1137,15 @@ netdev_tc_flow_dump_next(struct netdev_flow_dump *dump, + get_tc_qdisc_hook(netdev)); + + while (nl_dump_next(dump->nl_dump, &nl_flow, rbuffer)) { ++ struct dpif_flow_stats adjust_stats; + struct tc_flower flower; + + if (parse_netlink_to_tc_flower(&nl_flow, &id, &flower, dump->terse)) { continue; } @@ -53998,7 +54181,32 @@ index 9845e8d3fe..057fad412a 100644 continue; } -@@ -1194,13 +1216,14 @@ parse_put_flow_ct_action(struct tc_flower *flower, +@@ -1065,6 +1155,10 @@ netdev_tc_flow_dump_next(struct netdev_flow_dump *dump, + continue; + } + ++ if (!get_ufid_adjust_stats(ufid, &adjust_stats)) { ++ netdev_tc_adjust_stats(stats, &adjust_stats); ++ } ++ + match->wc.masks.in_port.odp_port = u32_to_odp(UINT32_MAX); + match->flow.in_port.odp_port = dump->port; + match_set_recirc_id(match, id.chain); +@@ -1164,7 +1258,12 @@ parse_put_flow_ct_action(struct tc_flower *flower, + NL_ATTR_FOR_EACH_UNSAFE (ct_attr, ct_left, ct, ct_len) { + switch (nl_attr_type(ct_attr)) { + case OVS_CT_ATTR_COMMIT: { +- action->ct.commit = true; ++ action->ct.commit = true; ++ } ++ break; ++ case OVS_CT_ATTR_FORCE_COMMIT: { ++ action->ct.commit = true; ++ action->ct.force = true; + } + break; + case OVS_CT_ATTR_ZONE: { +@@ -1194,15 +1293,20 @@ parse_put_flow_ct_action(struct tc_flower *flower, break; case OVS_CT_ATTR_LABELS: { const struct { @@ -54016,8 +54224,14 @@ index 9845e8d3fe..057fad412a 100644 + get_32aligned_u128(&ct_label->mask); } break; ++ /* The following option we do not support in tc-ct, and should ++ * not be ignored for proper operation. */ ++ case OVS_CT_ATTR_HELPER: ++ return EOPNOTSUPP; } -@@ -1222,8 +1245,8 @@ parse_put_flow_set_masked_action(struct tc_flower *flower, + } + +@@ -1222,8 +1326,8 @@ parse_put_flow_set_masked_action(struct tc_flower *flower, uint64_t set_stub[1024 / 8]; struct ofpbuf set_buf = OFPBUF_STUB_INITIALIZER(set_stub); char *set_data, *set_mask; @@ -54028,7 +54242,7 @@ index 9845e8d3fe..057fad412a 100644 const struct nlattr *attr; int i, j, type; size_t size; -@@ -1265,14 +1288,6 @@ parse_put_flow_set_masked_action(struct tc_flower *flower, +@@ -1265,14 +1369,6 @@ parse_put_flow_set_masked_action(struct tc_flower *flower, } } @@ -54043,7 +54257,7 @@ index 9845e8d3fe..057fad412a 100644 if (hasmask && !is_all_zeros(set_mask, size)) { VLOG_DBG_RL(&rl, "unsupported sub attribute of set action type %d", type); -@@ -1281,6 +1296,8 @@ parse_put_flow_set_masked_action(struct tc_flower *flower, +@@ -1281,6 +1377,8 @@ parse_put_flow_set_masked_action(struct tc_flower *flower, } ofpbuf_uninit(&set_buf); @@ -54052,7 +54266,7 @@ index 9845e8d3fe..057fad412a 100644 return 0; } -@@ -1288,6 +1305,7 @@ static int +@@ -1288,6 +1386,7 @@ static int parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action, const struct nlattr *set, size_t set_len) { @@ -54060,7 +54274,7 @@ index 9845e8d3fe..057fad412a 100644 const struct nlattr *tunnel; const struct nlattr *tun_attr; size_t tun_left, tunnel_len; -@@ -1306,6 +1324,7 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action, +@@ -1306,6 +1405,7 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action, action->type = TC_ACT_ENCAP; action->encap.id_present = false; @@ -54068,7 +54282,7 @@ index 9845e8d3fe..057fad412a 100644 flower->action_count++; NL_ATTR_FOR_EACH_UNSAFE(tun_attr, tun_left, tunnel, tunnel_len) { switch (nl_attr_type(tun_attr)) { -@@ -1330,6 +1349,18 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action, +@@ -1330,6 +1430,18 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action, action->encap.ttl = nl_attr_get_u8(tun_attr); } break; @@ -54087,7 +54301,7 @@ index 9845e8d3fe..057fad412a 100644 case OVS_TUNNEL_KEY_ATTR_IPV6_SRC: { action->encap.ipv6.ipv6_src = nl_attr_get_in6_addr(tun_attr); -@@ -1354,12 +1385,31 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action, +@@ -1354,12 +1466,31 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action, action->encap.data.present.len = nl_attr_get_size(tun_attr); } break; @@ -54119,7 +54333,7 @@ index 9845e8d3fe..057fad412a 100644 static int test_key_and_mask(struct match *match) { -@@ -1442,8 +1492,23 @@ test_key_and_mask(struct match *match) +@@ -1442,8 +1573,23 @@ test_key_and_mask(struct match *match) return EOPNOTSUPP; } @@ -54144,7 +54358,7 @@ index 9845e8d3fe..057fad412a 100644 return EOPNOTSUPP; } -@@ -1452,18 +1517,51 @@ test_key_and_mask(struct match *match) +@@ -1452,18 +1598,51 @@ test_key_and_mask(struct match *match) static void flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl, @@ -54199,7 +54413,7 @@ index 9845e8d3fe..057fad412a 100644 len = flower->key.tunnel.metadata.present.len; while (len) { opt = &flower->key.tunnel.metadata.opts.gnv[cnt]; -@@ -1474,8 +1572,6 @@ flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl, +@@ -1474,8 +1653,6 @@ flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl, cnt += sizeof(struct geneve_opt) / 4 + opt->length; len -= sizeof(struct geneve_opt) + opt->length * 4; } @@ -54208,7 +54422,7 @@ index 9845e8d3fe..057fad412a 100644 } static void -@@ -1541,6 +1637,12 @@ parse_match_ct_state_to_flower(struct tc_flower *flower, struct match *match) +@@ -1541,6 +1718,12 @@ parse_match_ct_state_to_flower(struct tc_flower *flower, struct match *match) flower->key.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW); flower->mask.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW); } @@ -54221,16 +54435,17 @@ index 9845e8d3fe..057fad412a 100644 } if (mask->ct_zone) { -@@ -1574,7 +1676,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, +@@ -1574,7 +1757,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, const struct flow *key = &match->flow; struct flow *mask = &match->wc.masks; const struct flow_tnl *tnl = &match->flow.tunnel; - const struct flow_tnl *tnl_mask = &mask->tunnel; + struct flow_tnl *tnl_mask = &mask->tunnel; ++ struct dpif_flow_stats adjust_stats; struct tc_action *action; bool recirc_act = false; uint32_t block_id = 0; -@@ -1615,17 +1717,49 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, +@@ -1615,17 +1799,49 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, flower.key.tunnel.ttl = tnl->ip_ttl; flower.key.tunnel.tp_src = tnl->tp_src; flower.key.tunnel.tp_dst = tnl->tp_dst; @@ -54282,7 +54497,7 @@ index 9845e8d3fe..057fad412a 100644 flower.key.eth_type = key->dl_type; flower.mask.eth_type = mask->dl_type; -@@ -1638,7 +1772,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, +@@ -1638,7 +1854,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, if (mask->vlans[0].tpid && eth_type_vlan(key->vlans[0].tpid)) { flower.key.encap_eth_type[0] = flower.key.eth_type; @@ -54291,7 +54506,7 @@ index 9845e8d3fe..057fad412a 100644 flower.key.eth_type = key->vlans[0].tpid; flower.mask.eth_type = mask->vlans[0].tpid; } -@@ -1734,7 +1868,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, +@@ -1734,7 +1950,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, memset(&mask->arp_tha, 0, sizeof mask->arp_tha); } @@ -54300,7 +54515,7 @@ index 9845e8d3fe..057fad412a 100644 flower.key.ip_proto = key->nw_proto; flower.mask.ip_proto = mask->nw_proto; mask->nw_proto = 0; -@@ -1841,7 +1975,25 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, +@@ -1841,7 +2057,25 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, VLOG_DBG_RL(&rl, "Can't find netdev for output port %d", port); return ENODEV; } @@ -54326,7 +54541,7 @@ index 9845e8d3fe..057fad412a 100644 action->out.ingress = is_internal_port(netdev_get_type(outdev)); action->type = TC_ACT_OUTPUT; flower.action_count++; -@@ -1879,10 +2031,6 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, +@@ -1879,10 +2113,6 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, if (err) { return err; } @@ -54337,7 +54552,32 @@ index 9845e8d3fe..057fad412a 100644 } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_SET_MASKED) { const struct nlattr *set = nl_attr_get(nla); const size_t set_len = nl_attr_get_size(nla); -@@ -1989,7 +2137,8 @@ netdev_tc_flow_get(struct netdev *netdev, +@@ -1929,10 +2159,12 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, + return EOPNOTSUPP; + } + ++ memset(&adjust_stats, 0, sizeof adjust_stats); + if (get_ufid_tc_mapping(ufid, &id) == 0) { + VLOG_DBG_RL(&rl, "updating old handle: %d prio: %d", + id.handle, id.prio); +- info->tc_modify_flow_deleted = !del_filter_and_ufid_mapping(&id, ufid); ++ info->tc_modify_flow_deleted = !del_filter_and_ufid_mapping( ++ &id, ufid, &adjust_stats); + } + + prio = get_prio_for_tc_flower(&flower); +@@ -1950,8 +2182,9 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, + if (!err) { + if (stats) { + memset(stats, 0, sizeof *stats); ++ netdev_tc_adjust_stats(stats, &adjust_stats); + } +- add_ufid_tc_mapping(netdev, ufid, &id); ++ add_ufid_tc_mapping(netdev, ufid, &id, &adjust_stats); + } + + return err; +@@ -1989,8 +2222,16 @@ netdev_tc_flow_get(struct netdev *netdev, } in_port = netdev_ifindex_to_odp_port(id.ifindex); @@ -54345,20 +54585,45 @@ index 9845e8d3fe..057fad412a 100644 + parse_tc_flower_to_match(netdev, &flower, match, actions, + stats, attrs, buf, false); ++ if (stats) { ++ struct dpif_flow_stats adjust_stats; ++ ++ if (!get_ufid_adjust_stats(ufid, &adjust_stats)) { ++ netdev_tc_adjust_stats(stats, &adjust_stats); ++ } ++ } match->wc.masks.in_port.odp_port = u32_to_odp(UINT32_MAX); match->flow.in_port.odp_port = in_port; -@@ -2015,9 +2164,7 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED, - if (stats) { - memset(stats, 0, sizeof *stats); - if (!tc_get_flower(&id, &flower)) { + match_set_recirc_id(match, id.chain); +@@ -2003,7 +2244,6 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED, + const ovs_u128 *ufid, + struct dpif_flow_stats *stats) + { +- struct tc_flower flower; + struct tcf_id id; + int error; + +@@ -2012,18 +2252,7 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED, + return error; + } + +- if (stats) { +- memset(stats, 0, sizeof *stats); +- if (!tc_get_flower(&id, &flower)) { - stats->n_packets = get_32aligned_u64(&flower.stats.n_packets); - stats->n_bytes = get_32aligned_u64(&flower.stats.n_bytes); - stats->used = flower.lastused; -+ parse_tc_flower_to_stats(&flower, stats); - } - } +- } +- } +- +- error = del_filter_and_ufid_mapping(&id, ufid); +- +- return error; ++ return del_filter_and_ufid_mapping(&id, ufid, stats); + } -@@ -2077,13 +2224,13 @@ probe_multi_mask_per_prio(int ifindex) + static int +@@ -2077,13 +2306,13 @@ probe_multi_mask_per_prio(int ifindex) id2 = tc_make_tcf_id(ifindex, block_id, prio, TC_INGRESS); error = tc_replace_flower(&id2, &flower); @@ -54374,7 +54639,7 @@ index 9845e8d3fe..057fad412a 100644 multi_mask_per_prio = true; VLOG_INFO("probe tc: multiple masks on single tc prio is supported."); -@@ -2135,7 +2282,7 @@ probe_ct_state_support(int ifindex) +@@ -2135,7 +2364,7 @@ probe_ct_state_support(int ifindex) goto out_del; } @@ -54383,7 +54648,7 @@ index 9845e8d3fe..057fad412a 100644 ct_state_support = OVS_CS_F_NEW | OVS_CS_F_ESTABLISHED | OVS_CS_F_TRACKED | -@@ -2149,7 +2296,7 @@ probe_ct_state_support(int ifindex) +@@ -2149,7 +2378,7 @@ probe_ct_state_support(int ifindex) goto out_del; } @@ -54392,7 +54657,7 @@ index 9845e8d3fe..057fad412a 100644 /* Test for ct_state INVALID support */ memset(&flower, 0, sizeof flower); -@@ -2160,7 +2307,7 @@ probe_ct_state_support(int ifindex) +@@ -2160,7 +2389,7 @@ probe_ct_state_support(int ifindex) goto out; } @@ -54401,7 +54666,7 @@ index 9845e8d3fe..057fad412a 100644 ct_state_support |= OVS_CS_F_INVALID; /* Test for ct_state REPLY support */ -@@ -2176,7 +2323,7 @@ probe_ct_state_support(int ifindex) +@@ -2176,7 +2405,7 @@ probe_ct_state_support(int ifindex) ct_state_support |= OVS_CS_F_REPLY_DIR; out_del: @@ -54410,7 +54675,7 @@ index 9845e8d3fe..057fad412a 100644 out: tc_add_del_qdisc(ifindex, false, 0, TC_INGRESS); VLOG_INFO("probe tc: supported ovs ct_state bits: 0x%x", ct_state_support); -@@ -2251,7 +2398,7 @@ netdev_tc_init_flow_api(struct netdev *netdev) +@@ -2251,7 +2480,7 @@ netdev_tc_init_flow_api(struct netdev *netdev) /* fallback here if delete chains fail */ if (!get_chain_supported) { @@ -54564,6 +54829,36 @@ index 8305f6c427..c797783782 100644 netdev->node = shash_add(&netdev_shash, name, netdev); /* By default enable one tx and rx queue per netdev. */ +diff --git a/lib/netlink.c b/lib/netlink.c +index 8204025a56..6215282d6f 100644 +--- a/lib/netlink.c ++++ b/lib/netlink.c +@@ -570,6 +570,13 @@ nl_msg_put_nested(struct ofpbuf *msg, + nl_msg_end_nested(msg, offset); + } + ++/* Reset message size to offset. */ ++void ++nl_msg_reset_size(struct ofpbuf *msg, size_t offset) ++{ ++ msg->size = offset; ++} ++ + /* If 'buffer' begins with a valid "struct nlmsghdr", pulls the header and its + * payload off 'buffer', stores header and payload in 'msg->data' and + * 'msg->size', and returns a pointer to the header. +diff --git a/lib/netlink.h b/lib/netlink.h +index b97470743e..e9050c31ba 100644 +--- a/lib/netlink.h ++++ b/lib/netlink.h +@@ -86,6 +86,7 @@ void nl_msg_cancel_nested(struct ofpbuf *, size_t offset); + bool nl_msg_end_non_empty_nested(struct ofpbuf *, size_t offset); + void nl_msg_put_nested(struct ofpbuf *, uint16_t type, + const void *data, size_t size); ++void nl_msg_reset_size(struct ofpbuf *, size_t offset); + + /* Prepending attributes. */ + void *nl_msg_push_unspec_uninit(struct ofpbuf *, uint16_t type, size_t); diff --git a/lib/odp-util.c b/lib/odp-util.c index 9a705cffa3..fac4cf3a8c 100644 --- a/lib/odp-util.c @@ -56038,7 +56333,7 @@ index a921159667..2fe6c540a7 100644 * key-value pairs, e.g. * diff --git a/lib/socket-util.c b/lib/socket-util.c -index 4f1ffecf5d..38705cc51e 100644 +index 4f1ffecf5d..3eb3a3816b 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -62,7 +62,8 @@ static bool parse_sockaddr_components(struct sockaddr_storage *ss, @@ -56130,16 +56425,42 @@ index 4f1ffecf5d..38705cc51e 100644 error = EAFNOSUPPORT; goto exit; } -@@ -660,7 +672,7 @@ inet_parse_passive(const char *target_, int default_port, +@@ -648,7 +660,8 @@ exit: + * zeros '*ss' and returns false. */ + bool + inet_parse_passive(const char *target_, int default_port, +- struct sockaddr_storage *ss) ++ struct sockaddr_storage *ss, ++ bool resolve_host, bool *dns_failure) + { + char *target = xstrdup(target_); + char *port, *host; +@@ -660,7 +673,7 @@ inet_parse_passive(const char *target_, int default_port, ok = false; } else { ok = parse_sockaddr_components(ss, host, port, default_port, - target_, true); -+ target_, true, NULL); ++ target_, resolve_host, dns_failure); } if (!ok) { memset(ss, 0, sizeof *ss); -@@ -783,7 +795,8 @@ inet_parse_address(const char *target_, struct sockaddr_storage *ss) +@@ -698,8 +711,14 @@ inet_open_passive(int style, const char *target, int default_port, + struct sockaddr_storage ss; + int fd = 0, error; + unsigned int yes = 1; ++ bool dns_failure; + +- if (!inet_parse_passive(target, default_port, &ss)) { ++ if (!inet_parse_passive(target, default_port, &ss, true, &dns_failure)) { ++ if (dns_failure) { ++ /* DNS failure means asynchronous DNS resolution is in progress, ++ * or that the name does currently not resolve. */ ++ return -EAGAIN; ++ } + return -EAFNOSUPPORT; + } + kernel_chooses_port = ss_get_port(&ss) == 0; +@@ -783,7 +802,8 @@ inet_parse_address(const char *target_, struct sockaddr_storage *ss) { char *target = xstrdup(target_); char *host = unbracket(target); @@ -56150,10 +56471,10 @@ index 4f1ffecf5d..38705cc51e 100644 memset(ss, 0, sizeof *ss); } diff --git a/lib/socket-util.h b/lib/socket-util.h -index 9ccb7d4cc4..bf66393df9 100644 +index 9ccb7d4cc4..4eec627e3e 100644 --- a/lib/socket-util.h +++ b/lib/socket-util.h -@@ -49,7 +49,8 @@ ovs_be32 guess_netmask(ovs_be32 ip); +@@ -49,12 +49,14 @@ ovs_be32 guess_netmask(ovs_be32 ip); void inet_parse_host_port_tokens(char *s, char **hostp, char **portp); void inet_parse_port_host_tokens(char *s, char **portp, char **hostp); bool inet_parse_active(const char *target, int default_port, @@ -56163,6 +56484,13 @@ index 9ccb7d4cc4..bf66393df9 100644 int inet_open_active(int style, const char *target, int default_port, struct sockaddr_storage *ssp, int *fdp, uint8_t dscp); + bool inet_parse_passive(const char *target, int default_port, +- struct sockaddr_storage *ssp); ++ struct sockaddr_storage *ssp, ++ bool resolve_host, bool *dns_failure); + int inet_open_passive(int style, const char *target, int default_port, + struct sockaddr_storage *ssp, uint8_t dscp, + bool kernel_print_port); diff --git a/lib/sset.c b/lib/sset.c index b2e3f43ec9..6fbaa9d60d 100644 --- a/lib/sset.c @@ -56324,7 +56652,7 @@ index fcaddf10ad..71039e24f1 100644 /* Attempts to guess the content type of a stream whose first few bytes were diff --git a/lib/tc.c b/lib/tc.c -index adb2d3182a..485e4834f8 100644 +index adb2d3182a..7298ce6901 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -84,6 +84,11 @@ struct flower_key_to_pedit { @@ -56526,7 +56854,32 @@ index adb2d3182a..485e4834f8 100644 action->type = TC_ACT_PEDIT; return 0; -@@ -1314,8 +1343,8 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower) +@@ -1305,7 +1334,23 @@ get_user_hz(void) + static void + nl_parse_tcf(const struct tcf_t *tm, struct tc_flower *flower) + { +- flower->lastused = time_msec() - (tm->lastuse * 1000 / get_user_hz()); ++ uint64_t lastused; ++ ++ /* On creation both tm->install and tm->lastuse are set to jiffies ++ * by the kernel. So if both values are the same, the flow has not been ++ * used yet. ++ * ++ * Note that tm->firstuse can not be used due to some kernel bug, i.e., ++ * hardware offloaded flows do not update tm->firstuse. */ ++ if (tm->lastuse == tm->install) { ++ lastused = 0; ++ } else { ++ lastused = time_msec() - (tm->lastuse * 1000 / get_user_hz()); ++ } ++ ++ if (flower->lastused < lastused) { ++ flower->lastused = lastused; ++ } + } + + static int +@@ -1314,8 +1359,8 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower) struct nlattr *gact_attrs[ARRAY_SIZE(gact_policy)]; const struct tc_gact *p; struct nlattr *gact_parms; @@ -56536,7 +56889,7 @@ index adb2d3182a..485e4834f8 100644 if (!nl_parse_nested(options, gact_policy, gact_attrs, ARRAY_SIZE(gact_policy))) { -@@ -1335,8 +1364,9 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower) +@@ -1335,8 +1380,9 @@ nl_parse_act_gact(struct nlattr *options, struct tc_flower *flower) return EINVAL; } @@ -56548,7 +56901,7 @@ index adb2d3182a..485e4834f8 100644 return 0; } -@@ -1357,9 +1387,9 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower) +@@ -1357,9 +1403,9 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower) struct nlattr *mirred_attrs[ARRAY_SIZE(mirred_policy)]; const struct tc_mirred *m; const struct nlattr *mirred_parms; @@ -56559,7 +56912,7 @@ index adb2d3182a..485e4834f8 100644 if (!nl_parse_nested(options, mirred_policy, mirred_attrs, ARRAY_SIZE(mirred_policy))) { -@@ -1387,8 +1417,8 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower) +@@ -1387,8 +1433,8 @@ nl_parse_act_mirred(struct nlattr *options, struct tc_flower *flower) action->type = TC_ACT_OUTPUT; mirred_tm = mirred_attrs[TCA_MIRRED_TM]; @@ -56570,7 +56923,7 @@ index adb2d3182a..485e4834f8 100644 return 0; } -@@ -1487,7 +1517,9 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower) +@@ -1487,7 +1533,9 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower) if (ipv4_max) { ovs_be32 addr = nl_attr_get_be32(ipv4_max); @@ -56581,7 +56934,7 @@ index adb2d3182a..485e4834f8 100644 } } else if (ipv6_min) { action->ct.range.ip_family = AF_INET6; -@@ -1496,7 +1528,9 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower) +@@ -1496,7 +1544,9 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower) if (ipv6_max) { struct in6_addr addr = nl_attr_get_in6_addr(ipv6_max); @@ -56592,7 +56945,7 @@ index adb2d3182a..485e4834f8 100644 } } -@@ -1504,6 +1538,10 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower) +@@ -1504,6 +1554,10 @@ nl_parse_act_ct(struct nlattr *options, struct tc_flower *flower) action->ct.range.port.min = nl_attr_get_be16(port_min); if (port_max) { action->ct.range.port.max = nl_attr_get_be16(port_max); @@ -56603,7 +56956,7 @@ index adb2d3182a..485e4834f8 100644 } } } -@@ -1698,24 +1736,89 @@ static const struct nl_policy act_policy[] = { +@@ -1698,24 +1752,89 @@ static const struct nl_policy act_policy[] = { [TCA_ACT_STATS] = { .type = NL_A_NESTED, .optional = false, }, }; @@ -56702,7 +57055,7 @@ index adb2d3182a..485e4834f8 100644 int err = 0; if (!nl_parse_nested(action, act_policy, action_attrs, -@@ -1763,21 +1866,8 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, +@@ -1763,21 +1882,8 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, flower->act_cookie.len = nl_attr_get_size(act_cookie); } @@ -56726,7 +57079,7 @@ index adb2d3182a..485e4834f8 100644 } #define TCA_ACT_MIN_PRIO 1 -@@ -1964,14 +2054,21 @@ tc_dump_tc_chain_start(struct tcf_id *id, struct nl_dump *dump) +@@ -1964,14 +2070,21 @@ tc_dump_tc_chain_start(struct tcf_id *id, struct nl_dump *dump) } int @@ -56749,7 +57102,7 @@ index adb2d3182a..485e4834f8 100644 int tc_get_flower(struct tcf_id *id, struct tc_flower *flower) { -@@ -1980,6 +2077,7 @@ tc_get_flower(struct tcf_id *id, struct tc_flower *flower) +@@ -1980,6 +2093,7 @@ tc_get_flower(struct tcf_id *id, struct tc_flower *flower) int error; request_from_tcf_id(id, 0, RTM_GETTFILTER, NLM_F_ECHO, &request); @@ -56757,7 +57110,7 @@ index adb2d3182a..485e4834f8 100644 error = tc_transact(&request, &reply); if (error) { return error; -@@ -2399,14 +2497,14 @@ nl_msg_put_act_flags(struct ofpbuf *request) { +@@ -2399,14 +2513,14 @@ nl_msg_put_act_flags(struct ofpbuf *request) { * first_word_mask/last_word_mask - the mask to use for the first/last read * (as we read entire words). */ static void @@ -56775,7 +57128,7 @@ index adb2d3182a..485e4834f8 100644 max_offset = m->offset + m->size; start_offset = ROUND_DOWN(m->offset, 4); -@@ -2473,7 +2571,8 @@ csum_update_flag(struct tc_flower *flower, +@@ -2473,7 +2587,8 @@ csum_update_flag(struct tc_flower *flower, static int nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, @@ -56785,7 +57138,7 @@ index adb2d3182a..485e4834f8 100644 { struct { struct tc_pedit sel; -@@ -2497,12 +2596,12 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, +@@ -2497,12 +2612,12 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request, continue; } @@ -56801,7 +57154,7 @@ index adb2d3182a..485e4834f8 100644 if (j == 0) { mask_word &= first_word_mask; -@@ -2556,6 +2655,29 @@ nl_msg_put_flower_acts_release(struct ofpbuf *request, uint16_t act_index) +@@ -2556,6 +2671,29 @@ nl_msg_put_flower_acts_release(struct ofpbuf *request, uint16_t act_index) nl_msg_end_nested(request, act_offset); } @@ -56831,7 +57184,7 @@ index adb2d3182a..485e4834f8 100644 static int nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) { -@@ -2572,20 +2694,22 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) +@@ -2572,20 +2710,22 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) action = flower->actions; for (i = 0; i < flower->action_count; i++, action++) { @@ -56860,7 +57213,7 @@ index adb2d3182a..485e4834f8 100644 } } break; -@@ -2792,13 +2916,16 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) +@@ -2792,13 +2932,16 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) struct in6_addr *ipv6_dst_mask = &flower->mask.tunnel.ipv6.ipv6_dst; struct in6_addr *ipv6_src = &flower->key.tunnel.ipv6.ipv6_src; struct in6_addr *ipv6_dst = &flower->key.tunnel.ipv6.ipv6_dst; @@ -56878,7 +57231,7 @@ index adb2d3182a..485e4834f8 100644 if (ipv4_dst_mask || ipv4_src_mask) { nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, -@@ -2824,8 +2951,15 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) +@@ -2824,8 +2967,15 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) nl_msg_put_u8(request, TCA_FLOWER_KEY_ENC_IP_TTL, ttl); nl_msg_put_u8(request, TCA_FLOWER_KEY_ENC_IP_TTL_MASK, ttl_mask); } @@ -56895,7 +57248,7 @@ index adb2d3182a..485e4834f8 100644 } if (id_mask) { nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_KEY_ID, id); -@@ -2914,13 +3048,13 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) +@@ -2914,13 +3064,13 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) FLOWER_PUT_MASKED_VALUE(icmp_code, TCA_FLOWER_KEY_ICMPV6_CODE); FLOWER_PUT_MASKED_VALUE(icmp_type, TCA_FLOWER_KEY_ICMPV6_TYPE); } @@ -56914,7 +57267,7 @@ index adb2d3182a..485e4834f8 100644 if (host_eth_type == ETH_P_IP) { FLOWER_PUT_MASKED_VALUE(ipv4.ipv4_src, TCA_FLOWER_KEY_IPV4_SRC); FLOWER_PUT_MASKED_VALUE(ipv4.ipv4_dst, TCA_FLOWER_KEY_IPV4_DST); -@@ -2993,12 +3127,79 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) +@@ -2993,12 +3143,79 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) return 0; } @@ -56995,7 +57348,7 @@ index adb2d3182a..485e4834f8 100644 return false; } -@@ -3011,8 +3212,8 @@ cmp_tc_flower_match_action(const struct tc_flower *a, +@@ -3011,8 +3228,8 @@ cmp_tc_flower_match_action(const struct tc_flower *a, uint8_t key_b = ((uint8_t *)&b->key)[i] & mask; if (key_a != key_b) { @@ -57006,7 +57359,7 @@ index adb2d3182a..485e4834f8 100644 return false; } } -@@ -3022,14 +3223,15 @@ cmp_tc_flower_match_action(const struct tc_flower *a, +@@ -3022,14 +3239,15 @@ cmp_tc_flower_match_action(const struct tc_flower *a, const struct tc_action *action_b = b->actions; if (a->action_count != b->action_count) { @@ -57026,7 +57379,7 @@ index adb2d3182a..485e4834f8 100644 } } diff --git a/lib/tc.h b/lib/tc.h -index a147ca461d..55bed0853a 100644 +index a147ca461d..35068cbd89 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -256,11 +256,23 @@ struct tc_action { @@ -57053,7 +57406,15 @@ index a147ca461d..55bed0853a 100644 enum tc_offloaded_state { TC_OFFLOADED_STATE_UNDEFINED, TC_OFFLOADED_STATE_IN_HW, -@@ -330,15 +342,10 @@ struct tc_flower { +@@ -307,7 +319,6 @@ static inline bool + is_tcf_id_eq(struct tcf_id *id1, struct tcf_id *id2) + { + return id1->prio == id2->prio +- && id1->handle == id2->handle + && id1->handle == id2->handle + && id1->hook == id2->hook + && id1->block_id == id2->block_id +@@ -330,15 +341,10 @@ struct tc_flower { int action_count; struct tc_action actions[TCA_ACT_MAX_NUM]; @@ -57071,7 +57432,7 @@ index a147ca461d..55bed0853a 100644 uint32_t csum_update_flags; bool tunnel; -@@ -352,15 +359,9 @@ struct tc_flower { +@@ -352,15 +358,9 @@ struct tc_flower { enum tc_offload_policy tc_policy; }; @@ -57905,7 +58266,7 @@ index 78a54c715d..109940ad2a 100644 oftrace_node_destroy(node); } diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c -index 57f94df544..fe47090584 100644 +index 57f94df544..adb53f8031 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -362,6 +362,10 @@ static void upcall_unixctl_dump_wait(struct unixctl_conn *conn, int argc, @@ -57930,7 +58291,15 @@ index 57f94df544..fe47090584 100644 ovsthread_once_done(&once); } } -@@ -3099,6 +3107,31 @@ upcall_unixctl_purge(struct unixctl_conn *conn, int argc OVS_UNUSED, +@@ -1868,6 +1876,7 @@ try_ukey_replace(struct umap *umap, struct udpif_key *old_ukey, + ovs_mutex_lock(&new_ukey->mutex); + cmap_replace(&umap->cmap, &old_ukey->cmap_node, + &new_ukey->cmap_node, new_ukey->hash); ++ new_ukey->dump_seq = old_ukey->dump_seq; + ovsrcu_postpone(ukey_delete__, old_ukey); + transition_ukey(old_ukey, UKEY_DELETED); + transition_ukey(new_ukey, UKEY_VISIBLE); +@@ -3099,6 +3108,31 @@ upcall_unixctl_purge(struct unixctl_conn *conn, int argc OVS_UNUSED, unixctl_command_reply(conn, ""); } @@ -57999,7 +58368,7 @@ index 114aff8ea3..0fc6d2ea60 100644 enum xc_type type; union { diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c -index 578cbfe581..8a28b29d4c 100644 +index 578cbfe581..97614ec4d7 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -865,7 +865,7 @@ xlate_xbridge_init(struct xlate_cfg *xcfg, struct xbridge *xbridge) @@ -58321,7 +58690,7 @@ index 578cbfe581..8a28b29d4c 100644 /* If ofp_port in flow sample action is equel to ofp_port, * this sample action is a input port action. */ -@@ -7609,6 +7676,10 @@ xlate_wc_finish(struct xlate_ctx *ctx) +@@ -7609,6 +7676,43 @@ xlate_wc_finish(struct xlate_ctx *ctx) ctx->wc->masks.vlans[i].tci = 0; } } @@ -58329,10 +58698,43 @@ index 578cbfe581..8a28b29d4c 100644 + if (!flow_tnl_dst_is_set(&ctx->xin->upcall_flow->tunnel)) { + memset(&ctx->wc->masks.tunnel, 0, sizeof ctx->wc->masks.tunnel); + } ++} ++ ++/* This will optimize the odp actions generated. For now, it will remove ++ * trailing clone actions that are unnecessary. */ ++static void ++xlate_optimize_odp_actions(struct xlate_in *xin) ++{ ++ struct ofpbuf *actions = xin->odp_actions; ++ struct nlattr *last_action = NULL; ++ struct nlattr *a; ++ int left; ++ ++ if (!actions) { ++ return; ++ } ++ ++ /* Find the last action in the set. */ ++ NL_ATTR_FOR_EACH (a, left, actions->data, actions->size) { ++ last_action = a; ++ } ++ ++ /* Remove the trailing clone() action, by directly embedding the nested ++ * actions. */ ++ if (last_action && nl_attr_type(last_action) == OVS_ACTION_ATTR_CLONE) { ++ void *dest; ++ ++ nl_msg_reset_size(actions, ++ (unsigned char *) last_action - ++ (unsigned char *) actions->data); ++ ++ dest = nl_msg_put_uninit(actions, nl_attr_get_size(last_action)); ++ memmove(dest, nl_attr_get(last_action), nl_attr_get_size(last_action)); ++ } } /* Translates the flow, actions, or rule in 'xin' into datapath actions in -@@ -7784,6 +7855,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) +@@ -7784,6 +7888,12 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) goto exit; } @@ -58345,6 +58747,17 @@ index 578cbfe581..8a28b29d4c 100644 /* Tunnel metadata in udpif format must be normalized before translation. */ if (flow->tunnel.flags & FLOW_TNL_F_UDPIF) { const struct tun_table *tun_tab = ofproto_get_tun_tab( +@@ -8030,6 +8140,10 @@ exit: + if (xin->odp_actions) { + ofpbuf_clear(xin->odp_actions); + } ++ } else { ++ /* In the non-error case, see if we can further optimize the datapath ++ * rules by removing redundant (clone) actions. */ ++ xlate_optimize_odp_actions(xin); + } + + /* Install drop action if datapath supports explicit drop action. */ diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h index 851088d794..2ba90e999c 100644 --- a/ofproto/ofproto-dpif-xlate.h @@ -58965,7 +59378,7 @@ index 9f44007d97..ca80c28235 100644 break; } diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c -index 351c39d8aa..916a1f414e 100644 +index 351c39d8aa..17868f5b72 100644 --- a/ovsdb/jsonrpc-server.c +++ b/ovsdb/jsonrpc-server.c @@ -197,9 +197,9 @@ ovsdb_jsonrpc_server_remove_db(struct ovsdb_jsonrpc_server *svr, @@ -58992,7 +59405,60 @@ index 351c39d8aa..916a1f414e 100644 struct ovsdb_jsonrpc_remote *remote = node->data; struct ovsdb_jsonrpc_options *options = shash_find_data(new_remotes, node->name); -@@ -585,9 +585,9 @@ ovsdb_jsonrpc_session_set_options(struct ovsdb_jsonrpc_session *session, +@@ -267,25 +267,36 @@ ovsdb_jsonrpc_server_add_remote(struct ovsdb_jsonrpc_server *svr, + int error; + + error = jsonrpc_pstream_open(name, &listener, options->dscp); +- if (error && error != EAFNOSUPPORT) { +- VLOG_ERR_RL(&rl, "%s: listen failed: %s", name, ovs_strerror(error)); +- return NULL; +- } ++ switch (error) { ++ case 0: ++ case EAFNOSUPPORT: ++ remote = xmalloc(sizeof *remote); ++ remote->server = svr; ++ remote->listener = listener; ++ ovs_list_init(&remote->sessions); ++ remote->dscp = options->dscp; ++ remote->read_only = options->read_only; ++ remote->role = nullable_xstrdup(options->role); ++ shash_add(&svr->remotes, name, remote); ++ if (!listener) { ++ /* Not a listener, attempt creation of active jsonrpc session. */ ++ ovsdb_jsonrpc_session_create(remote, ++ jsonrpc_session_open(name, true), ++ svr->read_only || remote->read_only); ++ } ++ return remote; + +- remote = xmalloc(sizeof *remote); +- remote->server = svr; +- remote->listener = listener; +- ovs_list_init(&remote->sessions); +- remote->dscp = options->dscp; +- remote->read_only = options->read_only; +- remote->role = nullable_xstrdup(options->role); +- shash_add(&svr->remotes, name, remote); ++ case EAGAIN: ++ VLOG_DBG_RL(&rl, "%s: listen failed: " ++ "DNS resolution in progress or host not found", name); ++ return NULL; + +- if (!listener) { +- ovsdb_jsonrpc_session_create(remote, jsonrpc_session_open(name, true), +- svr->read_only || remote->read_only); ++ default: ++ VLOG_ERR_RL(&rl, "%s: listen failed: %s", name, ++ ovs_strerror(error)); ++ return NULL; + } +- return remote; ++ OVS_NOT_REACHED(); + } + + static void +@@ -585,9 +596,9 @@ ovsdb_jsonrpc_session_set_options(struct ovsdb_jsonrpc_session *session, static void ovsdb_jsonrpc_session_run_all(struct ovsdb_jsonrpc_remote *remote) { @@ -59004,7 +59470,7 @@ index 351c39d8aa..916a1f414e 100644 int error = ovsdb_jsonrpc_session_run(s); if (error) { ovsdb_jsonrpc_session_close(s); -@@ -642,9 +642,9 @@ ovsdb_jsonrpc_session_get_memory_usage_all( +@@ -642,9 +653,9 @@ ovsdb_jsonrpc_session_get_memory_usage_all( static void ovsdb_jsonrpc_session_close_all(struct ovsdb_jsonrpc_remote *remote) { @@ -59016,7 +59482,7 @@ index 351c39d8aa..916a1f414e 100644 ovsdb_jsonrpc_session_close(s); } } -@@ -660,9 +660,9 @@ static void +@@ -660,9 +671,9 @@ static void ovsdb_jsonrpc_session_reconnect_all(struct ovsdb_jsonrpc_remote *remote, bool force, const char *comment) { @@ -59028,7 +59494,7 @@ index 351c39d8aa..916a1f414e 100644 if (force || !s->db_change_aware) { jsonrpc_session_force_reconnect(s->js); if (comment && jsonrpc_session_is_connected(s->js)) { -@@ -909,9 +909,9 @@ error: +@@ -909,9 +920,9 @@ error: static void ovsdb_jsonrpc_session_unlock_all(struct ovsdb_jsonrpc_session *s) { @@ -59040,7 +59506,7 @@ index 351c39d8aa..916a1f414e 100644 ovsdb_jsonrpc_session_unlock__(waiter); } } -@@ -1198,8 +1198,8 @@ static void +@@ -1198,8 +1209,8 @@ static void ovsdb_jsonrpc_trigger_remove__(struct ovsdb_jsonrpc_session *s, struct ovsdb *db) { @@ -59051,7 +59517,7 @@ index 351c39d8aa..916a1f414e 100644 if (!db || t->trigger.db == db) { ovsdb_jsonrpc_trigger_complete(t); } -@@ -1226,8 +1226,8 @@ ovsdb_jsonrpc_trigger_complete_all(struct ovsdb_jsonrpc_session *s) +@@ -1226,8 +1237,8 @@ ovsdb_jsonrpc_trigger_complete_all(struct ovsdb_jsonrpc_session *s) static void ovsdb_jsonrpc_trigger_complete_done(struct ovsdb_jsonrpc_session *s) { @@ -59062,7 +59528,7 @@ index 351c39d8aa..916a1f414e 100644 ovsdb_jsonrpc_trigger_complete(trigger); } } -@@ -1688,8 +1688,8 @@ ovsdb_jsonrpc_monitor_preremove_db(struct ovsdb_jsonrpc_session *s, +@@ -1688,8 +1699,8 @@ ovsdb_jsonrpc_monitor_preremove_db(struct ovsdb_jsonrpc_session *s, { ovs_assert(db); @@ -59073,7 +59539,7 @@ index 351c39d8aa..916a1f414e 100644 if (m->db == db) { ovsdb_jsonrpc_monitor_destroy(m, true); } -@@ -1700,9 +1700,9 @@ ovsdb_jsonrpc_monitor_preremove_db(struct ovsdb_jsonrpc_session *s, +@@ -1700,9 +1711,9 @@ ovsdb_jsonrpc_monitor_preremove_db(struct ovsdb_jsonrpc_session *s, static void ovsdb_jsonrpc_monitor_remove_all(struct ovsdb_jsonrpc_session *s) { @@ -61922,7 +62388,7 @@ index 757cf7186e..fe475e7b38 100644 + +AT_CLEANUP diff --git a/tests/nsh.at b/tests/nsh.at -index 4d49f12017..91ded1445d 100644 +index 4d49f12017..6b7b6856f2 100644 --- a/tests/nsh.at +++ b/tests/nsh.at @@ -27,7 +27,7 @@ AT_CHECK([ @@ -62015,6 +62481,26 @@ index 4d49f12017..91ded1445d 100644 bridge("br0") ------------- +@@ -724,7 +724,7 @@ ovs-appctl time/warp 1000 + AT_CHECK([ + ovs-appctl dpctl/dump-flows dummy@ovs-dummy | strip_used | grep -v ipv6 | sort + ], [0], [flow-dump from the main thread: +-recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.30,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,push_nsh(flags=0,ttl=63,mdtype=1,np=1,spi=0x3000,si=255,c1=0x0,c2=0x0,c3=0x0,c4=0x0),clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.3,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(1)),set(ipv4(src=30.0.0.1,dst=30.0.0.3)),tnl_pop(4789)) ++recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.30,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,push_nsh(flags=0,ttl=63,mdtype=1,np=1,spi=0x3000,si=255,c1=0x0,c2=0x0,c3=0x0,c4=0x0),tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.3,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(1)),set(ipv4(src=30.0.0.1,dst=30.0.0.3)),tnl_pop(4789) + tunnel(tun_id=0x0,src=30.0.0.1,dst=30.0.0.3,flags(-df-csum+key)),recirc_id(0),in_port(4789),packet_type(ns=1,id=0x894f),eth_type(0x894f),nsh(np=1,spi=0x3000,si=255), packets:1, bytes:108, used:0.0s, actions:pop_nsh(),recirc(0x1) + tunnel(tun_id=0x0,src=30.0.0.1,dst=30.0.0.3,flags(-df-csum+key)),recirc_id(0x1),in_port(4789),packet_type(ns=1,id=0x800),eth_type(0x0800),ipv4(frag=no), packets:1, bytes:84, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=aa:55:aa:55:00:03),6 + ]) +@@ -778,8 +778,8 @@ ovs-appctl time/warp 1000 + AT_CHECK([ + ovs-appctl dpctl/dump-flows dummy@ovs-dummy | strip_used | grep -v ipv6 | sort + ], [0], [flow-dump from the main thread: +-recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.20/255.255.255.248,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,push_nsh(flags=0,ttl=63,mdtype=1,np=1,spi=0x3020,si=255,c1=0x0,c2=0x0,c3=0x0,c4=0x0),clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(1)),set(ipv4(src=20.0.0.1,dst=20.0.0.2)),tnl_pop(4789)) +-tunnel(tun_id=0x0,src=20.0.0.1,dst=20.0.0.2,flags(-df-csum+key)),recirc_id(0),in_port(4789),packet_type(ns=1,id=0x894f),eth_type(0x894f),nsh(spi=0x3020,si=255), packets:1, bytes:108, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=11:22:33:44:55:66),set(nsh(spi=0x3020,si=254)),pop_eth,clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=20.0.0.2,dst=20.0.0.3,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(2)),set(ipv4(src=30.0.0.2,dst=30.0.0.3)),tnl_pop(4789)) ++recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.20/255.255.255.248,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,push_nsh(flags=0,ttl=63,mdtype=1,np=1,spi=0x3020,si=255,c1=0x0,c2=0x0,c3=0x0,c4=0x0),tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(1)),set(ipv4(src=20.0.0.1,dst=20.0.0.2)),tnl_pop(4789) ++tunnel(tun_id=0x0,src=20.0.0.1,dst=20.0.0.2,flags(-df-csum+key)),recirc_id(0),in_port(4789),packet_type(ns=1,id=0x894f),eth_type(0x894f),nsh(spi=0x3020,si=255), packets:1, bytes:108, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=11:22:33:44:55:66),set(nsh(spi=0x3020,si=254)),pop_eth,tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=20.0.0.2,dst=20.0.0.3,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(2)),set(ipv4(src=30.0.0.2,dst=30.0.0.3)),tnl_pop(4789) + tunnel(tun_id=0x0,src=30.0.0.2,dst=30.0.0.3,flags(-df-csum+key)),recirc_id(0),in_port(4789),packet_type(ns=1,id=0x894f),eth_type(0x894f),nsh(np=1,spi=0x3020,si=254), packets:1, bytes:108, used:0.0s, actions:pop_nsh(),recirc(0x2) + tunnel(tun_id=0x0,src=30.0.0.2,dst=30.0.0.3,flags(-df-csum+key)),recirc_id(0x2),in_port(4789),packet_type(ns=1,id=0x800),eth_type(0x0800),ipv4(frag=no), packets:1, bytes:84, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=aa:55:aa:55:00:03),6 + ]) diff --git a/tests/odp.at b/tests/odp.at index 4d08c59ca6..fce6a4f2bc 100644 --- a/tests/odp.at @@ -62133,7 +62619,7 @@ index 2c7e163bd6..7be6628c34 100644 AT_CLEANUP diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at -index 7c2edeb9d4..bc981f8fc6 100644 +index 7c2edeb9d4..cc5340f376 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -29,6 +29,58 @@ AT_CHECK([ovs-appctl revalidator/wait]) @@ -63503,7 +63989,48 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) OVS_VSWITCHD_STOP(["/stack underflow/d"]) -@@ -9855,7 +10054,7 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) +@@ -8717,6 +8916,40 @@ AT_CHECK([tail -1 stdout], [0], + OVS_VSWITCHD_STOP + AT_CLEANUP + ++AT_SETUP([ofproto-dpif - patch ports - no additional clone]) ++OVS_VSWITCHD_START( ++ [add-port br0 p0 -- set Interface p0 type=dummy ofport_request=1 -- dnl ++ add-port br0 p1 -- set Interface p1 type=patch dnl ++ options:peer=p2 ofport_request=2 -- dnl ++ add-br br1 -- dnl ++ set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- dnl ++ set bridge br1 datapath-type=dummy other-config:datapath-id=1234 dnl ++ fail-mode=secure -- dnl ++ add-port br1 p2 -- set Interface p2 type=patch dnl ++ options:peer=p1 -- dnl ++ add-port br1 p3 -- set Interface p3 type=dummy ofport_request=3]) ++ ++AT_DATA([flows-br0.txt], [dnl ++priority=10,tcp,action=push:NXM_OF_IN_PORT[],resubmit(,65),pop:NXM_OF_IN_PORT[] ++table=65,priority=10,ip,in_port=p0,action=p1 ++]) ++ ++AT_DATA([flows-br1.txt], [dnl ++priority=100,in_port=p2,tcp,ct_state=-trk,action=ct(table=0,zone=1) ++priority=100,in_port=p2,tcp,ct_state=+trk+est,ct_zone=1,action=p3 ++]) ++ ++AT_CHECK([ovs-ofctl --bundle add-flows br0 flows-br0.txt]) ++AT_CHECK([ovs-ofctl --bundle add-flows br1 flows-br1.txt]) ++ ++AT_CHECK([ovs-appctl ofproto/trace br0 in_port=p0,tcp --ct-next 'trk,est' | dnl ++ grep "Datapath actions:" | grep -q clone], ++ [1], [], [], ++ [ovs-appctl ofproto/trace br0 in_port=p0,tcp --ct-next 'trk,est']) ++ ++OVS_TRAFFIC_VSWITCHD_STOP ++AT_CLEANUP ++ + dnl ---------------------------------------------------------------------- + AT_BANNER([ofproto-dpif -- megaflows]) + +@@ -9855,7 +10088,7 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=86 in_port=1 (via no_match) data_len=86 (unbuffered) @@ -63512,7 +64039,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) OVS_VSWITCHD_STOP -@@ -9906,7 +10105,7 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) +@@ -9906,7 +10139,7 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=86 in_port=1 (via action) data_len=86 (unbuffered) @@ -63521,7 +64048,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) OVS_VSWITCHD_STOP -@@ -10166,10 +10365,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10166,10 +10399,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=6 cookie=0x0 total_len=106 reg0=0x1,reg1=0x4d2,reg2=0x1,reg3=0x1,reg4=0x1,in_port=1 (via action) data_len=106 (unbuffered) @@ -63534,7 +64061,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl -P nxt_packet_in --detach --no-chdir --pidfile 2> ofctl_monitor.log]) -@@ -10187,10 +10386,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10187,10 +10420,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. We should see both packets AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=6 cookie=0x0 total_len=106 reg0=0x1,reg1=0x4d2,reg2=0x1,reg3=0x1,reg4=0x1,in_port=1 (via action) data_len=106 (unbuffered) @@ -63547,7 +64074,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) OVS_VSWITCHD_STOP -@@ -10239,10 +10438,10 @@ dnl Note that the first packet doesn't have the ct_state bits set. This +@@ -10239,10 +10472,10 @@ dnl Note that the first packet doesn't have the ct_state bits set. This dnl happens because the ct_state field is available only after recirc. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered) @@ -63560,7 +64087,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl -P nxt_packet_in --detach --no-chdir --pidfile 2> ofctl_monitor.log]) -@@ -10261,10 +10460,10 @@ dnl Note that the first packet doesn't have the ct_state bits set. This +@@ -10261,10 +10494,10 @@ dnl Note that the first packet doesn't have the ct_state bits set. This dnl happens because the ct_state field is available only after recirc. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered) @@ -63573,7 +64100,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) dnl -@@ -10320,9 +10519,9 @@ dnl Note that the first packet doesn't have the ct_state bits set. This +@@ -10320,9 +10553,9 @@ dnl Note that the first packet doesn't have the ct_state bits set. This dnl happens because the ct_state field is available only after recirc. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=126 in_port=1 (via action) data_len=126 (unbuffered) @@ -63585,7 +64112,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) OVS_VSWITCHD_STOP -@@ -10433,7 +10632,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10433,7 +10666,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. Only one reply must be there AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 ct_state=est|rpl|trk,ct_nw_src=10.1.1.1,ct_nw_dst=10.1.1.2,ct_nw_proto=17,ct_tp_src=1,ct_tp_dst=2,ip,in_port=2 (via action) data_len=106 (unbuffered) @@ -63594,7 +64121,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 dnl OFPT_ECHO_REQUEST (xid=0x0): 0 bytes of payload ]) -@@ -10467,7 +10666,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10467,7 +10700,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=86 ct_state=inv|trk,ipv6,in_port=2 (via action) data_len=86 (unbuffered) @@ -63603,7 +64130,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) OVS_VSWITCHD_STOP -@@ -10523,16 +10722,16 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10523,16 +10756,16 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. We only see the latter two packets (for each zone), not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered) @@ -63624,7 +64151,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) OVS_VSWITCHD_STOP -@@ -10579,10 +10778,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10579,10 +10812,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered) @@ -63637,7 +64164,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) OVS_VSWITCHD_STOP -@@ -10629,10 +10828,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10629,10 +10862,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. We only see the first and the last packet AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=47 ct_state=new|trk,ct_nw_src=172.16.0.1,ct_nw_dst=172.16.0.2,ct_nw_proto=17,ct_tp_src=41614,ct_tp_dst=5555,ip,in_port=1 (via action) data_len=47 (unbuffered) @@ -63650,7 +64177,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) OVS_VSWITCHD_STOP -@@ -10681,19 +10880,19 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10681,19 +10914,19 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered) @@ -63675,7 +64202,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) OVS_VSWITCHD_STOP -@@ -10738,10 +10937,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -10738,10 +10971,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 ct_state=est|rpl|trk,ct_label=0x1,ct_nw_src=10.1.1.1,ct_nw_dst=10.1.1.2,ct_nw_proto=17,ct_tp_src=1,ct_tp_dst=2,ip,in_port=2 (via action) data_len=106 (unbuffered) @@ -63688,7 +64215,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) OVS_VSWITCHD_STOP -@@ -11152,16 +11351,16 @@ dnl Note that the first packet doesn't have the ct_state bits set. This +@@ -11152,16 +11385,16 @@ dnl Note that the first packet doesn't have the ct_state bits set. This dnl happens because the ct_state field is available only after recirc. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=106 in_port=1 (via action) data_len=106 (unbuffered) @@ -63709,7 +64236,7 @@ index 7c2edeb9d4..bc981f8fc6 100644 ]) dnl The next test verifies that ct_clear at the datapath only gets executed -@@ -11235,13 +11434,13 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) +@@ -11235,13 +11468,13 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit]) dnl Check this output. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=106 ct_state=est|rpl|trk,ct_nw_src=10.1.2.100,ct_nw_dst=10.1.2.200,ct_nw_proto=17,ct_tp_src=6,ct_tp_dst=6,ip,in_port=2 (via action) data_len=106 (unbuffered) @@ -64928,6 +65455,105 @@ index 876cb836cd..4a183bf186 100644 --remote=ptcp:0:127.0.0.1 dnl db.tmp], [0], [stdout], [stderr]) PARSE_LISTENING_PORT([listener.log], [BAD_TCP_PORT]) +diff --git a/tests/packet-type-aware.at b/tests/packet-type-aware.at +index 054dcc9ccf..3b5c66fe52 100644 +--- a/tests/packet-type-aware.at ++++ b/tests/packet-type-aware.at +@@ -326,7 +326,7 @@ ovs-appctl time/warp 1000 + AT_CHECK([ + ovs-appctl dpctl/dump-flows --names dummy@ovs-dummy | strip_used | grep -v ipv6 | sort + ], [0], [flow-dump from the main thread: +-recirc_id(0),in_port(n1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.30,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.3,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(br-p1)),set(ipv4(src=30.0.0.1,dst=30.0.0.3)),tnl_pop(gre_sys)) ++recirc_id(0),in_port(n1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.30,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.3,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(br-p1)),set(ipv4(src=30.0.0.1,dst=30.0.0.3)),tnl_pop(gre_sys) + tunnel(src=30.0.0.1,dst=30.0.0.3,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=0,id=0),eth(dst=1e:2c:e9:2a:66:9e),eth_type(0x0800),ipv4(dst=192.168.10.30,frag=no), packets:1, bytes:98, used:0.0s, actions:set(eth(dst=aa:55:aa:55:00:03)),n3 + ]) + +@@ -344,7 +344,7 @@ ovs-appctl time/warp 1000 + AT_CHECK([ + ovs-appctl dpctl/dump-flows --names dummy@ovs-dummy | strip_used | grep -v ipv6 | sort + ], [0], [flow-dump from the main thread: +-recirc_id(0),in_port(n1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.20,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(br-p1)),set(ipv4(src=20.0.0.1,dst=20.0.0.2)),tnl_pop(gre_sys)) ++recirc_id(0),in_port(n1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.20,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(br-p1)),set(ipv4(src=20.0.0.1,dst=20.0.0.2)),tnl_pop(gre_sys) + tunnel(src=20.0.0.1,dst=20.0.0.2,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=0,id=0),eth(dst=46:1e:7d:1a:95:a1),eth_type(0x0800),ipv4(dst=192.168.10.20,frag=no), packets:1, bytes:98, used:0.0s, actions:set(eth(dst=aa:55:aa:55:00:02)),n2 + ]) + +@@ -362,7 +362,7 @@ ovs-appctl time/warp 1000 + AT_CHECK([ + ovs-appctl dpctl/dump-flows --names dummy@ovs-dummy | strip_used | grep -v ipv6 | sort + ], [0], [flow-dump from the main thread: +-recirc_id(0),in_port(n2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.10,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:01,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=20.0.0.2,dst=20.0.0.1,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(br-p2)),set(ipv4(src=10.0.0.2,dst=10.0.0.1)),tnl_pop(gre_sys)) ++recirc_id(0),in_port(n2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.10,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:01,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=20.0.0.2,dst=20.0.0.1,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(br-p2)),set(ipv4(src=10.0.0.2,dst=10.0.0.1)),tnl_pop(gre_sys) + tunnel(src=10.0.0.2,dst=10.0.0.1,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=0,id=0),eth(dst=3a:6d:d2:09:9c:ab),eth_type(0x0800),ipv4(dst=192.168.10.10,frag=no), packets:1, bytes:98, used:0.0s, actions:set(eth(dst=aa:55:aa:55:00:01)),n1 + ]) + +@@ -380,8 +380,8 @@ ovs-appctl time/warp 1000 + AT_CHECK([ + ovs-appctl dpctl/dump-flows --names dummy@ovs-dummy | strip_used | grep -v ipv6 | sort + ], [0], [flow-dump from the main thread: +-recirc_id(0),in_port(n2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.30,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:01,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=20.0.0.2,dst=20.0.0.1,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(br-p2)),set(ipv4(src=10.0.0.2,dst=10.0.0.1)),tnl_pop(gre_sys)) +-tunnel(src=10.0.0.2,dst=10.0.0.1,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.30,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.3,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(br-p1)),set(ipv4(src=30.0.0.1,dst=30.0.0.3)),tnl_pop(gre_sys)) ++recirc_id(0),in_port(n2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.30,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:01,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=20.0.0.2,dst=20.0.0.1,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(br-p2)),set(ipv4(src=10.0.0.2,dst=10.0.0.1)),tnl_pop(gre_sys) ++tunnel(src=10.0.0.2,dst=10.0.0.1,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.30,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.3,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(br-p1)),set(ipv4(src=30.0.0.1,dst=30.0.0.3)),tnl_pop(gre_sys) + tunnel(src=30.0.0.1,dst=30.0.0.3,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=0,id=0),eth(dst=1e:2c:e9:2a:66:9e),eth_type(0x0800),ipv4(dst=192.168.10.30,frag=no), packets:1, bytes:98, used:0.0s, actions:set(eth(dst=aa:55:aa:55:00:03)),n3 + ]) + +@@ -399,9 +399,9 @@ ovs-appctl time/warp 1000 + AT_CHECK([ + ovs-appctl dpctl/dump-flows --names dummy@ovs-dummy | strip_used | grep -v ipv6 | sort + ], [0], [flow-dump from the main thread: +-recirc_id(0),in_port(n3),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.10,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:03,dl_type=0x0800),ipv4(src=30.0.0.3,dst=30.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br-p3)),set(ipv4(src=20.0.0.3,dst=20.0.0.2)),tnl_pop(gre_sys)) ++recirc_id(0),in_port(n3),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.10,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:03,dl_type=0x0800),ipv4(src=30.0.0.3,dst=30.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br-p3)),set(ipv4(src=20.0.0.3,dst=20.0.0.2)),tnl_pop(gre_sys) + tunnel(src=10.0.0.2,dst=10.0.0.1,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=1,id=0x800),eth_type(0x0800),ipv4(dst=192.168.10.10,frag=no), packets:1, bytes:84, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=aa:55:aa:55:00:01),n1 +-tunnel(src=20.0.0.3,dst=20.0.0.2,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=1,id=0x800),eth_type(0x0800),ipv4(dst=192.168.10.10,tos=0/0x3,frag=no), packets:1, bytes:84, used:0.0s, actions:clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:01,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=20.0.0.2,dst=20.0.0.1,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br-p2)),set(ipv4(src=10.0.0.2,dst=10.0.0.1)),tnl_pop(gre_sys)) ++tunnel(src=20.0.0.3,dst=20.0.0.2,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=1,id=0x800),eth_type(0x0800),ipv4(dst=192.168.10.10,tos=0/0x3,frag=no), packets:1, bytes:84, used:0.0s, actions:tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:01,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=20.0.0.2,dst=20.0.0.1,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br-p2)),set(ipv4(src=10.0.0.2,dst=10.0.0.1)),tnl_pop(gre_sys) + ]) + + # Clear up megaflow cache +@@ -418,7 +418,7 @@ ovs-appctl time/warp 1000 + AT_CHECK([ + ovs-appctl dpctl/dump-flows --names dummy@ovs-dummy | strip_used | grep -v ipv6 | sort + ], [0], [flow-dump from the main thread: +-recirc_id(0),in_port(n3),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.20,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:03,dl_type=0x0800),ipv4(src=30.0.0.3,dst=30.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(br-p3)),set(ipv4(src=20.0.0.3,dst=20.0.0.2)),tnl_pop(gre_sys)) ++recirc_id(0),in_port(n3),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.20,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:03,dl_type=0x0800),ipv4(src=30.0.0.3,dst=30.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(br-p3)),set(ipv4(src=20.0.0.3,dst=20.0.0.2)),tnl_pop(gre_sys) + tunnel(src=20.0.0.3,dst=20.0.0.2,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=0,id=0),eth(dst=46:1e:7d:1a:95:a1),eth_type(0x0800),ipv4(dst=192.168.10.20,frag=no), packets:1, bytes:98, used:0.0s, actions:set(eth(dst=aa:55:aa:55:00:02)),n2 + ]) + +@@ -504,7 +504,7 @@ ovs-appctl time/warp 1000 + AT_CHECK([ + ovs-appctl dpctl/dump-flows --names dummy@ovs-dummy | strip_used | grep -v ipv6 | sort + ], [0], [flow-dump from the main thread: +-recirc_id(0),in_port(n3),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.20,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:03,dl_type=0x0800),ipv4(src=30.0.0.3,dst=30.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br-p3)),set(ipv4(src=20.0.0.3,dst=20.0.0.2)),tnl_pop(gre_sys)) ++recirc_id(0),in_port(n3),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.20,tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:03,dl_type=0x0800),ipv4(src=30.0.0.3,dst=30.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br-p3)),set(ipv4(src=20.0.0.3,dst=20.0.0.2)),tnl_pop(gre_sys) + tunnel(src=20.0.0.3,dst=20.0.0.2,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=1,id=0x800),eth_type(0x0800),ipv4(dst=192.168.10.20,frag=no), packets:1, bytes:84, used:0.0s, actions:drop + ]) + +@@ -726,7 +726,7 @@ ovs-appctl time/warp 1000 + AT_CHECK([ + ovs-appctl dpctl/dump-flows --names dummy@ovs-dummy | strip_used | grep -v ipv6 | sort + ], [0], [flow-dump from the main thread: +-recirc_id(0),in_port(n0),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=de:af:be:ef:ba:be,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br2)),n2) ++recirc_id(0),in_port(n0),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=de:af:be:ef:ba:be,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br2)),n2 + ]) + + AT_CHECK([ +@@ -814,7 +814,7 @@ ovs-appctl time/warp 1000 + AT_CHECK([ + ovs-appctl dpctl/dump-flows --names dummy@ovs-dummy | strip_used | grep -v ipv6 | sort + ], [0], [flow-dump from the main thread: +-recirc_id(0),in_port(n0),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=de:af:be:ef:ba:be,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br2)),n2) ++recirc_id(0),in_port(n0),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=de:af:be:ef:ba:be,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br2)),n2 + ]) + + AT_CHECK([ +@@ -892,7 +892,7 @@ ovs-appctl time/warp 1000 + AT_CHECK([ + ovs-appctl dpctl/dump-flows --names dummy@ovs-dummy | strip_used | grep -v ipv6 | sort + ], [0], [flow-dump from the main thread: +-recirc_id(0),in_port(n0),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:n1,pop_eth,clone(tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=de:af:be:ef:ba:be,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br2)),n2) ++recirc_id(0),in_port(n0),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(tos=0/0x3,frag=no), packets:1, bytes:98, used:0.0s, actions:n1,pop_eth,tnl_push(tnl_port(gre_sys),header(size=38,type=3,eth(dst=de:af:be:ef:ba:be,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x800))),out_port(br2)),n2 + ]) + + AT_CHECK([ diff --git a/tests/pmd.at b/tests/pmd.at index a2f9d34a2a..a2832b544c 100644 --- a/tests/pmd.at @@ -65399,8 +66025,21 @@ index 86d633ac4f..f0aaae63eb 100644 # VSCTL_ADD_DATAPATH_TABLE() # # Create system datapath table "system" for kernel tests in ovsdb +diff --git a/tests/system-layer3-tunnels.at b/tests/system-layer3-tunnels.at +index d21fd777dd..c37852b216 100644 +--- a/tests/system-layer3-tunnels.at ++++ b/tests/system-layer3-tunnels.at +@@ -147,7 +147,7 @@ AT_CHECK([tail -1 stdout], [0], + dnl Check GRE tunnel push + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(3),eth(dst=f9:bc:12:44:34:b6,src=af:55:aa:55:00:03),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.92,proto=1,tos=0,ttl=64,frag=no)'], [0], [stdout]) + AT_CHECK([tail -1 stdout], [0], +- [Datapath actions: clone(tnl_push(tnl_port(4),header(size=38,type=3,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:03,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.92,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(2)),1) ++ [Datapath actions: tnl_push(tnl_port(4),header(size=38,type=3,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:03,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.92,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(2)),1 + ]) + + OVS_VSWITCHD_STOP diff --git a/tests/system-offloads-traffic.at b/tests/system-offloads-traffic.at -index 80bc1dd5c3..14a332f5ed 100644 +index 80bc1dd5c3..9f50f3b01d 100644 --- a/tests/system-offloads-traffic.at +++ b/tests/system-offloads-traffic.at @@ -90,7 +90,7 @@ AT_CHECK([tc -o -s -d filter show dev ovs-p0 ingress | @@ -65421,6 +66060,74 @@ index 80bc1dd5c3..14a332f5ed 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP +@@ -168,3 +168,67 @@ matchall + ]) + OVS_TRAFFIC_VSWITCHD_STOP + AT_CLEANUP ++ ++ ++AT_SETUP([offloads - simulated flow action update]) ++OVS_TRAFFIC_VSWITCHD_START([], [], [-- set Open_vSwitch . other_config:hw-offload=true]) ++ ++ADD_NAMESPACES(at_ns0, at_ns1) ++ ++ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ++ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ++ ++AT_DATA([flows.txt], [dnl ++add in_port=ovs-p0,actions=ovs-p1,br0 ++add in_port=ovs-p1,actions=ovs-p0,br0 ++]) ++AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) ++ ++NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl ++10 packets transmitted, 10 received, 0% packet loss, time 0ms ++]) ++ ++AT_CHECK([ovs-appctl dpctl/dump-flows | grep "eth_type(0x0800)" | sort | dnl ++ strip_recirc | strip_used | dnl ++ sed 's/,packet_type(ns=[[0-9]]*,id=[[0-9]]*),/,/;s/,eth(),/,/;s/bytes:756/bytes:882/'], ++ [0], [dnl ++recirc_id(),in_port(2),eth_type(0x0800),ipv4(frag=no), packets:9, bytes:882, used:0.0s, actions:3,1 ++recirc_id(),in_port(3),eth_type(0x0800),ipv4(frag=no), packets:9, bytes:882, used:0.0s, actions:2,1 ++]) ++ ++AT_DATA([flows2.txt], [dnl ++modify in_port=ovs-p0,actions=ovs-p1 ++modify in_port=ovs-p1,actions=ovs-p0 ++]) ++AT_CHECK([ovs-ofctl add-flows br0 flows2.txt]) ++AT_CHECK([ovs-appctl revalidator/wait], [0]) ++ ++NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl ++10 packets transmitted, 10 received, 0% packet loss, time 0ms ++]) ++ ++AT_CHECK([ovs-appctl dpctl/dump-flows | grep "eth_type(0x0800)" | sort | dnl ++ strip_recirc | strip_used | dnl ++ sed -e 's/,packet_type(ns=[[0-9]]*,id=[[0-9]]*),/,/;s/,eth(),/,/;s/bytes:1596/bytes:1862/'], ++ [0], [dnl ++recirc_id(),in_port(2),eth_type(0x0800),ipv4(frag=no), packets:19, bytes:1862, used:0.0s, actions:3 ++recirc_id(),in_port(3),eth_type(0x0800),ipv4(frag=no), packets:19, bytes:1862, used:0.0s, actions:2 ++]) ++ ++AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) ++AT_CHECK([ovs-appctl revalidator/wait], [0]) ++ ++NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl ++10 packets transmitted, 10 received, 0% packet loss, time 0ms ++]) ++ ++AT_CHECK([ovs-appctl dpctl/dump-flows | grep "eth_type(0x0800)" | sort | dnl ++ strip_recirc | strip_used | dnl ++ sed 's/,packet_type(ns=[[0-9]]*,id=[[0-9]]*),/,/;s/,eth(),/,/;s/bytes:2436/bytes:2842/'], ++ [0], [dnl ++recirc_id(),in_port(2),eth_type(0x0800),ipv4(frag=no), packets:29, bytes:2842, used:0.0s, actions:3,1 ++recirc_id(),in_port(3),eth_type(0x0800),ipv4(frag=no), packets:29, bytes:2842, used:0.0s, actions:2,1 ++]) ++ ++OVS_TRAFFIC_VSWITCHD_STOP ++AT_CLEANUP diff --git a/tests/system-route.at b/tests/system-route.at index 1714273e35..270956d13f 100644 --- a/tests/system-route.at @@ -65440,7 +66147,7 @@ index 1714273e35..270956d13f 100644 dnl Delete ip address. AT_CHECK([ip addr del 10.0.0.17/24 dev p1-route], [0], [stdout]) diff --git a/tests/system-traffic.at b/tests/system-traffic.at -index f22d86e466..4808e78de3 100644 +index f22d86e466..d4c34c1291 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -192,6 +192,46 @@ NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 2 fc00:1::2 | FORMAT_PI @@ -65836,7 +66543,77 @@ index f22d86e466..4808e78de3 100644 ]) OVS_TRAFFIC_VSWITCHD_STOP -@@ -1765,10 +1917,10 @@ dnl p1(at_ns1) interface +@@ -1738,6 +1890,69 @@ masks-cache:size:256 + OVS_TRAFFIC_VSWITCHD_STOP + AT_CLEANUP + ++AT_SETUP([datapath - simulated flow action update]) ++OVS_TRAFFIC_VSWITCHD_START() ++ ++ADD_NAMESPACES(at_ns0, at_ns1) ++ ++ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ++ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ++ ++AT_DATA([flows.txt], [dnl ++add in_port=ovs-p0,actions=ovs-p1,br0 ++add in_port=ovs-p1,actions=ovs-p0,br0 ++]) ++AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) ++ ++NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl ++10 packets transmitted, 10 received, 0% packet loss, time 0ms ++]) ++ ++AT_CHECK([ovs-appctl dpctl/dump-flows | grep "eth_type(0x0800)" | sort | dnl ++ strip_recirc | strip_used | dnl ++ sed 's/,packet_type(ns=[[0-9]]*,id=[[0-9]]*),/,/;s/,eth(),/,/;s/bytes:756/bytes:882/'], ++ [0], [dnl ++recirc_id(),in_port(2),eth_type(0x0800),ipv4(frag=no), packets:9, bytes:882, used:0.0s, actions:3,1 ++recirc_id(),in_port(3),eth_type(0x0800),ipv4(frag=no), packets:9, bytes:882, used:0.0s, actions:2,1 ++]) ++ ++AT_DATA([flows2.txt], [dnl ++modify in_port=ovs-p0,actions=ovs-p1 ++modify in_port=ovs-p1,actions=ovs-p0 ++]) ++AT_CHECK([ovs-ofctl add-flows br0 flows2.txt]) ++AT_CHECK([ovs-appctl revalidator/wait], [0]) ++ ++NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl ++10 packets transmitted, 10 received, 0% packet loss, time 0ms ++]) ++ ++AT_CHECK([ovs-appctl dpctl/dump-flows | grep "eth_type(0x0800)" | sort | dnl ++ strip_recirc | strip_used | dnl ++ sed -e 's/,packet_type(ns=[[0-9]]*,id=[[0-9]]*),/,/;s/,eth(),/,/;s/bytes:1596/bytes:1862/'], ++ [0], [dnl ++recirc_id(),in_port(2),eth_type(0x0800),ipv4(frag=no), packets:19, bytes:1862, used:0.0s, actions:3 ++recirc_id(),in_port(3),eth_type(0x0800),ipv4(frag=no), packets:19, bytes:1862, used:0.0s, actions:2 ++]) ++ ++AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) ++AT_CHECK([ovs-appctl revalidator/wait], [0]) ++ ++NS_CHECK_EXEC([at_ns0], [ping -q -c 10 -i 0.1 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl ++10 packets transmitted, 10 received, 0% packet loss, time 0ms ++]) ++ ++AT_CHECK([ovs-appctl dpctl/dump-flows | grep "eth_type(0x0800)" | sort | dnl ++ strip_recirc | strip_used | dnl ++ sed 's/,packet_type(ns=[[0-9]]*,id=[[0-9]]*),/,/;s/,eth(),/,/;s/bytes:2436/bytes:2842/'], ++ [0], [dnl ++recirc_id(),in_port(2),eth_type(0x0800),ipv4(frag=no), packets:29, bytes:2842, used:0.0s, actions:3,1 ++recirc_id(),in_port(3),eth_type(0x0800),ipv4(frag=no), packets:29, bytes:2842, used:0.0s, actions:2,1 ++]) ++ ++OVS_TRAFFIC_VSWITCHD_STOP ++AT_CLEANUP ++ + AT_BANNER([MPLS]) + + AT_SETUP([mpls - encap header dp-support]) +@@ -1765,10 +1980,10 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) dnl Check the expected mpls encapsulated packet on the egress interface @@ -65851,7 +66628,7 @@ index f22d86e466..4808e78de3 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -1797,10 +1949,10 @@ dnl p1(at_ns1) interface +@@ -1797,10 +2012,10 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) dnl Check the expected mpls encapsulated packet on the egress interface @@ -65866,7 +66643,7 @@ index f22d86e466..4808e78de3 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -1830,10 +1982,10 @@ dnl p1(at_ns1) interface +@@ -1830,10 +2045,10 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) dnl Check the expected mpls encapsulated packet on the egress interface @@ -65881,7 +66658,7 @@ index f22d86e466..4808e78de3 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -1862,10 +2014,10 @@ dnl p1(at_ns1) interface +@@ -1862,10 +2077,10 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) dnl Check the expected mpls encapsulated packet on the egress interface @@ -65896,7 +66673,7 @@ index f22d86e466..4808e78de3 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -1896,13 +2048,13 @@ dnl p1(at_ns1) interface +@@ -1896,13 +2111,13 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 00 00 00 00 00 02 00 00 00 00 00 01 88 47 00 00 21 40 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) dnl Check the expected decapsulated on the egress interface @@ -65917,7 +66694,7 @@ index f22d86e466..4808e78de3 100644 OVS_TRAFFIC_VSWITCHD_STOP -@@ -1933,15 +2085,51 @@ dnl p1(at_ns1) interface +@@ -1933,15 +2148,51 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 00 00 00 00 00 02 00 00 00 00 00 01 88 47 00 00 21 40 36 b1 ee 7c 01 02 36 b1 ee 7c 01 03 08 00 45 00 00 54 03 44 40 00 40 01 21 61 0a 01 01 01 0a 01 01 02 08 00 ef ac 7c e4 00 03 5b 2c 1f 61 00 00 00 00 50 0b 02 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 > /dev/null]) dnl Check the expected decapsulated on the egress interface @@ -65976,7 +66753,7 @@ index f22d86e466..4808e78de3 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -1985,9 +2173,9 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) +@@ -1985,9 +2236,9 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN2 (xid=0x0): total_len=42 in_port=1 (via action) data_len=42 (unbuffered) @@ -65988,7 +66765,7 @@ index f22d86e466..4808e78de3 100644 ]) OVS_TRAFFIC_VSWITCHD_STOP -@@ -2033,9 +2221,9 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) +@@ -2033,9 +2284,9 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN2 (xid=0x0): cookie=0x0 total_len=42 in_port=1 (via action) data_len=42 (unbuffered) @@ -66000,7 +66777,7 @@ index f22d86e466..4808e78de3 100644 ]) dnl -@@ -2980,6 +3168,15 @@ NXST_FLOW reply: +@@ -2980,6 +3231,15 @@ NXST_FLOW reply: table=1, priority=100,ct_state=+est+trk,in_port=1 actions=output:2 ]) @@ -66016,7 +66793,7 @@ index f22d86e466..4808e78de3 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -3140,11 +3337,11 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) +@@ -3140,11 +3400,11 @@ OVS_APP_EXIT_AND_WAIT([ovs-ofctl]) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log | grep -v ff02 | grep -v fe80 | grep -v no_match], [0], [dnl NXT_PACKET_IN2 (xid=0x0): table_id=1 cookie=0x0 total_len=75 ct_state=inv|trk,ip,in_port=2 (via action) data_len=75 (unbuffered) @@ -66031,7 +66808,7 @@ index f22d86e466..4808e78de3 100644 ]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.0.1)], [0], [dnl -@@ -3345,6 +3542,11 @@ AT_CHECK([ovs-ofctl bundle br0 bundle.txt]) +@@ -3345,6 +3605,11 @@ AT_CHECK([ovs-ofctl bundle br0 bundle.txt]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl ]) @@ -66043,7 +66820,7 @@ index f22d86e466..4808e78de3 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -4100,15 +4302,15 @@ action=normal +@@ -4100,15 +4365,15 @@ action=normal AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) @@ -66062,7 +66839,7 @@ index f22d86e466..4808e78de3 100644 "1616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610a, actions=ct(table=1)"]) AT_CHECK([ovs-appctl dpctl/dump-flows | head -2 | tail -1 | grep -q -e ["]udp[(]src=5001["]]) -@@ -5384,7 +5586,7 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | sed -e 's/dst= +@@ -5384,7 +5649,7 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | sed -e 's/dst= udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.2XX,sport=,dport=),mark=1 ]) @@ -66071,7 +66848,7 @@ index f22d86e466..4808e78de3 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -6134,7 +6336,7 @@ sleep 1 +@@ -6134,7 +6399,7 @@ sleep 1 dnl UDP packets from ns0->ns1 should solicit "destination unreachable" response. NS_CHECK_EXEC([at_ns0], [bash -c "echo a | nc -6 $NC_EOF_OPT -u fc00::2 1"]) @@ -66080,7 +66857,7 @@ index f22d86e466..4808e78de3 100644 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fc00::2)], [0], [dnl udp,orig=(src=fc00::1,dst=fc00::2,sport=,dport=),reply=(src=fc00::2,dst=fc00::240,sport=,dport=) -@@ -6454,7 +6656,7 @@ on_exit 'ovs-appctl revalidator/purge' +@@ -6454,7 +6719,7 @@ on_exit 'ovs-appctl revalidator/purge' on_exit 'ovs-appctl dpif/dump-flows br0' dnl Should work with the virtual IP address through NAT @@ -66089,7 +66866,7 @@ index f22d86e466..4808e78de3 100644 echo Request $i NS_CHECK_EXEC([at_ns1], [wget 10.1.1.64 -t 5 -T 1 --retry-connrefused -v -o wget$i.log]) done -@@ -6743,6 +6945,132 @@ AT_CHECK([ovs-ofctl dump-flows br0 | grep table=2, | OFPROTO_CLEAR_DURATION_IDLE +@@ -6743,6 +7008,132 @@ AT_CHECK([ovs-ofctl dump-flows br0 | grep table=2, | OFPROTO_CLEAR_DURATION_IDLE OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP @@ -66222,7 +66999,7 @@ index f22d86e466..4808e78de3 100644 AT_BANNER([802.1ad]) AT_SETUP([802.1ad - vlan_limit]) -@@ -7007,12 +7335,12 @@ dnl p1(at_ns1) interface +@@ -7007,12 +7398,12 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) dnl Check the expected nsh encapsulated packet on the egress interface @@ -66241,7 +67018,7 @@ index f22d86e466..4808e78de3 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -7039,10 +7367,10 @@ dnl p1(at_ns1) interface +@@ -7039,10 +7430,10 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 00 64 03 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) dnl Check the expected de-capsulated TCP packet on the egress interface @@ -66256,7 +67033,7 @@ index f22d86e466..4808e78de3 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -7072,12 +7400,12 @@ dnl p1(at_ns1) interface +@@ -7072,12 +7463,12 @@ dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 01 00 03 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) dnl Check the expected NSH packet with new fields in the header @@ -66275,7 +67052,7 @@ index f22d86e466..4808e78de3 100644 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -@@ -7106,23 +7434,23 @@ dnl First send packet from at_ns0 --> OVS with SPI=0x100 and SI=2 +@@ -7106,23 +7497,23 @@ dnl First send packet from at_ns0 --> OVS with SPI=0x100 and SI=2 NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 01 00 02 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) dnl Check for the above packet on p1 interface @@ -67316,9 +68093,77 @@ index fc8ce4a2c0..96c89bd4e6 100644 && error != WSAECONNRESET #endif diff --git a/tests/tunnel-push-pop-ipv6.at b/tests/tunnel-push-pop-ipv6.at -index 3f58e3e8fd..8c5af459e9 100644 +index 3f58e3e8fd..c96b77cd15 100644 --- a/tests/tunnel-push-pop-ipv6.at +++ b/tests/tunnel-push-pop-ipv6.at +@@ -63,7 +63,7 @@ AT_CHECK([ovs-ofctl add-flow int-br action=2]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:01),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(6),header(size=58,type=109,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=0x0,proto=0x6558))),out_port(100)),1) ++ [Datapath actions: tnl_push(tnl_port(6),header(size=58,type=109,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=0x0,proto=0x6558))),out_port(100)),1 + ]) + + OVS_VSWITCHD_STOP +@@ -151,14 +151,14 @@ dnl Check ERSPAN v1 tunnel push + AT_CHECK([ovs-ofctl add-flow int-br action=2]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:01),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(6),header(size=70,type=108,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),erspan(ver=1,sid=0x7b,idx=0x3)),out_port(100)),1) ++ [Datapath actions: tnl_push(tnl_port(6),header(size=70,type=108,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),erspan(ver=1,sid=0x7b,idx=0x3)),out_port(100)),1 + ]) + + dnl Check ERSPAN v2 tunnel push + AT_CHECK([ovs-ofctl mod-flows int-br action=3]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:01),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(6),header(size=74,type=108,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=47,tclass=0x0,hlimit=64),erspan(ver=2,sid=0x237,dir=1,hwid=0x7)),out_port(100)),1) ++ [Datapath actions: tnl_push(tnl_port(6),header(size=74,type=108,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=47,tclass=0x0,hlimit=64),erspan(ver=2,sid=0x237,dir=1,hwid=0x7)),out_port(100)),1 + ]) + + ovs-appctl vlog/set dbg +@@ -388,28 +388,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(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:01),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)),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(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:01),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)),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(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:01),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=109,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=109,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 + ]) + + 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(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:01),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)),1 + ]) + + dnl Check Geneve tunnel push with options +@@ -417,7 +417,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(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:01),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)),1 + ]) + + dnl Check decapsulation of GRE packet @@ -452,7 +452,7 @@ OVS_APP_EXIT_AND_WAIT(ovs-ofctl) AT_CHECK([cat ofctl_monitor.log], [0], [dnl @@ -67328,10 +68173,100 @@ index 3f58e3e8fd..8c5af459e9 100644 ]) AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port 5'], [0], [dnl +@@ -472,7 +472,7 @@ 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(src=36:b1:ee:7c:01:01,dst=36:b1:ee:7c:01:02),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:ca:fe,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:ca:fe,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 + ]) + + AT_CHECK([ovs-appctl tnl/arp/show | tail -n+3 | sort], [0], [dnl +@@ -490,7 +490,7 @@ 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(src=36:b1:ee:7c:01:01,dst=36:b1:ee:7c:01:02),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)),1 + ]) + + AT_CHECK([ovs-appctl tnl/arp/show | tail -n+3 | sort], [0], [dnl diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at -index 57589758f4..50f90815a1 100644 +index 57589758f4..65b1469e49 100644 --- a/tests/tunnel-push-pop.at +++ b/tests/tunnel-push-pop.at +@@ -85,7 +85,7 @@ AT_CHECK([ovs-vsctl -- set Interface br0 options:pcap=br0.pcap]) + AT_CHECK([ovs-ofctl add-flow int-br action=2]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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=50,type=107,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),erspan(ver=1,sid=0x7b,idx=0x3)),out_port(100)),1) ++ [Datapath actions: tnl_push(tnl_port(3),header(size=50,type=107,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),erspan(ver=1,sid=0x7b,idx=0x3)),out_port(100)),1 + ]) + + dnl Check ERSPAN v2 tunnel push +@@ -93,7 +93,7 @@ AT_CHECK([ovs-ofctl mod-flows int-br action=3]) + AT_CHECK([ovs-appctl revalidator/wait]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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=54,type=107,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),erspan(ver=2,sid=0x237,dir=1,hwid=0x7)),out_port(100)),1) ++ [Datapath actions: tnl_push(tnl_port(3),header(size=54,type=107,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),erspan(ver=2,sid=0x237,dir=1,hwid=0x7)),out_port(100)),1 + ]) + + dnl Check ERSPAN v2 flow-based tunnel push +@@ -101,7 +101,7 @@ AT_CHECK([ovs-ofctl mod-flows int-br "action=set_field:1.1.2.94->tun_dst,set_fie + AT_CHECK([ovs-appctl revalidator/wait]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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=54,type=107,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=47,tos=0,ttl=64,frag=0x4000),erspan(ver=2,sid=0x1c8,dir=1,hwid=0x1)),out_port(100)),1) ++ [Datapath actions: tnl_push(tnl_port(3),header(size=54,type=107,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=47,tos=0,ttl=64,frag=0x4000),erspan(ver=2,sid=0x1c8,dir=1,hwid=0x1)),out_port(100)),1 + ]) + + dnl Check ERSPAN v2 flow-based tunnel push, erspan_ver=flow +@@ -110,7 +110,7 @@ AT_CHECK([ovs-ofctl mod-flows int-br "action=set_field:1.1.2.94->tun_dst,set_fie + AT_CHECK([ovs-appctl revalidator/wait]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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=54,type=107,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=47,tos=0,ttl=64,frag=0x4000),erspan(ver=2,sid=0x38,dir=1,hwid=0x1)),out_port(100)),1) ++ [Datapath actions: tnl_push(tnl_port(3),header(size=54,type=107,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=47,tos=0,ttl=64,frag=0x4000),erspan(ver=2,sid=0x38,dir=1,hwid=0x1)),out_port(100)),1 + ]) + + dnl Dynamically set erspan v1 +@@ -118,7 +118,7 @@ AT_CHECK([ovs-ofctl mod-flows int-br "action=set_field:1.1.2.94->tun_dst,set_fie + AT_CHECK([ovs-appctl revalidator/wait]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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=50,type=107,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=47,tos=0,ttl=64,frag=0x4000),erspan(ver=1,sid=0x38,idx=0x1)),out_port(100)),1) ++ [Datapath actions: tnl_push(tnl_port(3),header(size=50,type=107,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=47,tos=0,ttl=64,frag=0x4000),erspan(ver=1,sid=0x38,idx=0x1)),out_port(100)),1 + ]) + + dnl Check ERSPAN v2 flow-based tunnel push +@@ -126,7 +126,7 @@ AT_CHECK([ovs-ofctl mod-flows int-br "action=set_field:1.1.2.94->tun_dst,set_fie + AT_CHECK([ovs-appctl revalidator/wait]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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=54,type=107,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=47,tos=0,ttl=64,frag=0x4000),erspan(ver=2,sid=0x1c8,dir=1,hwid=0x1)),out_port(100)),1) ++ [Datapath actions: tnl_push(tnl_port(3),header(size=54,type=107,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=47,tos=0,ttl=64,frag=0x4000),erspan(ver=2,sid=0x1c8,dir=1,hwid=0x1)),out_port(100)),1 + ]) + + dnl Check ERSPAN v2 flow-based tunnel push, erspan_ver=flow +@@ -135,7 +135,7 @@ AT_CHECK([ovs-ofctl mod-flows int-br "action=set_field:1.1.2.94->tun_dst,set_fie + AT_CHECK([ovs-appctl revalidator/wait]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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=54,type=107,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=47,tos=0,ttl=64,frag=0x4000),erspan(ver=2,sid=0x38,dir=1,hwid=0x1)),out_port(100)),1) ++ [Datapath actions: tnl_push(tnl_port(3),header(size=54,type=107,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=47,tos=0,ttl=64,frag=0x4000),erspan(ver=2,sid=0x38,dir=1,hwid=0x1)),out_port(100)),1 + ]) + + dnl Dynamically set erspan v1 +@@ -143,7 +143,7 @@ AT_CHECK([ovs-ofctl mod-flows int-br "action=set_field:1.1.2.94->tun_dst,set_fie + AT_CHECK([ovs-appctl revalidator/wait]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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=50,type=107,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=47,tos=0,ttl=64,frag=0x4000),erspan(ver=1,sid=0x38,idx=0x1)),out_port(100)),1) ++ [Datapath actions: tnl_push(tnl_port(3),header(size=50,type=107,eth(dst=f8:bc:12:44:34:b8,src=aa:55:aa:55:00:00,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.94,proto=47,tos=0,ttl=64,frag=0x4000),erspan(ver=1,sid=0x38,idx=0x1)),out_port(100)),1 + ]) + + dnl Check ERSPAN tunnel pop @@ -369,6 +369,26 @@ AT_CHECK([ovs-appctl tnl/neigh/show | grep br | sort], [0], [dnl 1.1.2.92 f8:bc:12:44:34:b6 br0 ]) @@ -67359,6 +68294,81 @@ index 57589758f4..50f90815a1 100644 dnl Receive ARP reply without VLAN header AT_CHECK([ovs-vsctl set port br0 tag=0]) AT_CHECK([ovs-appctl tnl/neigh/flush], [0], [OK +@@ -431,49 +451,49 @@ 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(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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)),1 + ]) + + dnl Check VXLAN GPE tunnel push + AT_CHECK([ovs-ofctl add-flow int-br action=8]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:01),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=0xc000003,vni=0x159)),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=0xc000003,vni=0x159)),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(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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)),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(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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)),1 + ]) + + dnl Check L3GRE tunnel push + AT_CHECK([ovs-ofctl add-flow int-br action=7]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:01),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: pop_eth,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=0x800),key=0x1c8)),out_port(100)),1) ++ [Datapath actions: pop_eth,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=0x800),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(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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)),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(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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)),1 + ]) + + dnl Check Geneve tunnel push with options +@@ -481,7 +501,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(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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)),1 + ]) + + dnl Check GTP-U tunnel push +@@ -489,7 +509,7 @@ AT_CHECK([ovs-ofctl add-flow int-br "actions=9"]) + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),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: pop_eth,clone(tnl_push(tnl_port(2152),header(size=50,type=110,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=2152,csum=0x0),gtpu(flags=0x30,msgtype=255,teid=0x7b)),out_port(100)),1) ++ [Datapath actions: pop_eth,tnl_push(tnl_port(2152),header(size=50,type=110,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=2152,csum=0x0),gtpu(flags=0x30,msgtype=255,teid=0x7b)),out_port(100)),1 + ]) + AT_CHECK([ovs-ofctl del-flows int-br]) + @@ -546,6 +566,28 @@ AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port [[37]]' | sort], [0], [dnl port 7: rx pkts=5, bytes=434, drop=?, errs=?, frame=?, over=?, crc=? ]) @@ -67406,6 +68416,24 @@ index 57589758f4..50f90815a1 100644 ]) dnl Receive VXLAN with different MAC and verify that the neigh cache gets updated +@@ -579,7 +621,7 @@ 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(src=36:b1:ee:7c:01:01,dst=36:b1:ee:7c:01:02),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:ca:fe,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:ca:fe,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 + ]) + + AT_CHECK([ovs-appctl tnl/neigh/show | tail -n+3 | sort], [0], [dnl +@@ -596,7 +638,7 @@ ovs-appctl time/warp 1000 + dnl Check VXLAN tunnel push + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=36:b1:ee:7c:01:01,dst=36:b1:ee:7c:01:02),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)),1 + ]) + + AT_CHECK([ovs-appctl tnl/neigh/show | tail -n+3 | sort], [0], [dnl @@ -718,14 +760,14 @@ dnl Output to tunnel from a int-br internal port. dnl Checking that the packet arrived and it was correctly encapsulated. AT_CHECK([ovs-ofctl add-flow int-br "in_port=LOCAL,actions=debug_slow,output:2"]) @@ -67424,6 +68452,15 @@ index 57589758f4..50f90815a1 100644 dnl Datapath actions should not have tunnel push action. AT_CHECK([ovs-appctl dpctl/dump-flows | grep -q tnl_push], [1]) +@@ -772,7 +814,7 @@ AT_CHECK([ovs-ofctl add-flow int-br action=3]) + + AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=17,tos=0,ttl=64,frag=no),udp(src=51283,dst=4789)'], [0], [stdout]) + AT_CHECK([tail -1 stdout], [0], +- [Datapath actions: clone(tnl_push(tnl_port(3),header(size=46,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=0x3000,proto=0x6558),key=0x1c8,seq=0x0)),out_port(100)),1) ++ [Datapath actions: tnl_push(tnl_port(3),header(size=46,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=0x3000,proto=0x6558),key=0x1c8,seq=0x0)),out_port(100)),1 + ]) + + dnl Verify outer L2 and L3 header flow fields can be matched in the underlay bridge @@ -842,3 +884,54 @@ Datapath actions: 7 OVS_VSWITCHD_STOP @@ -67470,11 +68507,11 @@ index 57589758f4..50f90815a1 100644 +AT_CHECK([tail -2 stdout], [0], [dnl +Megaflow: recirc_id=0,eth,in_port=7,dl_src=00:00:00:00:00:00,dnl +dl_dst=00:00:00:00:00:00,dl_type=0x0000 -+Datapath actions: push_vlan(vid=200,pcp=0),1,clone(tnl_push(tnl_port(4789),dnl ++Datapath actions: push_vlan(vid=200,pcp=0),1,tnl_push(tnl_port(4789),dnl +header(size=50,type=4,eth(dst=aa:55:aa:66:00:00,src=aa:55:aa:55:00:00,dnl +dl_type=0x0800),ipv4(src=10.0.0.2,dst=10.0.0.11,proto=17,tos=0,ttl=64,dnl +frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0x8000000,vni=0x0)),dnl -+out_port(100)),8) ++out_port(100)),8 +]) + +OVS_VSWITCHD_STOP diff --git a/SPECS/openvswitch2.17.spec b/SPECS/openvswitch2.17.spec index 6d78cf4..9e8720c 100644 --- a/SPECS/openvswitch2.17.spec +++ b/SPECS/openvswitch2.17.spec @@ -57,7 +57,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.17.0 -Release: 63%{?dist} +Release: 65%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -748,6 +748,52 @@ exit 0 %endif %changelog +* Mon Feb 13 2023 Open vSwitch CI - 2.17.0-65 +- Merging upstream branch-2.17 [RH git: 2011158f64] + Commit list: + 6626562c53 sparse: Fix build with DPDK and GCC 12. + 82dc71f808 ovsdb-server: Fix handling of DNS name for listener configuration. + 9b341844e7 netdev-offload-tc: If the flow has not been used, report it as such. + adac28dcdf netdev-offload-tc: Conntrack ALGs are not supported with tc. + a1c2abba78 netdev-offload-tc: Fix tc conntrack force commit support. + 68a2818b09 ofproto-dpif-upcall: New ukey needs to take the old ukey's dump seq. + 2eb7a60668 netdev-offload-tc: Preserve tc statistics when flow gets modified. + 4f51407698 sparse: Fix numa.h for libnuma >= 2.0.13. + + +* Tue Feb 07 2023 Eelco Chaudron - 2.17.0-64 +- ofproto-dpif-xlate: Optimize datapath action set by removing last clone action. [RH git: 684b6e8ad9] + Manual backport of the below commit. In addition to the upstream fix, + we also had to bring in the nl_msg_reset_size() function. We also had + to fix-up nine test cases as they where showing incorrect results. + + Bugzilla : https://bugzilla.redhat.com/2110018 + Upstream commit: 4f5decf4ab3f ("ofproto-dpif-xlate: Optimize datapath action set by removing last clone action.") + + When OFPROTO non-reversible actions are translated to data plane + actions, the only thing looked at is if there are more actions + pending. If this is the case, the action is encapsulated in a + clone(). + + This could lead to unnecessary clones if no meaningful data + plane actions are added. For example, the register pop in the + included test case. + + The best solution would probably be to build the full action + path and determine if the clone is needed. However, this would + be a huge change in the existing design, so for now, we just try + to optimize the generated datapath flow. We can revisit this + later, as some of the pending CT issues might need this rework. + + Fixes: feee58b9587f ("ofproto-dpif-xlate: Keep track of the last action") + Fixes: dadd8357f224 ("ofproto-dpif: Fix issue with non-reversible actions on a patch ports.") + Acked-by: Ales Musil + Signed-off-by: Eelco Chaudron + Signed-off-by: Ilya Maximets + + Signed-off-by: Eelco Chaudron + + * Mon Jan 30 2023 Open vSwitch CI - 2.17.0-63 - Merging upstream branch-2.17 [RH git: 64bd43b450] Commit list: