On Thu, Jun 3, 2021 at 2:50 PM Mark Michelson <mmich...@redhat.com> wrote:
>
> Dealing with NAT and load balancer IPs has been a bit of a pain point.
> It requires creating static routes if east-west traffic to those
> addresses is desired. Further, it requires ARPs to be sent between the
> logical routers in order to create MAC Bindings.
>
> This commit seeks to make things easier. NAT and load balancer addresess
> automatically have IP routing logical flows and ARP resolution logical
> flows created for reachable routers. This eliminates the need to create
> static routes, and it also eliminates the need for ARPs to be sent
> between logical routers.
>
> In this commit, the behavior is not optional. The next commit will
> introduce configuration to make the behavior optional.
>
> Signed-off-by: Mark Michelson <mmich...@redhat.com>
> ---
>  northd/ovn-northd.c  | 133 ++++++++++++++++++++++++++-
>  northd/ovn_northd.dl |  57 ++++++++++++
>  tests/ovn-northd.at  | 214 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 399 insertions(+), 5 deletions(-)
>

Hi Mark,

Thanks for the patch series.

Overall the patch looks good to me.

There are a couple of  things which need to be addressed
  - You need to rebase the whole series.

  -  Some test cases are failing and libasan is complaining about
memory leaks - https://github.com/ovsrobot/ovn/runs/2740075247
    ******
   ==348806==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 912 byte(s) in 57 object(s) allocated from:
    #0 0x7f01a1b40d1f in __interceptor_malloc (/lib64/libasan.so.6+0xaed1f)
    #1 0x5c2c6d in xmalloc__ ../lib/util.c:137
    #2 0x5c2c6d in xmalloc ../lib/util.c:172
    #3 0x4102a5 in assign_routable_addresses ../northd/ovn-northd.c:1488
    #4 0x418933 in join_logical_ports ../northd/ovn-northd.c:2468
    #5 0x422f91 in build_ports ../northd/ovn-northd.c:3688
    #6 0x461f31 in ovnnb_db_run ../northd/ovn-northd.c:13452
    #7 0x464ffb in ovn_db_run ../northd/ovn-northd.c:14123
    #8 0x46860c in main ../northd/ovn-northd.c:14612
    #9 0x7f01a129fb74 in __libc_start_main (/lib64/libc.so.6+0x27b74)

Direct leak of 57 byte(s) in 57 object(s) allocated from:
    #0 0x7f01a1b40d1f in __interceptor_malloc (/lib64/libasan.so.6+0xaed1f)
    #1 0x5c2f79 in xcalloc__ ../lib/util.c:121
    #2 0x5c2f79 in xcalloc ../lib/util.c:158
    #3 0x418933 in join_logical_ports ../northd/ovn-northd.c:2468
    #4 0x422f91 in build_ports ../northd/ovn-northd.c:3688
    #5 0x461f31 in ovnnb_db_run ../northd/ovn-northd.c:13452
    #6 0x464ffb in ovn_db_run ../northd/ovn-northd.c:14123
    #7 0x46860c in main ../northd/ovn-northd.c:14612
    #8 0x7f01a129fb74 in __libc_start_main (/lib64/libc.so.6+0x27b74)
*******

  - You need to add missing documentation in ovn-northd.8.xml for the
newly added lflows.


Thanks
Numan


> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
> index ef4f5b790..3b9cad80b 100644
> --- a/northd/ovn-northd.c
> +++ b/northd/ovn-northd.c
> @@ -1353,6 +1353,21 @@ build_datapaths(struct northd_context *ctx, struct 
> hmap *datapaths,
>      }
>  }
>
> +/* Structure representing logical router port
> + * routable addresses. This includes DNAT and Load Balancer
> + * addresses. This structure will only be filled in if the
> + * router port is a gateway router port. Otherwise, all pointers
> + * will be NULL and n_addrs will be 0.
> + */
> +struct ovn_port_routable_addresses {
> +    /* Array of address strings suitable for writing to a database table */
> +    char **addresses;
> +    /* The addresses field parsed into component parts */
> +    struct lport_addresses *laddrs;
> +    /* Number of items in each of the above arrays */
> +    size_t n_addrs;
> +};
> +
>  /* A logical switch port or logical router port.
>   *
>   * In steady state, an ovn_port points to a northbound Logical_Switch_Port
> @@ -1396,6 +1411,8 @@ struct ovn_port {
>
>      struct lport_addresses lrp_networks;
>
> +    struct ovn_port_routable_addresses routables;
> +
>      /* Logical port multicast data. */
>      struct mcast_port_info mcast_info;
>
> @@ -1422,6 +1439,48 @@ struct ovn_port {
>      struct ovs_list list;       /* In list of similar records. */
>  };
>
> +static void
> +destroy_routable_addresses(struct ovn_port_routable_addresses *ra)
> +{
> +    if (ra->n_addrs == 0) {
> +        return;
> +    }
> +
> +    for (size_t i = 0; i < ra->n_addrs; i++) {
> +        free(ra->addresses[i]);
> +        destroy_lport_addresses(&ra->laddrs[i]);
> +    }
> +    free(ra->addresses);
> +    free(ra->laddrs);
> +}
> +
> +static char **get_nat_addresses(const struct ovn_port *op, size_t *n);
> +
> +static void
> +assign_routable_addresses(struct ovn_port *op)
> +{
> +    size_t n;
> +    char **nats = get_nat_addresses(op, &n);
> +
> +    if (!nats) {
> +        return;
> +    }
> +
> +    struct lport_addresses *laddrs = xcalloc(n, sizeof(*laddrs));
> +    for (size_t i = 0; i < n; i++) {
> +        int ofs;
> +        if (!extract_addresses(nats[i], &laddrs[i], &ofs)){
> +            continue;
> +        }
> +    }
> +
> +    /* Everything seems to have worked out */
> +    op->routables.addresses = nats;
> +    op->routables.laddrs = laddrs;
> +    op->routables.n_addrs = n;
> +}
> +
> +
>  static void
>  ovn_port_set_nb(struct ovn_port *op,
>                  const struct nbrec_logical_switch_port *nbsp,
> @@ -1471,6 +1530,8 @@ ovn_port_destroy(struct hmap *ports, struct ovn_port 
> *port)
>          }
>          free(port->ps_addrs);
>
> +        destroy_routable_addresses(&port->routables);
> +
>          destroy_lport_addresses(&port->lrp_networks);
>          free(port->json_key);
>          free(port->key);
> @@ -2378,6 +2439,8 @@ join_logical_ports(struct northd_context *ctx,
>                       * use during flow creation. */
>                      od->l3dgw_port = op;
>                      od->l3redirect_port = crp;
> +
> +                    assign_routable_addresses(op);
>                  }
>              }
>          }
> @@ -2501,7 +2564,7 @@ get_nat_addresses(const struct ovn_port *op, size_t *n)
>  {
>      size_t n_nats = 0;
>      struct eth_addr mac;
> -    if (!op->nbrp || !op->od || !op->od->nbr
> +    if (!op || !op->nbrp || !op->od || !op->od->nbr
>          || (!op->od->nbr->n_nat && !op->od->nbr->n_load_balancer)
>          || !eth_addr_from_string(op->nbrp->mac, &mac)) {
>          *n = n_nats;
> @@ -3089,7 +3152,6 @@ ovn_port_update_sbrec(struct northd_context *ctx,
>              } else {
>                  sbrec_port_binding_set_options(op->sb, NULL);
>              }
> -
>              const char *nat_addresses = smap_get(&op->nbsp->options,
>                                             "nat-addresses");
>              size_t n_nats = 0;
> @@ -3145,6 +3207,7 @@ ovn_port_update_sbrec(struct northd_context *ctx,
>              if (add_router_port_garp) {
>                  struct ds garp_info = DS_EMPTY_INITIALIZER;
>                  ds_put_format(&garp_info, "%s", op->peer->lrp_networks.ea_s);
> +
>                  for (size_t i = 0; i < op->peer->lrp_networks.n_ipv4_addrs;
>                       i++) {
>                      ds_put_format(&garp_info, " %s",
> @@ -3161,7 +3224,6 @@ ovn_port_update_sbrec(struct northd_context *ctx,
>                  nats[n_nats - 1] = ds_steal_cstr(&garp_info);
>                  ds_destroy(&garp_info);
>              }
> -
>              sbrec_port_binding_set_nat_addresses(op->sb,
>                                                   (const char **) nats, 
> n_nats);
>              for (size_t i = 0; i < n_nats; i++) {
> @@ -9876,7 +9938,7 @@ build_ND_RA_flows_for_lrouter(struct ovn_datapath *od, 
> struct hmap *lflows)
>   */
>  static void
>  build_ip_routing_flows_for_lrouter_port(
> -        struct ovn_port *op, struct hmap *lflows)
> +        struct ovn_port *op, struct hmap *ports,struct hmap *lflows)
>  {
>      if (op->nbrp) {
>
> @@ -9893,6 +9955,31 @@ build_ip_routing_flows_for_lrouter_port(
>                        op->lrp_networks.ipv6_addrs[i].plen, NULL, false,
>                        &op->nbrp->header_, false);
>          }
> +    } else if (lsp_is_router(op->nbsp)) {
> +        struct ovn_port *peer = ovn_port_get_peer(ports, op);
> +        if (!peer || !peer->nbrp || !peer->lrp_networks.n_ipv4_addrs) {
> +            return;
> +        }
> +
> +        for (int i = 0; i < op->od->n_router_ports; i++) {
> +            struct ovn_port *router_port = ovn_port_get_peer(
> +                    ports, op->od->router_ports[i]);
> +            if (!router_port || !router_port->nbrp || router_port == peer) {
> +                continue;
> +            }
> +
> +            struct ovn_port_routable_addresses *ra = &router_port->routables;
> +            for (size_t j = 0; j < ra->n_addrs; j++) {
> +                struct lport_addresses *laddrs = &ra->laddrs[j];
> +                for (size_t k = 0; k < laddrs->n_ipv4_addrs; k++) {
> +                    add_route(lflows, peer->od, peer,
> +                              peer->lrp_networks.ipv4_addrs[0].addr_s,
> +                              laddrs->ipv4_addrs[k].network_s,
> +                              laddrs->ipv4_addrs[k].plen, NULL, false,
> +                              &peer->nbrp->header_, false);
> +                }
> +            }
> +        }
>      }
>  }
>
> @@ -10071,6 +10158,36 @@ build_arp_resolve_flows_for_lrouter(
>      }
>  }
>
> +static void
> +routable_addresses_to_lflows(struct hmap *lflows, struct ovn_port 
> *router_port,
> +                             struct ovn_port *peer, struct ds *match,
> +                             struct ds *actions)
> +{
> +    struct ovn_port_routable_addresses *ra = &router_port->routables;
> +    if (!ra->n_addrs) {
> +        return;
> +    }
> +
> +    for (size_t i = 0; i < ra->n_addrs; i++) {
> +        ds_clear(match);
> +        ds_put_format(match, "outport == %s && "REG_NEXT_HOP_IPV4" == {", 
> peer->json_key);
> +        bool first = true;
> +        for (size_t j = 0; j < ra->laddrs[i].n_ipv4_addrs; j++) {
> +            if (!first) {
> +                ds_put_cstr(match, ", ");
> +            }
> +            ds_put_cstr(match, ra->laddrs[i].ipv4_addrs[j].addr_s);
> +            first = false;
> +        }
> +        ds_put_cstr(match, "}");
> +
> +        ds_clear(actions);
> +        ds_put_format(actions, "eth.dst = %s; next;", ra->laddrs[i].ea_s);
> +        ovn_lflow_add(lflows, peer->od, S_ROUTER_IN_ARP_RESOLVE, 100,
> +                      ds_cstr(match), ds_cstr(actions));
> +    }
> +}
> +
>  /* Local router ingress table ARP_RESOLVE: ARP Resolution.
>   *
>   * Any unicast packet that reaches this table is an IP packet whose
> @@ -10393,6 +10510,12 @@ build_arp_resolve_flows_for_lrouter_port(
>                                          ds_cstr(match), ds_cstr(actions),
>                                          &op->nbsp->header_);
>              }
> +
> +            if (smap_get(&peer->od->nbr->options, "chassis") ||
> +                (peer->od->l3dgw_port && peer == peer->od->l3dgw_port)) {
> +                routable_addresses_to_lflows(lflows, router_port, peer,
> +                                             match, actions);
> +            }
>          }
>      }
>
> @@ -11946,7 +12069,7 @@ build_lswitch_and_lrouter_iterate_by_op(struct 
> ovn_port *op,
>                                            &lsi->actions);
>      build_neigh_learning_flows_for_lrouter_port(op, lsi->lflows, &lsi->match,
>                                                  &lsi->actions);
> -    build_ip_routing_flows_for_lrouter_port(op, lsi->lflows);
> +    build_ip_routing_flows_for_lrouter_port(op, lsi->ports, lsi->lflows);
>      build_ND_RA_flows_for_lrouter_port(op, lsi->lflows, &lsi->match,
>                                         &lsi->actions);
>      build_arp_resolve_flows_for_lrouter_port(op, lsi->lflows, lsi->ports,
> diff --git a/northd/ovn_northd.dl b/northd/ovn_northd.dl
> index 60ace7e61..610bfbfb2 100644
> --- a/northd/ovn_northd.dl
> +++ b/northd/ovn_northd.dl
> @@ -23,6 +23,7 @@ import multicast
>  import helpers
>  import ipam
>  import vec
> +import set
>
>  index Logical_Flow_Index() on sb::Out_Logical_Flow()
>
> @@ -6468,6 +6469,45 @@ Route(key, dst.port, dst.src_ip, Some{dst.nexthop}) :-
>      dsts.size() == 1,
>      Some{var dst} = dsts.nth(0).
>
> +/* Create routes from peer to port's routable addresses */
> +Route(key, peer, src_ip, None) :-
> +    RouterPortRoutableAddresses(port, addresses),
> +    FirstHopRouterPortRoutableAddresses(port, peer_uuid),
> +    peer_lrp in &nb::Logical_Router_Port(._uuid = peer_uuid),
> +    peer in &RouterPort(.lrp = peer_lrp, .networks = networks),
> +    Some{var src} = networks.ipv4_addrs.first(),
> +    var src_ip = IPv4{src.addr},
> +    var addr = FlatMap(addresses),
> +    var ip4_addr = FlatMap(addr.ipv4_addrs),
> +    var key = RouteKey{DstIp, IPv4{ip4_addr.addr}, ip4_addr.plen}.
> +
> +/* This relation indicates that logical router port "port" has routable
> + * addresses (i.e. DNAT and Load Balancer VIPs) and that logical router
> + * port "peer" is reachable via a hop across a single logical switch.
> + */
> +relation FirstHopRouterPortRoutableAddresses(
> +    port: uuid,
> +    peer: uuid)
> +FirstHopRouterPortRoutableAddresses(port_uuid, peer_uuid) :-
> +    FirstHopLogicalRouter(r1, ls),
> +    FirstHopLogicalRouter(r2, ls),
> +    r1 != r2,
> +    LogicalRouterPort(port_uuid, r1),
> +    LogicalRouterPort(peer_uuid, r2),
> +    RouterPortRoutableAddresses(.rport = port_uuid),
> +    lrp in &nb::Logical_Router_Port(._uuid = port_uuid),
> +    peer_lrp in &nb::Logical_Router_Port(._uuid = peer_uuid),
> +    LogicalSwitchRouterPort(_, lrp.name, ls),
> +    LogicalSwitchRouterPort(_, peer_lrp.name, ls).
> +
> +relation RouterPortRoutableAddresses(
> +    rport: uuid,
> +    addresses: Set<lport_addresses>)
> +RouterPortRoutableAddresses(port.lrp._uuid, addresses) :-
> +    port in &RouterPort(.is_redirect = true),
> +    var addresses = get_nat_addresses(port).filter_map(extract_addresses),
> +    addresses != set_empty().
> +
>  /* Return a vector of pairs (1, set[0]), ... (n, set[n - 1]). */
>  function numbered_vec(set: Set<'A>) : Vec<(bit<16>, 'A)> = {
>      var vec = vec_with_capacity(set.size());
> @@ -6956,6 +6996,23 @@ Flow(.logical_datapath = lr_uuid,
>      snat_ips.contains_key(IPv6{addr.addr}),
>      var match_ips = "${addr.addr}".group_by((lr_uuid, lrp_uuid)).to_vec().
>
> +/* Create ARP resolution flows for NAT and LB addresses for first hop
> + * logical routers
> + */
> +Flow(.logical_datapath = peer.router._uuid,
> +     .stage = s_ROUTER_IN_ARP_RESOLVE(),
> +     .priority = 100,
> +     .__match = "outport == ${peer.json_name} && " ++ rEG_NEXT_HOP() ++ " == 
> {${ips}}",
> +     .actions = "eth.dst = ${addr.ea}; next;",
> +     .external_ids = stage_hint(lrp._uuid)) :-
> +     RouterPortRoutableAddresses(port, addresses),
> +     FirstHopRouterPortRoutableAddresses(port, peer_uuid),
> +     peer in &RouterPort(.lrp = lrp),
> +     lrp._uuid == peer_uuid,
> +     not peer.router.options.get_bool_def("dynamic_neigh_routers", false),
> +     var addr = FlatMap(addresses),
> +     var ips = addr.ipv4_addrs.map(|a| a.addr.to_string()).join(", ").
> +
>  /* This is a logical switch port that backs a VM or a container.
>   * Extract its addresses. For each of the address, go through all
>   * the router ports attached to the switch (to which this port
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 3c2aef4b0..12a8e47b4 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -3594,3 +3594,217 @@ check ovn-nbctl --wait=sb sync
>  OVS_APP_EXIT_AND_WAIT([NORTHD_TYPE])
>  AT_CLEANUP
>  ])
> +
> +# XXX This test currently only runs for ovn-northd.c. The test fails
> +# with ovn-northd-ddlog because of the section where 2 HA_Chassis_Groups
> +# are used by 2 routers. For some reason, this causes ovn-northd-ddlog
> +# to stop processing new changes to the northbound database and to
> +# seemingly infinitely loop. This issue has been reported, but there is
> +# currently no fix for it. Once this issue is fixed, we can run this
> +# test for both C and DDLog versions of northd.
> +AT_SETUP([ovn -- NAT and Load Balancer flows])
> +
> +# Determine if expected flows are present. The only parameter to this
> +# function is the number of expected flows per NAT destination address.
> +# This should always be either 0 or 1. 0 means that we do not expect
> +# lflows to be present. 1 means we expect an lflow to be present
> +check_lflows() {
> +    expected=$1
> +    ro1_flows=$(ovn-sbctl lflow-list ro1)
> +
> +    ro1_ip_routing=$(grep lr_in_ip_routing <<< "$ro1_flows")
> +    match=$(grep -c "match=(ip4.dst == 20.0.0.100/32)" <<< "$ro1_ip_routing")
> +    AT_CHECK([test "$expected" = "$match"])
> +
> +    ro1_arp_resolve=$(grep lr_in_arp_resolve <<< "$ro1_flows")
> +    match=$(grep -c 'match=(outport == "ro1-sw" && reg0 == {20.0.0.100})' 
> <<< "$ro1_arp_resolve")
> +    AT_CHECK([test "$expected" = "$match"])
> +
> +    ro2_flows=$(ovn-sbctl lflow-list ro2)
> +
> +    ro2_ip_routing=$(grep lr_in_ip_routing <<< "$ro2_flows")
> +    match=$(grep -c "match=(ip4.dst == 10.0.0.100/32)" <<< "$ro2_ip_routing")
> +    AT_CHECK([test "$expected" = "$match"])
> +
> +    ro2_arp_resolve=$(grep lr_in_arp_resolve <<< "$ro2_flows")
> +    match=$(grep -c 'match=(outport == "ro2-sw" && reg0 == {10.0.0.100})' 
> <<< "$ro2_arp_resolve")
> +    AT_CHECK([test "$expected" = "$match"])
> +}
> +
> +ovn_start
> +
> +AS_BOX([Setting up the logical network])
> +
> +check ovn-nbctl ls-add sw
> +
> +check ovn-nbctl lr-add ro1
> +check ovn-nbctl lrp-add ro1 ro1-sw 00:00:00:00:00:01 10.0.0.1/24
> +check ovn-nbctl lsp-add sw sw-ro1
> +
> +check ovn-nbctl lr-add ro2
> +check ovn-nbctl lrp-add ro2 ro2-sw 00:00:00:00:00:02 20.0.0.1/24
> +check ovn-nbctl --wait=sb lsp-add sw sw-ro2
> +
> +check ovn-nbctl ls-add ls1
> +check ovn-nbctl lsp-add ls1 vm1
> +check ovn-nbctl lsp-set-addresses vm1 "00:00:00:00:01:02 192.168.1.2"
> +check ovn-nbctl lrp-add ro1 ro1-ls1 00:00:00:00:01:01 192.168.1.1/24
> +check ovn-nbctl lsp-add ls1 ls1-ro1
> +check ovn-nbctl lsp-set-type ls1-ro1 router
> +check ovn-nbctl lsp-set-addresses ls1-ro1 router
> +check ovn-nbctl lsp-set-options ls1-ro1 router-port=ro1-ls1
> +
> +check ovn-nbctl ls-add ls2
> +check ovn-nbctl lsp-add ls2 vm2
> +check ovn-nbctl lsp-set-addresses vm2 "00:00:00:00:02:02 192.168.2.2"
> +check ovn-nbctl lrp-add ro2 ro2-ls2 00:00:00:00:02:01 192.168.2.1/24
> +check ovn-nbctl lsp-add ls2 ls2-ro2
> +check ovn-nbctl lsp-set-type ls2-ro2 router
> +check ovn-nbctl lsp-set-addresses ls2-ro2 router
> +check ovn-nbctl lsp-set-options ls2-ro2 router-port=ro2-ls2
> +
> +check ovn-nbctl ha-chassis-group-add grp1
> +check ovn-nbctl ha-chassis-group-add-chassis grp1 hv1 100
> +grp1_uuid=$(ovn-nbctl --columns=_uuid --bare find HA_Chassis_group name=grp1)
> +
> +check ovn-nbctl ha-chassis-group-add grp2
> +check ovn-nbctl ha-chassis-group-add-chassis grp2 hv2 100
> +grp2_uuid=$(ovn-nbctl --columns=_uuid --bare find HA_Chassis_group name=grp2)
> +
> +AS_BOX([Checking that unconnected logical switch ports generate no lflows])
> +
> +check_lflows 0
> +
> +AS_BOX([Checking that connected logical switch ports have no lflows for 
> non-gateway ports])
> +
> +check ovn-nbctl lsp-set-type sw-ro1 router
> +check ovn-nbctl lsp-set-addresses sw-ro1 router
> +check ovn-nbctl lsp-set-options sw-ro1 router-port=ro1-sw
> +
> +check ovn-nbctl lsp-set-type sw-ro2 router
> +check ovn-nbctl lsp-set-addresses sw-ro2 router
> +check ovn-nbctl --wait=sb lsp-set-options sw-ro2 router-port=ro2-sw
> +
> +check_lflows 0
> +
> +AS_BOX([Checking that NAT flows are not installed for non-gateway routers])
> +
> +check ovn-nbctl lr-nat-add ro1 dnat 10.0.0.100 192.168.1.100
> +check ovn-nbctl lr-nat-add ro2 dnat 20.0.0.100 192.168.2.100
> +
> +check_lflows 0
> +
> +AS_BOX([Checking that NAT flows are installed for gateway routers])
> +
> +check ovn-nbctl lrp-set-gateway-chassis ro1-sw hv1 100
> +check ovn-nbctl --wait=sb lrp-set-gateway-chassis ro2-sw hv2 100
> +
> +check_lflows 1
> +
> +AS_BOX([Checking that NAT flows are not installed for routers with gateway 
> chassis removed])
> +
> +check ovn-nbctl lrp-del-gateway-chassis ro1-sw hv1
> +check ovn-nbctl --wait=sb lrp-del-gateway-chassis ro2-sw hv2
> +
> +check_lflows 0
> +
> +AS_BOX([Checking that NAT flows are installed for routers with 
> HA_Chassis_Group])
> +
> +check ovn-nbctl set logical_router_port ro1-sw ha_chassis_group="$grp1_uuid"
> +check ovn-nbctl --wait=sb set logical_router_port ro2-sw 
> ha_chassis_group="$grp2_uuid"
> +
> +check_lflows 1
> +
> +AS_BOX([Checking that NAT flows are not installed for routers with 
> HA_Chassis_Group removed])
> +
> +check ovn-nbctl clear logical_router_port ro1-sw ha_chassis_group
> +check ovn-nbctl --wait=sb clear logical_router_port ro2-sw ha_chassis_group
> +
> +check_lflows 0
> +
> +AS_BOX([Checking that Floating IP NAT flows are not installed with no 
> gateway port set])
> +
> +check ovn-nbctl lr-nat-del ro1
> +check ovn-nbctl lr-nat-del ro2
> +
> +check ovn-nbctl lr-nat-add ro1 dnat_and_snat 10.0.0.100 192.168.1.2 vm1 
> 00:00:00:00:00:01
> +check ovn-nbctl lr-nat-add ro2 dnat_and_snat 20.0.0.100 192.168.2.2 vm2 
> 00:00:00:00:00:02
> +
> +check_lflows 0
> +
> +AS_BOX([Checking that Floating IP NAT flows are installed for gateway 
> routers])
> +
> +check ovn-nbctl lrp-set-gateway-chassis ro1-sw hv1 100
> +check ovn-nbctl --wait=sb lrp-set-gateway-chassis ro2-sw hv2 100
> +
> +check_lflows 1
> +
> +AS_BOX([Checking that Floating IP NAT flows are not installed for routers 
> with gateway chassis removed])
> +
> +check ovn-nbctl lrp-del-gateway-chassis ro1-sw hv1
> +check ovn-nbctl --wait=sb lrp-del-gateway-chassis ro2-sw hv2
> +
> +check_lflows 0
> +
> +AS_BOX([Checking that Floating IP NAT flows are installed for routers with 
> ha_chassis_group])
> +
> +grp1_uuid=$(ovn-nbctl --columns=_uuid --bare find HA_Chassis_group name=grp1)
> +check ovn-nbctl set logical_router_port ro1-sw ha_chassis_group="$grp1_uuid"
> +
> +grp2_uuid=$(ovn-nbctl --columns=_uuid --bare find HA_Chassis_group name=grp2)
> +check ovn-nbctl --wait=sb set logical_router_port ro2-sw 
> ha_chassis_group="$grp2_uuid"
> +
> +check_lflows 1
> +
> +AS_BOX([Checking that Floating IP NAT flows are not installed for routers 
> with HA_Chassis_Group removed])
> +
> +check ovn-nbctl clear logical_router_port ro1-sw ha_chassis_group
> +check ovn-nbctl --wait=sb clear logical_router_port ro2-sw ha_chassis_group
> +
> +check_lflows 0
> +
> +AS_BOX([Checking that Load Balancer VIP flows are not installed for routers 
> with no gateway port])
> +
> +check ovn-nbctl lr-nat-del ro1
> +check ovn-nbctl lr-nat-del ro2
> +
> +check ovn-nbctl lb-add lb1 10.0.0.100 192.168.1.2
> +check ovn-nbctl lr-lb-add ro1 lb1
> +
> +check ovn-nbctl lb-add lb2 20.0.0.100 192.168.2.2
> +check ovn-nbctl lr-lb-add ro2 lb2
> +
> +check_lflows 0
> +
> +AS_BOX([Checking that Load Balancer VIP flows are installed for gateway 
> routers])
> +
> +check ovn-nbctl lrp-set-gateway-chassis ro1-sw hv1 100
> +check ovn-nbctl --wait=sb lrp-set-gateway-chassis ro2-sw hv2 100
> +
> +check_lflows 1
> +
> +AS_BOX([Checking that Load Balancer VIP flows are not installed for routers 
> with gateway chassis removed])
> +
> +check ovn-nbctl lrp-del-gateway-chassis ro1-sw hv1
> +check ovn-nbctl --wait=sb lrp-del-gateway-chassis ro2-sw hv2
> +
> +check_lflows 0
> +
> +AS_BOX([Checking that Load Balancer VIP flows are installed for routers with 
> ha_chassis_group])
> +
> +grp1_uuid=$(ovn-nbctl --columns=_uuid --bare find HA_Chassis_group name=grp1)
> +check ovn-nbctl set logical_router_port ro1-sw ha_chassis_group="$grp1_uuid"
> +
> +grp2_uuid=$(ovn-nbctl --columns=_uuid --bare find HA_Chassis_group name=grp2)
> +check ovn-nbctl --wait=sb set logical_router_port ro2-sw 
> ha_chassis_group="$grp2_uuid"
> +
> +check_lflows 1
> +
> +AS_BOX([Checking that Load Balancer VIP flows are not iinstalled for routers 
> with HA_Chassis_Group removed])
> +
> +check ovn-nbctl clear logical_router_port ro1-sw ha_chassis_group
> +check ovn-nbctl --wait=sb clear logical_router_port ro2-sw ha_chassis_group
> +
> +check_lflows 0
> +
> +AT_CLEANUP
> --
> 2.31.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