On Fri, Jan 15, 2021 at 11:56 PM Dumitru Ceara <dce...@redhat.com> wrote:
>
> In case traffic that gets load balanced is DNAT-ed to a backend IP that
> happens to be the source of the traffic then OVN performs an additional
> SNAT to ensure that return traffic is directed through OVN.
>
> Until now the load balancer VIP was chosen as SNAT IP.  However, in
> specific scenarios, the CMS may prefer a different IP, e.g., a single
> cluster-wide IP.  This commit adds support, through the newly added
> Load_Balancer.option 'hairpin_snat_ip', to allow the CMS to explicitly
> chose a SNAT IP.
>
> Due to the fact that now traffic that was hairpinned might need to be
> SNAT-ed to different IPs for different load balancers that share the
> same VIP address value we need to also explicitly match on L4 protocol
> and ports in the 'OFTABLE_CT_SNAT_FOR_VIP' table.
>
> Signed-off-by: Dumitru Ceara <dce...@redhat.com>

Thanks Dumitru for this patch. The patch LGTM.

I applied to the master branch.

Numan

> ---
>  NEWS                |   3 +
>  controller/lflow.c  |  53 +++++++++------
>  lib/lb.c            |  26 ++++++++
>  lib/lb.h            |  11 ++++
>  lib/ovn-util.c      |  21 ++++++
>  lib/ovn-util.h      |   1 +
>  northd/ovn-northd.c |   9 +--
>  ovn-nb.xml          |   8 +++
>  ovn-sb.ovsschema    |   9 ++-
>  ovn-sb.xml          |   8 +++
>  tests/ovn-northd.at |   6 ++
>  tests/ovn.at        | 182 
> ++++++++++++++++++++++++++++++++++++++--------------
>  12 files changed, 261 insertions(+), 76 deletions(-)
>
> diff --git a/NEWS b/NEWS
> index e89c5f4..57a9ba9 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -10,6 +10,9 @@ Post-v20.12.0
>      "ovn-installed".  This external-id is set by ovn-controller only after 
> all
>      openflow operations corresponding to the OVS interface being added have
>      been processed.
> +  - Add a new option to Load_Balancer.options, "hairpin_snat_ip", to allow
> +    users to explicitly select which source IP should be used for load
> +    balancer hairpin traffic.
>
>  OVN v20.12.0 - 18 Dec 2020
>  --------------------------
> diff --git a/controller/lflow.c b/controller/lflow.c
> index c02585b..5c53b0d 100644
> --- a/controller/lflow.c
> +++ b/controller/lflow.c
> @@ -1191,26 +1191,30 @@ add_lb_vip_hairpin_flows(struct ovn_controller_lb *lb,
>      struct match hairpin_reply_match = MATCH_CATCHALL_INITIALIZER;
>
>      if (IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)) {
> -        ovs_be32 ip4 = in6_addr_get_mapped_ipv4(&lb_backend->ip);
> +        ovs_be32 bip4 = in6_addr_get_mapped_ipv4(&lb_backend->ip);
> +        ovs_be32 vip4 = lb->hairpin_snat_ips.n_ipv4_addrs
> +                        ? lb->hairpin_snat_ips.ipv4_addrs[0].addr
> +                        : in6_addr_get_mapped_ipv4(&lb_vip->vip);
>
>          match_set_dl_type(&hairpin_match, htons(ETH_TYPE_IP));
> -        match_set_nw_src(&hairpin_match, ip4);
> -        match_set_nw_dst(&hairpin_match, ip4);
> -
> -        match_set_dl_type(&hairpin_reply_match,
> -                          htons(ETH_TYPE_IP));
> -        match_set_nw_src(&hairpin_reply_match, ip4);
> -        match_set_nw_dst(&hairpin_reply_match,
> -                         in6_addr_get_mapped_ipv4(&lb_vip->vip));
> +        match_set_nw_src(&hairpin_match, bip4);
> +        match_set_nw_dst(&hairpin_match, bip4);
> +
> +        match_set_dl_type(&hairpin_reply_match, htons(ETH_TYPE_IP));
> +        match_set_nw_src(&hairpin_reply_match, bip4);
> +        match_set_nw_dst(&hairpin_reply_match, vip4);
>      } else {
> +        struct in6_addr *bip6 = &lb_backend->ip;
> +        struct in6_addr *vip6 = lb->hairpin_snat_ips.n_ipv6_addrs
> +                                ? &lb->hairpin_snat_ips.ipv6_addrs[0].addr
> +                                : &lb_vip->vip;
>          match_set_dl_type(&hairpin_match, htons(ETH_TYPE_IPV6));
> -        match_set_ipv6_src(&hairpin_match, &lb_backend->ip);
> -        match_set_ipv6_dst(&hairpin_match, &lb_backend->ip);
> +        match_set_ipv6_src(&hairpin_match, bip6);
> +        match_set_ipv6_dst(&hairpin_match, bip6);
>
> -        match_set_dl_type(&hairpin_reply_match,
> -                          htons(ETH_TYPE_IPV6));
> -        match_set_ipv6_src(&hairpin_reply_match, &lb_backend->ip);
> -        match_set_ipv6_dst(&hairpin_reply_match, &lb_vip->vip);
> +        match_set_dl_type(&hairpin_reply_match, htons(ETH_TYPE_IPV6));
> +        match_set_ipv6_src(&hairpin_reply_match, bip6);
> +        match_set_ipv6_dst(&hairpin_reply_match, vip6);
>      }
>
>      if (lb_backend->port) {
> @@ -1256,6 +1260,7 @@ add_lb_vip_hairpin_flows(struct ovn_controller_lb *lb,
>  static void
>  add_lb_ct_snat_vip_flows(struct ovn_controller_lb *lb,
>                           struct ovn_lb_vip *lb_vip,
> +                         uint8_t lb_proto,
>                           struct ovn_desired_flow_table *flow_table)
>  {
>      uint64_t stub[1024 / 8];
> @@ -1279,10 +1284,16 @@ add_lb_ct_snat_vip_flows(struct ovn_controller_lb *lb,
>
>      if (IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)) {
>          nat->range_af = AF_INET;
> -        nat->range.addr.ipv4.min = in6_addr_get_mapped_ipv4(&lb_vip->vip);
> +        nat->range.addr.ipv4.min =
> +            lb->hairpin_snat_ips.n_ipv4_addrs
> +            ? lb->hairpin_snat_ips.ipv4_addrs[0].addr
> +            : in6_addr_get_mapped_ipv4(&lb_vip->vip);
>      } else {
>          nat->range_af = AF_INET6;
> -        nat->range.addr.ipv6.min = lb_vip->vip;
> +        nat->range.addr.ipv6.min
> +            = lb->hairpin_snat_ips.n_ipv6_addrs
> +            ? lb->hairpin_snat_ips.ipv6_addrs[0].addr
> +            : lb_vip->vip;
>      }
>      ofpacts.header = ofpbuf_push_uninit(&ofpacts, nat_offset);
>      ofpact_finish(&ofpacts, &ct->ofpact);
> @@ -1290,12 +1301,16 @@ add_lb_ct_snat_vip_flows(struct ovn_controller_lb *lb,
>      struct match match = MATCH_CATCHALL_INITIALIZER;
>      if (IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)) {
>          match_set_dl_type(&match, htons(ETH_TYPE_IP));
> -        match_set_ct_nw_dst(&match, nat->range.addr.ipv4.min);
> +        match_set_ct_nw_dst(&match, in6_addr_get_mapped_ipv4(&lb_vip->vip));
>      } else {
>          match_set_dl_type(&match, htons(ETH_TYPE_IPV6));
>          match_set_ct_ipv6_dst(&match, &lb_vip->vip);
>      }
>
> +    match_set_nw_proto(&match, lb_proto);
> +    match_set_ct_nw_proto(&match, lb_proto);
> +    match_set_ct_tp_dst(&match, htons(lb_vip->vip_port));
> +
>      uint32_t ct_state = OVS_CS_F_TRACKED | OVS_CS_F_DST_NAT;
>      match_set_ct_state_masked(&match, ct_state, ct_state);
>
> @@ -1351,7 +1366,7 @@ consider_lb_hairpin_flows(const struct 
> sbrec_load_balancer *sbrec_lb,
>                                       flow_table);
>          }
>
> -        add_lb_ct_snat_vip_flows(lb, lb_vip, flow_table);
> +        add_lb_ct_snat_vip_flows(lb, lb_vip, lb_proto, flow_table);
>      }
>
>      ovn_controller_lb_destroy(lb);
> diff --git a/lib/lb.c b/lib/lb.c
> index 2517c02..e11ac00 100644
> --- a/lib/lb.c
> +++ b/lib/lb.c
> @@ -170,6 +170,24 @@ void ovn_northd_lb_vip_destroy(struct ovn_northd_lb_vip 
> *vip)
>      free(vip->backends_nb);
>  }
>
> +static void
> +ovn_lb_get_hairpin_snat_ip(const struct uuid *lb_uuid,
> +                           const struct smap *lb_options,
> +                           struct lport_addresses *hairpin_addrs)
> +{
> +    const char *addresses = smap_get(lb_options, "hairpin_snat_ip");
> +
> +    if (!addresses) {
> +        return;
> +    }
> +
> +    if (!extract_ip_address(addresses, hairpin_addrs)) {
> +        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
> +        VLOG_WARN_RL(&rl, "bad hairpin_snat_ip %s in load balancer "UUID_FMT,
> +                     addresses, UUID_ARGS(lb_uuid));
> +    }
> +}
> +
>  struct ovn_northd_lb *
>  ovn_northd_lb_create(const struct nbrec_load_balancer *nbrec_lb,
>                       struct hmap *ports,
> @@ -224,6 +242,9 @@ ovn_northd_lb_create(const struct nbrec_load_balancer 
> *nbrec_lb,
>          ds_chomp(&sel_fields, ',');
>          lb->selection_fields = ds_steal_cstr(&sel_fields);
>      }
> +
> +    ovn_lb_get_hairpin_snat_ip(&nbrec_lb->header_.uuid, &nbrec_lb->options,
> +                               &lb->hairpin_snat_ips);
>      return lb;
>  }
>
> @@ -260,6 +281,7 @@ ovn_northd_lb_destroy(struct ovn_northd_lb *lb)
>      free(lb->vips);
>      free(lb->vips_nb);
>      free(lb->selection_fields);
> +    destroy_lport_addresses(&lb->hairpin_snat_ips);
>      free(lb->dps);
>      free(lb);
>  }
> @@ -289,6 +311,9 @@ ovn_controller_lb_create(const struct sbrec_load_balancer 
> *sbrec_lb)
>       * correct value.
>       */
>      lb->n_vips = n_vips;
> +
> +    ovn_lb_get_hairpin_snat_ip(&sbrec_lb->header_.uuid, &sbrec_lb->options,
> +                               &lb->hairpin_snat_ips);
>      return lb;
>  }
>
> @@ -299,5 +324,6 @@ ovn_controller_lb_destroy(struct ovn_controller_lb *lb)
>          ovn_lb_vip_destroy(&lb->vips[i]);
>      }
>      free(lb->vips);
> +    destroy_lport_addresses(&lb->hairpin_snat_ips);
>      free(lb);
>  }
> diff --git a/lib/lb.h b/lib/lb.h
> index 42c580b..dfce51c 100644
> --- a/lib/lb.h
> +++ b/lib/lb.h
> @@ -20,6 +20,7 @@
>  #include <sys/types.h>
>  #include <netinet/in.h>
>  #include "openvswitch/hmap.h"
> +#include "ovn-util.h"
>
>  struct nbrec_load_balancer;
>  struct sbrec_load_balancer;
> @@ -37,6 +38,11 @@ struct ovn_northd_lb {
>      struct ovn_northd_lb_vip *vips_nb;
>      size_t n_vips;
>
> +    struct lport_addresses hairpin_snat_ips; /* IP (v4 and/or v6) to be used
> +                                              * as source for hairpinned
> +                                              * traffic.
> +                                              */
> +
>      size_t n_dps;
>      size_t n_allocated_dps;
>      const struct sbrec_datapath_binding **dps;
> @@ -89,6 +95,11 @@ struct ovn_controller_lb {
>
>      struct ovn_lb_vip *vips;
>      size_t n_vips;
> +
> +    struct lport_addresses hairpin_snat_ips; /* IP (v4 and/or v6) to be used
> +                                              * as source for hairpinned
> +                                              * traffic.
> +                                              */
>  };
>
>  struct ovn_controller_lb *ovn_controller_lb_create(
> diff --git a/lib/ovn-util.c b/lib/ovn-util.c
> index 2136f90..b647106 100644
> --- a/lib/ovn-util.c
> +++ b/lib/ovn-util.c
> @@ -232,6 +232,27 @@ extract_ip_addresses(const char *address, struct 
> lport_addresses *laddrs)
>      return false;
>  }
>
> +/* Extracts at most one IPv4 and at most one IPv6 address from 'address'
> + * which should be of the format 'IP1 [IP2]'.
> + *
> + * Return true if at most one IPv4 address and at most one IPv6 address
> + * is found in 'address'.  IPs must be host IPs, i.e., no unmasked bits.
> + *
> + * The caller must call destroy_lport_addresses().
> + */
> +bool extract_ip_address(const char *address, struct lport_addresses *laddrs)
> +{
> +    if (!extract_ip_addresses(address, laddrs) ||
> +            laddrs->n_ipv4_addrs > 1 ||
> +            laddrs->n_ipv6_addrs > 1 ||
> +            (laddrs->n_ipv4_addrs && laddrs->ipv4_addrs[0].plen != 32) ||
> +            (laddrs->n_ipv6_addrs && laddrs->ipv6_addrs[0].plen != 128)) {
> +        destroy_lport_addresses(laddrs);
> +        return false;
> +    }
> +    return true;
> +}
> +
>  /* Extracts the mac, IPv4 and IPv6 addresses from the
>   * "nbrec_logical_router_port" parameter 'lrp'.  Stores the IPv4 and
>   * IPv6 addresses in the 'ipv4_addrs' and 'ipv6_addrs' fields of
> diff --git a/lib/ovn-util.h b/lib/ovn-util.h
> index b604b07..0823461 100644
> --- a/lib/ovn-util.h
> +++ b/lib/ovn-util.h
> @@ -72,6 +72,7 @@ bool extract_addresses(const char *address, struct 
> lport_addresses *,
>                         int *ofs);
>  bool extract_lsp_addresses(const char *address, struct lport_addresses *);
>  bool extract_ip_addresses(const char *address, struct lport_addresses *);
> +bool extract_ip_address(const char *address, struct lport_addresses *);
>  bool extract_lrp_networks(const struct nbrec_logical_router_port *,
>                            struct lport_addresses *);
>  bool extract_sbrec_binding_first_mac(const struct sbrec_port_binding 
> *binding,
> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
> index 969fbe1..1f9dc65 100644
> --- a/northd/ovn-northd.c
> +++ b/northd/ovn-northd.c
> @@ -3347,6 +3347,7 @@ build_ovn_lbs(struct northd_context *ctx, struct hmap 
> *datapaths,
>          sbrec_load_balancer_set_name(lb->slb, lb->nlb->name);
>          sbrec_load_balancer_set_vips(lb->slb, &lb->nlb->vips);
>          sbrec_load_balancer_set_protocol(lb->slb, lb->nlb->protocol);
> +        sbrec_load_balancer_set_options(lb->slb, &lb->nlb->options);
>          sbrec_load_balancer_set_datapaths(
>              lb->slb, (struct sbrec_datapath_binding **)lb->dps,
>              lb->n_dps);
> @@ -8332,15 +8333,10 @@ get_force_snat_ip(struct ovn_datapath *od, const char 
> *key_type,
>          return false;
>      }
>
> -    if (!extract_ip_addresses(addresses, laddrs) ||
> -        laddrs->n_ipv4_addrs > 1 ||
> -        laddrs->n_ipv6_addrs > 1 ||
> -        (laddrs->n_ipv4_addrs && laddrs->ipv4_addrs[0].plen != 32) ||
> -        (laddrs->n_ipv6_addrs && laddrs->ipv6_addrs[0].plen != 128)) {
> +    if (!extract_ip_address(addresses, laddrs)) {
>          static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
>          VLOG_WARN_RL(&rl, "bad ip %s in options of router "UUID_FMT"",
>                       addresses, UUID_ARGS(&od->key));
> -        destroy_lport_addresses(laddrs);
>          return false;
>      }
>
> @@ -13566,6 +13562,7 @@ main(int argc, char *argv[])
>      add_column_noalert(ovnsb_idl_loop.idl, &sbrec_load_balancer_col_name);
>      add_column_noalert(ovnsb_idl_loop.idl, &sbrec_load_balancer_col_vips);
>      add_column_noalert(ovnsb_idl_loop.idl, 
> &sbrec_load_balancer_col_protocol);
> +    add_column_noalert(ovnsb_idl_loop.idl, &sbrec_load_balancer_col_options);
>      add_column_noalert(ovnsb_idl_loop.idl,
>                         &sbrec_load_balancer_col_external_ids);
>
> diff --git a/ovn-nb.xml b/ovn-nb.xml
> index c2c58d8..58083f1 100644
> --- a/ovn-nb.xml
> +++ b/ovn-nb.xml
> @@ -1644,6 +1644,14 @@
>          Please note using <code>--reject</code> option will disable empty_lb
>          SB controller event for this load balancer.
>        </column>
> +
> +      <column name="options" key="hairpin_snat_ip">
> +        IP to be used as source IP for packets that have been hair-pinned
> +        after load balancing.  The default behavior when the option is not 
> set
> +        is to use the load balancer VIP as source IP.  This option may have
> +        exactly one IPv4 and/or one IPv6 address on it, separated by a space
> +        character.
> +      </column>
>      </group>
>    </table>
>
> diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema
> index b418434..0d20f08 100644
> --- a/ovn-sb.ovsschema
> +++ b/ovn-sb.ovsschema
> @@ -1,7 +1,7 @@
>  {
>      "name": "OVN_Southbound",
> -    "version": "20.14.0",
> -    "cksum": "1412040198 25748",
> +    "version": "20.15.0",
> +    "cksum": "539683023 25965",
>      "tables": {
>          "SB_Global": {
>              "columns": {
> @@ -482,6 +482,11 @@
>                      "type": {"key": {"type": "uuid",
>                                       "refTable": "Datapath_Binding"},
>                               "min": 0, "max": "unlimited"}},
> +                "options": {
> +                     "type": {"key": "string",
> +                              "value": "string",
> +                              "min": 0,
> +                              "max": "unlimited"}},
>                  "external_ids": {
>                      "type": {"key": "string", "value": "string",
>                               "min": 0, "max": "unlimited"}}},
> diff --git a/ovn-sb.xml b/ovn-sb.xml
> index 4c82d51..53fdc15 100644
> --- a/ovn-sb.xml
> +++ b/ovn-sb.xml
> @@ -4233,6 +4233,14 @@ tcp.flags = RST;
>        Datapaths to which this load balancer applies to.
>      </column>
>
> +    <group title="Load_Balancer options">
> +    <column name="options" key="hairpin_snat_ip">
> +      IP to be used as source IP for packets that have been hair-pinned after
> +      load balancing.  This value is automatically populated by
> +      <code>ovn-northd</code>.
> +    </column>
> +    </group>
> +
>      <group title="Common Columns">
>        <column name="external_ids">
>          See <em>External IDs</em> at the beginning of this document.
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 91eb9a3..9fce973 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -2117,6 +2117,12 @@ echo
>  echo "__file__:__line__: check that datapath sw1 has lb0 and lb1 set in the 
> load_balancers column."
>  check_column "$lb0_uuid $lb1_uuid" sb:datapath_binding load_balancers 
> external_ids:name=sw1
>
> +
> +echo
> +echo "__file__:__line__: Set hairpin_snat_ip on lb1 and check that SB DB is 
> updated."
> +check ovn-nbctl --wait=sb set Load_Balancer lb1 
> options:hairpin_snat_ip="42.42.42.42 4242::4242"
> +check_column "$lb1_uuid" sb:load_balancer _uuid name=lb1 
> options='{hairpin_snat_ip="42.42.42.42 4242::4242"}'
> +
>  echo
>  echo "__file__:__line__: Delete load balancer lb1 an check that datapath 
> sw1's load_balancers are updated accordingly."
>
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 9bac94b..c1a972e 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -20814,8 +20814,9 @@ build_tcp_syn() {
>
>  send_ipv4_pkt() {
>      local hv=$1 inport=$2 eth_src=$3 eth_dst=$4
> -    local ip_src=$5 ip_dst=$6 ip_proto=$7 ip_len=$8 ip_chksum=$9
> -    local l4_payload=${10}
> +    local ip_src=$5 ip_dst=$6 ip_proto=$7 ip_len=$8
> +    local l4_payload=$9
> +    local hp_ip_src=${10}
>      local hp_l4_payload=${11}
>      local outfile=${12}
>
> @@ -20823,8 +20824,10 @@ send_ipv4_pkt() {
>
>      local eth=${eth_dst}${eth_src}0800
>      local hp_eth=${eth_src}${eth_dst}0800
> -    local 
> ip=4500${ip_len}00004000${ip_ttl}${ip_proto}${ip_chksum}${ip_src}${ip_dst}
> -    local 
> hp_ip=4500${ip_len}00004000${ip_ttl}${ip_proto}${ip_chksum}${ip_dst}${ip_src}
> +    local ip=4500${ip_len}00004000${ip_ttl}${ip_proto}0000${ip_src}${ip_dst}
> +    ip=$(ip4_csum_inplace $ip)
> +    local 
> hp_ip=4500${ip_len}00004000${ip_ttl}${ip_proto}0000${hp_ip_src}${ip_src}
> +    hp_ip=$(ip4_csum_inplace ${hp_ip})
>      local packet=${eth}${ip}${l4_payload}
>      local hp_packet=${hp_eth}${hp_ip}${hp_l4_payload}
>
> @@ -20836,15 +20839,16 @@ send_ipv6_pkt() {
>      local hv=$1 inport=$2 eth_src=$3 eth_dst=$4
>      local ip_src=$5 ip_dst=$6 ip_proto=$7 ip_len=$8
>      local l4_payload=$9
> -    local hp_l4_payload=${10}
> -    local outfile=${11}
> +    local hp_ip_src=${10}
> +    local hp_l4_payload=${11}
> +    local outfile=${12}
>
>      local ip_ttl=40
>
>      local eth=${eth_dst}${eth_src}86dd
>      local hp_eth=${eth_src}${eth_dst}86dd
>      local ip=60000000${ip_len}${ip_proto}${ip_ttl}${ip_src}${ip_dst}
> -    local hp_ip=60000000${ip_len}${ip_proto}${ip_ttl}${ip_dst}${ip_src}
> +    local hp_ip=60000000${ip_len}${ip_proto}${ip_ttl}${hp_ip_src}${ip_src}
>      local packet=${eth}${ip}${l4_payload}
>      local hp_packet=${hp_eth}${hp_ip}${hp_l4_payload}
>
> @@ -20886,18 +20890,35 @@ ovn-nbctl lsp-add sw sw-rtr                       \
>
>  ovn-nbctl --wait=hv sync
>
> -# Inject IPv4 TCP packet from lsp.
> +ovn-sbctl dump-flows > sbflows
> +AT_CAPTURE_FILE([sbflows])
>  > expected
> +
> +# Inject IPv4 TCP packet from lsp.
>  tcp_payload=$(build_tcp_syn 84d0 1f90 05a7)
>  hp_tcp_payload=$(build_tcp_syn 84d0 0fc9 156e)
>  send_ipv4_pkt hv1 hv1-vif1 000000000001 000000000100 \
>      $(ip_to_hex 42 42 42 1) $(ip_to_hex 88 88 88 88) \
> -    06 0028 35f5 \
> -    ${tcp_payload} ${hp_tcp_payload} \
> +    06 0028 \
> +    ${tcp_payload} \
> +    $(ip_to_hex 88 88 88 88) ${hp_tcp_payload} \
>      expected
>
> -ovn-sbctl dump-flows > sbflows
> -AT_CAPTURE_FILE([sbflows])
> +# Check that traffic is hairpinned.
> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
> +
> +# Change LB Hairpin SNAT IP.
> +# Also flush conntrack to avoid reusing an existing entry.
> +as hv1 ovs-appctl dpctl/flush-conntrack
> +ovn-nbctl --wait=hv set load_balancer lb-ipv4-tcp 
> options:hairpin_snat_ip="88.88.88.87"
> +# Inject IPv4 TCP packet from lsp.
> +hp_tcp_payload=$(build_tcp_syn 84d0 0fc9 156f)
> +send_ipv4_pkt hv1 hv1-vif1 000000000001 000000000100 \
> +    $(ip_to_hex 42 42 42 1) $(ip_to_hex 88 88 88 88) \
> +    06 0028 \
> +    ${tcp_payload} \
> +    $(ip_to_hex 88 88 88 87) ${hp_tcp_payload} \
> +    expected
>
>  # Check that traffic is hairpinned.
>  OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
> @@ -20907,8 +20928,25 @@ udp_payload=$(build_udp 84d0 0fc8 6666)
>  hp_udp_payload=$(build_udp 84d0 07e5 6e49)
>  send_ipv4_pkt hv1 hv1-vif1 000000000001 000000000100 \
>      $(ip_to_hex 42 42 42 1) $(ip_to_hex 88 88 88 88) \
> -    11 001e 35f4 \
> -    ${udp_payload} ${hp_udp_payload} \
> +    11 001e \
> +    ${udp_payload} \
> +    $(ip_to_hex 88 88 88 88) ${hp_udp_payload} \
> +    expected
> +
> +# Check that traffic is hairpinned.
> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
> +
> +# Change LB Hairpin SNAT IP.
> +# Also flush conntrack to avoid reusing an existing entry.
> +as hv1 ovs-appctl dpctl/flush-conntrack
> +ovn-nbctl --wait=hv set load_balancer lb-ipv4-udp 
> options:hairpin_snat_ip="88.88.88.87"
> +# Inject IPv4 UDP packet from lsp.
> +hp_udp_payload=$(build_udp 84d0 07e5 6e4a)
> +send_ipv4_pkt hv1 hv1-vif1 000000000001 000000000100 \
> +    $(ip_to_hex 42 42 42 1) $(ip_to_hex 88 88 88 88) \
> +    11 001e \
> +    ${udp_payload} \
> +    $(ip_to_hex 88 88 88 87) ${hp_udp_payload} \
>      expected
>
>  # Check that traffic is hairpinned.
> @@ -20920,7 +20958,25 @@ hp_tcp_payload=$(build_tcp_syn 84d0 0fc9 4fc0)
>  send_ipv6_pkt hv1 hv1-vif1 000000000001 000000000100 \
>      42000000000000000000000000000001 88000000000000000000000000000088 \
>      06 0014 \
> -    ${tcp_payload} ${hp_tcp_payload} \
> +    ${tcp_payload} \
> +    88000000000000000000000000000088 ${hp_tcp_payload} \
> +    expected
> +
> +# Check that traffic is hairpinned.
> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
> +
> +# Change LB Hairpin SNAT IP.
> +# Also flush conntrack to avoid reusing an existing entry.
> +as hv1 ovs-appctl dpctl/flush-conntrack
> +ovn-nbctl --wait=hv set load_balancer lb-ipv6-tcp 
> options:hairpin_snat_ip="8800::0087"
> +
> +# Inject IPv6 TCP packet from lsp.
> +hp_tcp_payload=$(build_tcp_syn 84d0 0fc9 4fc1)
> +send_ipv6_pkt hv1 hv1-vif1 000000000001 000000000100 \
> +    42000000000000000000000000000001 88000000000000000000000000000088 \
> +    06 0014 \
> +    ${tcp_payload} \
> +    88000000000000000000000000000087 ${hp_tcp_payload} \
>      expected
>
>  # Check that traffic is hairpinned.
> @@ -20932,12 +20988,27 @@ hp_udp_payload=$(build_udp 84d0 07e5 a89b)
>  send_ipv6_pkt hv1 hv1-vif1 000000000001 000000000100 \
>      42000000000000000000000000000001 88000000000000000000000000000088 \
>      11 000a \
> -    ${udp_payload} ${hp_udp_payload} \
> +    ${udp_payload} \
> +    88000000000000000000000000000088 ${hp_udp_payload} \
>      expected
>
> -# Check that traffic is hairpinned.
> +Check that traffic is hairpinned.
>  OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
>
> +# Change LB Hairpin SNAT IP.
> +# Also flush conntrack to avoid reusing an existing entry.
> +as hv1 ovs-appctl dpctl/flush-conntrack
> +ovn-nbctl --wait=hv set load_balancer lb-ipv6-udp 
> options:hairpin_snat_ip="8800::0087"
> +
> +# Inject IPv6 UDP packet from lsp.
> +hp_udp_payload=$(build_udp 84d0 07e5 a89b)
> +send_ipv6_pkt hv1 hv1-vif1 000000000001 000000000100 \
> +    42000000000000000000000000000001 88000000000000000000000000000088 \
> +    11 000a \
> +    ${udp_payload} \
> +    88000000000000000000000000000087 ${hp_udp_payload} \
> +    expected
> +
>  OVN_CLEANUP([hv1])
>  AT_CLEANUP
>
> @@ -23157,7 +23228,7 @@ 
> priority=100,tcp,metadata=0x1,nw_src=42.42.42.1,nw_dst=88.88.88.88,tp_src=4041
>  a
>  ])
>
>  AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=70 | grep -v NXST | cut 
> -d ' ' -f8-], [0], [dnl
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
>  ])
>
>  AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=68], [0], [dnl
> @@ -23191,8 +23262,8 @@ 
> priority=100,tcp,metadata=0x1,nw_src=52.52.52.52,nw_dst=88.88.88.90,tp_src=4042
>  ])
>
>  AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=70 | grep -v NXST | cut 
> -d ' ' -f8-], [0], [dnl
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
>  ])
>
>  AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=68], [0], [dnl
> @@ -23228,8 +23299,8 @@ 
> priority=100,tcp,metadata=0x1,nw_src=52.52.52.52,nw_dst=88.88.88.90,tp_src=4042
>  ])
>
>  AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=70 | grep -v NXST | cut 
> -d ' ' -f8-], [0], [dnl
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
>  ])
>
>  check ovn-nbctl --wait=hv ls-lb-add sw0 lb-ipv4-udp
> @@ -23257,8 +23328,9 @@ 
> priority=100,udp,metadata=0x1,nw_src=42.42.42.1,nw_dst=88.88.88.88,tp_src=2021
>  a
>  ])
>
>  AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=70 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=17,ct_tp_dst=4040,udp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
>  ])
>
>  AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=68 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> @@ -23276,8 +23348,9 @@ 
> priority=100,udp,metadata=0x1,nw_src=42.42.42.1,nw_dst=88.88.88.88,tp_src=2021
>  a
>  ])
>
>  AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=70 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=17,ct_tp_dst=4040,udp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
>  ])
>
>  check ovn-nbctl --wait=hv ls-lb-add sw0 lb-ipv6-tcp
> @@ -23307,9 +23380,10 @@ 
> priority=100,udp,metadata=0x1,nw_src=42.42.42.1,nw_dst=88.88.88.88,tp_src=2021
>  a
>  ])
>
>  AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=70 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> -priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ipv6,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=6,ct_tp_dst=8080,tcp6,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=17,ct_tp_dst=4040,udp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
>  ])
>
>  AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=68 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> @@ -23329,9 +23403,10 @@ 
> priority=100,udp,metadata=0x1,nw_src=42.42.42.1,nw_dst=88.88.88.88,tp_src=2021
>  a
>  ])
>
>  AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=70 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> -priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ipv6,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=6,ct_tp_dst=8080,tcp6,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=17,ct_tp_dst=4040,udp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
>  ])
>
>  check ovn-nbctl --wait=hv ls-lb-add sw0 lb-ipv6-udp
> @@ -23363,9 +23438,11 @@ 
> priority=100,udp6,metadata=0x1,ipv6_src=4200::1,ipv6_dst=8800::88,tp_src=2021 
> ac
>  ])
>
>  AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=70 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> -priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ipv6,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=17,ct_tp_dst=4040,udp6,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=6,ct_tp_dst=8080,tcp6,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=17,ct_tp_dst=4040,udp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
>  ])
>
>  AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=68 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> @@ -23387,9 +23464,11 @@ 
> priority=100,udp6,metadata=0x1,ipv6_src=4200::1,ipv6_dst=8800::88,tp_src=2021 
> ac
>  ])
>
>  AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=70 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> -priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ipv6,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=17,ct_tp_dst=4040,udp6,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=6,ct_tp_dst=8080,tcp6,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=17,ct_tp_dst=4040,udp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
>  ])
>
>  check ovn-nbctl --wait=hv ls-lb-add sw1 lb-ipv6-udp
> @@ -23424,10 +23503,12 @@ 
> priority=100,udp6,metadata=0x2,ipv6_src=4200::1,ipv6_dst=8800::88,tp_src=2021 
> ac
>  ])
>
>  AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=70 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> -priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ipv6,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> -priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ipv6,metadata=0x2 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=17,ct_tp_dst=4040,udp6,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=17,ct_tp_dst=4040,udp6,metadata=0x2
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=6,ct_tp_dst=8080,tcp6,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=17,ct_tp_dst=4040,udp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
>  ])
>
>  AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=68 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> @@ -23450,10 +23531,12 @@ 
> priority=100,udp6,metadata=0x2,ipv6_src=4200::1,ipv6_dst=8800::88,tp_src=2021 
> ac
>  ])
>
>  AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=70 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> -priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ipv6,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> -priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ipv6,metadata=0x2 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=17,ct_tp_dst=4040,udp6,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=17,ct_tp_dst=4040,udp6,metadata=0x2
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=6,ct_tp_dst=8080,tcp6,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=17,ct_tp_dst=4040,udp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.90,ct_nw_proto=6,ct_tp_dst=8080,tcp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.90))
>  ])
>
>  as hv2 ovs-vsctl del-port hv2-vif1
> @@ -23502,9 +23585,10 @@ 
> priority=100,udp6,metadata=0x2,ipv6_src=4200::1,ipv6_dst=8800::88,tp_src=2021 
> ac
>  ])
>
>  AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=70 | grep -v NXST | cut 
> -d ' ' -f8- | sort], [0], [dnl
> -priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ipv6,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> -priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ipv6,metadata=0x2 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> -priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ip,metadata=0x1 
> actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=17,ct_tp_dst=4040,udp6,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=17,ct_tp_dst=4040,udp6,metadata=0x2
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_ipv6_dst=8800::88,ct_nw_proto=6,ct_tp_dst=8080,tcp6,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=8800::88))
> +priority=100,ct_state=+trk+dnat,ct_nw_dst=88.88.88.88,ct_nw_proto=17,ct_tp_dst=4040,udp,metadata=0x1
>  actions=ct(commit,zone=NXM_NX_REG12[[0..15]],nat(src=88.88.88.88))
>  ])
>
>  check ovn-nbctl --wait=hv ls-del sw0
> --
> 1.8.3.1
>
> _______________________________________________
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to