On Thu, Jan 30, 2025 at 11:31:16AM +0100, Dumitru Ceara wrote:
> On 1/30/25 11:21 AM, [email protected] wrote:
> > On Tue, 2025-01-28 at 17:42 +0100, Felix Huettner wrote:
> >> Hi everyone,
> >>
> >> i still need to review the actual patch, but i wanted to join the
> >> discussion.
> >>
> >> On Tue, Jan 28, 2025 at 04:19:37PM +0100, Frode Nordahl wrote:
> >>> Hello all,
> >>>
> >>> Apologies for the tardy response, I've been pursuing an interesting
> >>> bug related to the "add_route" NAT option and routing IPv4 over
> >>> IPv6
> >>> next hop, and wanted to see that to an end before chiming in.
> >>> Patches
> >>> imminent.
> >>>
> >>> On Tue, Jan 28, 2025 at 1:50 PM Dumitru Ceara <[email protected]>
> >>> wrote:
> >>>>
> >>>> On 1/28/25 1:33 PM, [email protected] wrote:
> >>>>> Hi Frode/Numan/Dumitru,
> >>>>> Thanks for the review and interest in this patch, I'll put my
> >>>>> two cents
> >>>>> to the discussion below.
> >>>>>
> >>>>
> >>>> Hi Martin,
> >>>>
> >>>>> On Mon, 2025-01-27 at 11:57 +0100, Dumitru Ceara wrote:
> >>>>>> On 1/26/25 4:49 AM, Numan Siddique wrote:
> >>>>>>> On Sat, Jan 25, 2025 at 5:52 PM Frode Nordahl
> >>>>>>> <[email protected]>
> >>>>>>> wrote:
> >>>>>>>>
> >>>>>>>> Hello,
> >>>>>>>>
> >>>>>>>> Note that this email is sent at a time convenient to me,
> >>>>>>>> please
> >>>>>>>> don't
> >>>>>>>> feel obliged to read nor respond to it until a time
> >>>>>>>> convenient
> >>>>>>>> for
> >>>>>>>> you.
> >>>>>>>>
> >>>>>>>> The timing of this bit of time skewed work is because I
> >>>>>>>> anticipated
> >>>>>>>> the output to be a new patch set for which we would have
> >>>>>>>> a desire
> >>>>>>>> to
> >>>>>>>> try to get within soft freeze. It became apparent that it
> >>>>>>>> would
> >>>>>>>> likely
> >>>>>>>> fit within the context of the patch set you diligently
> >>>>>>>> posted on
> >>>>>>>> friday, so I'll leave the result of it as a review
> >>>>>>>> comment
> >>>>>>>> instead.
> >>>>>>>>
> >>>>>>>> On Thu, Jan 23, 2025 at 3:00 PM Martin Kalcok
> >>>>>>>> <[email protected]> wrote:
> >>>>>>>>>
> >>>>>>>>> This change builds on top of the new "dynamic routing"
> >>>>>>>>> OVN
> >>>>>>>>> feature
> >>>>>>>>> that allows advertising routes to the fabric network.
> >>>>>>>>> When LR
> >>>>>>>>> option
> >>>>>>>>> "dynamic-routing" is set on the router, following two
> >>>>>>>>> new LRP
> >>>>>>>>> options
> >>>>>>>>> become available:
> >>>>>>>>>
> >>>>>>>>> * redistribute-nat - When set to "true", ovn-controller
> >>>>>>>>> will
> >>>>>>>>> advertise
> >>>>>>>>>                      routes for external NAT IPs valid
> >>>>>>>>> for the
> >>>>>>>>> LRP.
> >>>>>>>>> * redistribute-lb-vips - When set to "true", ovn-
> >>>>>>>>> controller
> >>>>>>>>> will advertise
> >>>>>>>>>                          host routes to LB VIPs via the
> >>>>>>>>> LRP.
> >>>>>>>>>
> >>>>>>>>> Co-authored-by: Frode Nordahl <[email protected]>
> >>>>>>>>> Signed-off-by: Frode Nordahl <[email protected]>
> >>>>>>>>
> >>>>>>>> Thanks! Good to have these options resurrected and
> >>>>>>>> adapted to the
> >>>>>>>> current state of the fabric integration patch epic.
> >>>>>>>>
> >>>>>>>> After having read up a bit on the current state of review
> >>>>>>>> of our
> >>>>>>>> sibling options "dynmic-routing", "dynamic-routing-
> >>>>>>>> connected" and
> >>>>>>>> "dynamic-routing-static", I wonder if we need to make the
> >>>>>>>> nat and
> >>>>>>>> LB
> >>>>>>>> options have similar prefixes?
> >>>>>
> >>>>> Yeah, "dynamic-routing-redistribute-lb-vips" is kinda mouthful,
> >>>>> but if
> >>>>> that's the prefix for every other related option, we should
> >>>>> follow it.
> >>>>>
> >>>>
> >>>> Alternatively we could try to change the dynamic-routing-
> >>>> redistribute-*
> >>>> options and instead adding a boolean for each "redistribute"
> >>>> option we
> >>>> could change "dynamic-routing-redistribute" to be a list of
> >>>> entities we
> >>>> want to redistribute, e.g.:
> >>>>
> >>>> LR.options.dynamic-routing-redistribute="connected;nat;lb"
> >>>
> >>> On the topic of NAT and LB, as discovered during review, there is
> >>> an
> >>> oddly named get_nat_addresses() function that can retrieve both NAT
> >>> and LB addresses.
> >>>
> >>> To save us the work of refactoring it, perhaps we could use a
> >>> single
> >>> keyword for both NAT and LB addresses? I mean, would you ever want
> >>> one
> >>> without the other?
> >>
> >> "dynamic-routing-redistribute" looks like the shorter version.
> >> However i see an advantage in the individual "dynamic-routing-
> >> static",
> >> etc. options as they could allow us to use more values than just
> >> "true"
> >> and "false". E.g. they could in the future be used to filter for a
> >> given
> >> prefix and only announce that.
> >>
> 
> In my opinion if we want to add support for route filtering (route-maps
> or whatever we call them) a single string will not be enough anyway to
> express potentially complex conditions.
> 
> >> But that is just an idea on a potential benefit. I don't actually see
> >> a
> >> reason to currently built that.
> > 
> > It occurred to me that we could also use `dynamic-routing-
> > nat`/`dynamic-routing-lb-vips` names. This would be both shorter and
> > kept the door open for non-boolean values in the future.
> > 
> 
> My vote still goes to a single option with value the list of
> protocols/objects we want to redistributed.  But I'm not going to block
> the per-object implementation if that's what the majority prefers.

Hi Dumitru,

since on IRC on Thursday there was no heavy opinion in either way I will
implement the "dynamic-routing-redistribute" for the next version of the
patches. Then everyone can take a look how it feels.

Thanks a lot,
Felix

> 
> Regards,
> Dumitru
> 
> > Martin.
> > 
> >>
> >>>
> >>>> What do you guys think?
> >>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>> Signed-off-by: Martin Kalcok
> >>>>>>>>> <[email protected]>
> >>>>>>>
> >>>>>>> Hi Frode/Martin,
> >>>>>>>
> >>>>>>
> >>>>>> Hi Numan,
> >>>>>>
> >>>>>> Just a disclaimer before I reply to the rest: I didn't review
> >>>>>> these
> >>>>>> two
> >>>>>> patches properly yet.
> >>>>>>
> >>>>>>> I've a few questions related to the entire BGP series.  Can
> >>>>>>> you
> >>>>>>> please
> >>>>>>> help answer my questions?
> >>>>>>>
> >>>>>>> 1.  If I understand, a logical port in the provider logical
> >>>>>>> switch
> >>>>>>> (with localnet port) needs to be created
> >>>>>>
> >>>>>> I have this branch in my repo where I applied the previous
> >>>>>> versions
> >>>>>> of
> >>>>>> Frode/Felix's BGP series and there's a test there that shows
> >>>>>> how
> >>>>>> things
> >>>>>> are configured:
> >>>>>>
> >>>>>> https://github.com/dceara/ovn/blob/80edb08e6dfd5d3b5e19288d7cc277639d85a8ae/tests/system-ovn.at#L13945-L13969
> >>>>>>
> >>>>>> But IMO, the switch where the BGP control plane (FRR or
> >>>>>> something
> >>>>>> else)
> >>>>>> is connected doesn't have to be a "provider" logical switch. 
> >>>>>> The BGP
> >>>>>> control plane can run behind any LSP on any logical switch
> >>>>>> that's
> >>>>>> connected to a logical router port that has
> >>>>>> options:routing-protocols=BGP,BFD set.
> >>>>>>
> >>>>>> All we need to do is ensure that BGP packets (control
> >>>>>> traffic) reach
> >>>>>> that logical router port.
> >>>>>>
> >>>>>> In fact, in some cases we might _not even need to use the
> >>>>>> routing-protocols option_ as long as the CMS ensures itself
> >>>>>> that BGP
> >>>>>> packets (control traffic) reach the FRR instance in some
> >>>>>> other (out
> >>>>>> of
> >>>>>> band) way.
> >>>>>>
> >>>>>>>     and this port will be used to bind the VIF for the
> >>>>>>> "frr" to
> >>>>>>> establish a bgp (unnumbered) session
> >>>>>>>     with its neighbor (which I assume will be the leaf
> >>>>>>> switch) to
> >>>>>>> advertise the routes right ?
> >>>>>>
> >>>>>> That's one option yes.  But it can be any BGP speaker in
> >>>>>> general.
> >>>>>> Even
> >>>>>> another FRR (or other control plane) running behind a
> >>>>>> different OVN
> >>>>>> logical router (port).
> >>>>>>
> >>>>>>>     Is my understanding correct ?  If so,  this logical
> >>>>>>> port will
> >>>>>>> use
> >>>>>>> the SAME mac as the logical router port.
> >>>>>>
> >>>>>> Yes that's going to be required.
> >>>>>>
> >>>>>>>     What will be the type of this logical port ?
> >>>>>>
> >>>>>> Regular VIF, but because the VIF and LRP share mac address we
> >>>>>> had to
> >>>>>> take extra care and did:
> >>>>>>
> >>>>>> https://github.com/ovn-org/ovn/commit/370527673c2b35c1b79d90a4e5052177e593a699#diff-97e16400e2bcbb4b65f7f3b8f2c05e9e8e56148df77719b71d60f235e3bcc0edR14058-R14083
> >>>>>>
> >>>>>>>     Does the patch series add any system tests and create
> >>>>>>> this
> >>>>>>> logical port ?
> >>>>>>>     As I commented in another patch, adding end-to-end
> >>>>>>> multi node
> >>>>>>> system tests would be very full.
> >>>>>>>
> >>>>>>
> >>>>>> +1 I agree with this completely.
> >>>>>>
> >>>>>
> >>>>> I agree with everything that Dumitru very well summarized
> >>>>> above, thank
> >>>>> you. Just one question about the multi-node tests. The commit
> >>>>> above,
> >>>>> that Dumitru linked, also includes system tests for "routing-
> >>>>> protocol-
> >>>>> redirect". While it's not a multinode, it tests that process on
> >>>>> "external network" can connect to BGP port on LRP, ensuring
> >>>>> that BGP
> >>>>> control plane is redirected to the specified LSP.
> >>>>> Are we talking here about multinode version of that test, or a
> >>>>> multinode test for leaking NAT/LB addresses to VRF? Because in
> >>>>> my mind
> >>>>> these are two distinct (although related) features.
> >>>>>
> >>>>
> >>>> I think that ideally we should try to cover all supported cases
> >>>> in a
> >>>> multi-node e2e test suite.  I'm not sure we will be able to
> >>>> (time-wise)
> >>>> though.
> >>>
> >>> We see the value of this too, and we are prepared to put some hands
> >>> on
> >>> that task. We have not done any multi node system tests before
> >>> though,
> >>> so your concerns about time are valid, we'll see how far we get! If
> >>> you have any pointers that would be helpful (looping in MJ).
> >>
> >> That would be awesome if you would work on that. I guess we could
> >> then
> >> split this up again so that everyone builds a test validating their
> >> individual use case. Then we get a broad coverage of this feature.
> >>
> >>>
> >>>>
> >>>>>>> 2.  Do this patch series advertise routes for the
> >>>>>>> dnat_and_snat's
> >>>>>>> with
> >>>>>>> external_mac and logical_port set ?
> >>>>>>>     Or does it only support gateway routers ?  and not
> >>>>>>> distributed
> >>>>>>> router with a DGP ?
> >>>>>>>      If it is supported,  I assume, frr needs to be run on
> >>>>>>> all the
> >>>>>>> compute nodes where the logical_port
> >>>>>>>     specified in the dnat_and_snat's reside.
> >>>>>>>
> >>>>>>
> >>>>>> I think that's true for all BGP support being added by the
> >>>>>> current
> >>>>>> in-flight series.
> >>>>>
> >>>>> This is a good point, I'll take a look at whether we need
> >>>>> special
> >>>>> handling for Distributed NAT in this patch. But as Dumitru
> >>>>> said, these
> >>>>> in-flight patch series for Fabric integration extend the
> >>>>> support from
> >>>>> just gateway routers to distributed routers as well. In that
> >>>>> case, the
> >>>>> FRR would have to be run on every compute node connected to the
> >>>>> fabric/provider network. I have my own questions about the DR
> >>>>> support,
> >>>>> I'll raise those in the Fabric Integration series.
> >>>>>
> >>>
> >>> In our target architecture we want to set up a gateway router on
> >>> every
> >>> chassis that speaks BGP, so the need for a routing protocol daemon
> >>> to
> >>> run on every chassis is not tied to the DGP support.
> >>>
> >>> We have a working POC with in-flight patches and OpenStack where we
> >>> slip a gateway router in on every hypervisor, using OpenStack's
> >>> "provider" network as a join LS.
> >>>
> >>> On the topic of distributed NAT what we have yet to verify is
> >>> whether
> >>> the filtering of advertised routes works as expected in the on-list
> >>> patches. The original controller series made an attempt at only
> >>> ever
> >>> announcing NAT/LB addresses that actually had logical ports to
> >>> instances local to its chassis. Meaning that a NAT address should
> >>> only
> >>> be announced by a single gateway router, which should avoid any
> >>> concerns about asymmetric routing which does not work well with CT
> >>> state.
> >>
> >> If you also add a tracked_port during advertised_route_table_sync
> >> then
> >> you should get different route priorities based on if the port is
> >> local
> >> or not.
> >> That should then be useable by frr to decide if to announce a given
> >> route or not.
> >>
> >> Would that maybe solve that usecase?
> >>
> >> Thanks a lot,
> >> Felix
> >>
> >>>
> >>> For LB's the story is a bit different, as you can have a single VIP
> >>> with backends across multiple chassis, and given hashing is
> >>> configured
> >>> correctly in the fabric, it could be safe to have traffic balance
> >>> across multiple chassis.
> >>>
> >>>> Ack, looking forward to reviews.
> >>>
> >>> Expect that to ramp up momentarily :)
> >>>
> >>> --
> >>> Frode Nordahl
> >>>
> >>>>>>
> >>>>>>>
> >>>>>>> Thanks
> >>>>>>> Numan
> >>>>>>>
> >>>>>>
> >>>>>> Regards,
> >>>>>> Dumitru
> >>>>>>
> >>>>>>>
> >>>>>>>>> ---
> >>>>>>>>>  NEWS                              |   4 +
> >>>>>>>>>  northd/en-advertised-route-sync.c |  11 +
> >>>>>>>>>  northd/inc-proc-northd.c          |   4 +
> >>>>>>>>>  northd/northd.c                   |  98 +++++++-
> >>>>>>>>>  northd/northd.h                   |   4 +
> >>>>>>>>>  ovn-nb.xml                        |  31 +++
> >>>>>>>>>  tests/system-ovn.at               | 379
> >>>>>>>>> ++++++++++++++++++++++++++++++
> >>>>>>>>>  7 files changed, 530 insertions(+), 1 deletion(-)
> >>>>>>>>>
> >>>>>>>>> diff --git a/NEWS b/NEWS
> >>>>>>>>> index f526013f1..ad5b74b2e 100644
> >>>>>>>>> --- a/NEWS
> >>>>>>>>> +++ b/NEWS
> >>>>>>>>> @@ -24,6 +24,10 @@ Post v24.09.0
> >>>>>>>>>       a lower priority than static routes.
> >>>>>>>>>     - Add the option "dynamic-routing-connected-as-
> >>>>>>>>> host-routes"
> >>>>>>>>> to LRPs. If set
> >>>>>>>>>       to true then connected routes are announced as
> >>>>>>>>> individual
> >>>>>>>>> host routes.
> >>>>>>>>> +   - Add 'redistribute-lb-vips' LRP option. If set to
> >>>>>>>>> true,
> >>>>>>>>> the LRP can be used
> >>>>>>>>> +     to advertise host paths to the Load Balancer VIPs
> >>>>>>>>> associated with the LR.
> >>>>>>>>> +   - Add 'redistribute-nat' LRP option. If set to
> >>>>>>>>> true, the
> >>>>>>>>> LRP can be used
> >>>>>>>>> +     to advertise external NAT IPs associated with it.
> >>>>>>>>>
> >>>>>>>>>  OVN v24.09.0 - 13 Sep 2024
> >>>>>>>>>  --------------------------
> >>>>>>>>> diff --git a/northd/en-advertised-route-sync.c
> >>>>>>>>> b/northd/en-
> >>>>>>>>> advertised-route-sync.c
> >>>>>>>>> index 065c73861..b6786b3af 100644
> >>>>>>>>> --- a/northd/en-advertised-route-sync.c
> >>>>>>>>> +++ b/northd/en-advertised-route-sync.c
> >>>>>>>>> @@ -421,9 +421,20 @@ advertised_route_table_sync(
> >>>>>>>>>                                          "dynamic-
> >>>>>>>>> routing-
> >>>>>>>>> static")) {
> >>>>>>>>>              continue;
> >>>>>>>>>          }
> >>>>>>>>> +        if (route->source == ROUTE_SOURCE_NAT &&
> >>>>>>>>> +                !smap_get_bool(&route->out_port->nbrp-
> >>>>>>>>>> options,
> >>>>>>>>> +                               "redistribute-nat",
> >>>>>>>>> false)) {
> >>>>>>>>> +                continue;
> >>>>>>>>> +        }
> >>>>>>>>> +        if (route->source == ROUTE_SOURCE_LB &&
> >>>>>>>>> +                !smap_get_bool(&route->out_port->nbrp-
> >>>>>>>>>> options,
> >>>>>>>>> +                               "redistribute-lb-vips",
> >>>>>>>>> false))
> >>>>>>>>> {
> >>>>>>>>> +                continue;
> >>>>>>>>> +        }
> >>>>>>>>>
> >>>>>>>>>          char *ip_prefix = normalize_v46_prefix(&route-
> >>>>>>>>>> prefix,
> >>>>>>>>>                                                 route-
> >>>>>>>>>> plen);
> >>>>>>>>> +
> >>>>>>>>>          ar_sync_to_sb(ovnsb_txn, &sync_routes,
> >>>>>>>>>                           route->od->sb,
> >>>>>>>>>                           route->out_port->sb,
> >>>>>>>>> diff --git a/northd/inc-proc-northd.c b/northd/inc-
> >>>>>>>>> proc-
> >>>>>>>>> northd.c
> >>>>>>>>> index ab500a86a..36e1d9993 100644
> >>>>>>>>> --- a/northd/inc-proc-northd.c
> >>>>>>>>> +++ b/northd/inc-proc-northd.c
> >>>>>>>>> @@ -262,6 +262,10 @@ void inc_proc_northd_init(struct
> >>>>>>>>> ovsdb_idl_loop *nb,
> >>>>>>>>>      engine_add_input(&en_routes, &en_bfd, NULL);
> >>>>>>>>>      engine_add_input(&en_routes, &en_northd,
> >>>>>>>>>                       routes_northd_change_handler);
> >>>>>>>>> +    engine_add_input(&en_routes, &en_lr_nat,
> >>>>>>>>> +                     NULL);
> >>>>>>>>> +    engine_add_input(&en_routes, &en_lb_data,
> >>>>>>>>> +                     NULL);
> >>>>>>>>>
> >>>>>>>>>      engine_add_input(&en_bfd_sync, &en_bfd, NULL);
> >>>>>>>>>      engine_add_input(&en_bfd_sync, &en_nb_bfd, NULL);
> >>>>>>>>> diff --git a/northd/northd.c b/northd/northd.c
> >>>>>>>>> index 23b0769fe..e86208ef8 100644
> >>>>>>>>> --- a/northd/northd.c
> >>>>>>>>> +++ b/northd/northd.c
> >>>>>>>>> @@ -11435,6 +11435,96 @@
> >>>>>>>>> parsed_routes_add_connected(const
> >>>>>>>>> struct ovn_datapath *od,
> >>>>>>>>>      }
> >>>>>>>>>  }
> >>>>>>>>>
> >>>>>>>>> +static void
> >>>>>>>>> +parsed_routes_add_nat(const struct ovn_datapath *od,
> >>>>>>>>> +                      const struct ovn_port *op,
> >>>>>>>>> +                      struct hmap *routes)
> >>>>>>>>> +{
> >>>>>>>>> +    if (!op->nbrp || !smap_get_bool(&op->nbrp-
> >>>>>>>>>> options,
> >>>>>>>>> +                                    "redistribute-
> >>>>>>>>> nat",
> >>>>>>>>> false)) {
> >>>>>>>>> +        return;
> >>>>>>>>> +    }
> >>>>>>>>> +
> >>>>>>>>> +    size_t n_nats = 0;
> >>>>>>>>> +    char **nats = NULL;
> >>>>>>>>> +    nats = get_nat_addresses(op, &n_nats, false,
> >>>>>>>>> false, NULL,
> >>>>>>>>> true);
> >>>>>>>>> +
> >>>>>>>>> +    for (size_t i = 0; i < n_nats; i++) {
> >>>>>>>>> +        struct lport_addresses *laddrs =
> >>>>>>>>> xzalloc(sizeof
> >>>>>>>>> *laddrs);
> >>>>>>>>> +        int ofs = 0;
> >>>>>>>>> +        extract_addresses(nats[i], laddrs, &ofs);
> >>>>>>>>> +        for (int j = 0; j < laddrs->n_ipv4_addrs; j++)
> >>>>>>>>> {
> >>>>>>>>> +            struct ipv4_netaddr *addr = &laddrs-
> >>>>>>>>>> ipv4_addrs[j];
> >>>>>>>>> +            struct in6_addr prefix;
> >>>>>>>>> +            ip46_parse(addr->network_s, &prefix);
> >>>>>>>>> +
> >>>>>>>>> +            parsed_route_add(od, NULL, &prefix, addr-
> >>>>>>>>>> plen,
> >>>>>>>>> +                             false, addr->addr_s, op,
> >>>>>>>>> +                             0, false,
> >>>>>>>>> +                             false, NULL,
> >>>>>>>>> ROUTE_SOURCE_NAT,
> >>>>>>>>> +                             &op->nbrp->header_,
> >>>>>>>>> routes);
> >>>>>>>>> +        }
> >>>>>>>>> +        for (int j = 0; j < laddrs->n_ipv6_addrs; j++)
> >>>>>>>>> {
> >>>>>>>>> +            struct ipv6_netaddr *addr = &laddrs-
> >>>>>>>>>> ipv6_addrs[j];
> >>>>>>>>> +            parsed_route_add(od, NULL, &addr->addr,
> >>>>>>>>> addr-
> >>>>>>>>>> plen,
> >>>>>>>>> +                             false, addr->addr_s, op,
> >>>>>>>>> +                             0, false,
> >>>>>>>>> +                             false, NULL,
> >>>>>>>>> ROUTE_SOURCE_NAT,
> >>>>>>>>> +                             &op->nbrp->header_,
> >>>>>>>>> routes);
> >>>>>>>>> +        }
> >>>>>>>>> +        destroy_lport_addresses(laddrs);
> >>>>>>>>> +        free(nats[i]);
> >>>>>>>>> +    }
> >>>>>>>>> +    free(nats);
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +static void
> >>>>>>>>> +parsed_routes_add_lb(const struct ovn_datapath *od,
> >>>>>>>>> +                     const struct ovn_port *op,
> >>>>>>>>> +                     struct hmap *routes)
> >>>>>>>>> +{
> >>>>>>>>> +    if (!op->nbrp || !smap_get_bool(&op->nbrp-
> >>>>>>>>>> options,
> >>>>>>>>> +                                    "redistribute-lb-
> >>>>>>>>> vips",
> >>>>>>>>> false)) {
> >>>>>>>>> +        return;
> >>>>>>>>> +    }
> >>>>>>>>> +
> >>>>>>>>
> >>>>>>>> The get_nat_addresses() function appears to have support
> >>>>>>>> for also
> >>>>>>>> retrieving LB addresses, and it appears to do it by
> >>>>>>>> consuming
> >>>>>>>> already
> >>>>>>>> populated ssets. It also supports filtering on Load
> >>>>>>>> Balancers
> >>>>>>>> with the
> >>>>>>>> "add_route" option set, which can be useful for
> >>>>>>>> retrieving
> >>>>>>>> indirectly
> >>>>>>>> connected resources (see further discussion below).
> >>>>>>>>
> >>>>>>>> Should we consider switching to it?
> >>>>>
> >>>>> Yeah, sounds good, I'll look into it.
> >>>>>
> >>>>>>>>
> >>>>>>>>> +    for (size_t i = 0; i < od->nbr->n_load_balancer;
> >>>>>>>>> i++) {
> >>>>>>>>> +        struct ovn_northd_lb *lb =
> >>>>>>>>> ovn_northd_lb_create(
> >>>>>>>>> +                                        od->nbr-
> >>>>>>>>>> load_balancer[i]);
> >>>>>>>>> +        for (size_t j = 0; j < lb->n_vips; j++) {
> >>>>>>>>> +            const struct ovn_lb_vip *lb_vip = &lb-
> >>>>>>>>>> vips[j];
> >>>>>>>>> +            if (find_lport_address(&op->lrp_networks,
> >>>>>>>>> lb_vip-
> >>>>>>>>>> vip_str)) {
> >>>>>>>>> +                int plen = lb_vip->address_family ==
> >>>>>>>>> AF_INET ?
> >>>>>>>>> 32 : 128;
> >>>>>>>>> +                parsed_route_add(od, NULL, &lb_vip-
> >>>>>>>>>> vip, plen,
> >>>>>>>>> +                                 false, lb_vip-
> >>>>>>>>>> vip_str, op,
> >>>>>>>>> +                                 0, false,
> >>>>>>>>> +                                 false, NULL,
> >>>>>>>>> ROUTE_SOURCE_LB,
> >>>>>>>>> +                                 &op->nbrp->header_,
> >>>>>>>>> routes);
> >>>>>>>>> +            }
> >>>>>>>>> +        }
> >>>>>>>>> +    }
> >>>>>>>>> +
> >>>>>>>>> +    for (size_t i = 0; i < od->nbr-
> >>>>>>>>>> n_load_balancer_group;
> >>>>>>>>> i++) {
> >>>>>>>>> +        struct nbrec_load_balancer_group *lb_group =
> >>>>>>>>> +            od->nbr->load_balancer_group[i];
> >>>>>>>>> +        for (size_t j = 0; j < lb_group-
> >>>>>>>>>> n_load_balancer; j++)
> >>>>>>>>> {
> >>>>>>>>> +            struct ovn_northd_lb *lb =
> >>>>>>>>> +                ovn_northd_lb_create(lb_group-
> >>>>>>>>>> load_balancer[j]);
> >>>>>>>>> +            for (size_t k = 0; k < lb->n_vips; k++) {
> >>>>>>>>> +                const struct ovn_lb_vip *lb_vip = &lb-
> >>>>>>>>>> vips[k];
> >>>>>>>>> +                if (find_lport_address(&op-
> >>>>>>>>>> lrp_networks,
> >>>>>>>>> lb_vip->vip_str)) {
> >>>>>>>>> +                    int plen = lb_vip->address_family
> >>>>>>>>> ==
> >>>>>>>>> AF_INET ? 32 : 128;
> >>>>>>>>> +                    parsed_route_add(od, NULL,
> >>>>>>>>> &lb_vip->vip,
> >>>>>>>>> plen,
> >>>>>>>>> +                                     false, lb_vip-
> >>>>>>>>>> vip_str,
> >>>>>>>>> op,
> >>>>>>>>> +                                     0, false,
> >>>>>>>>> +                                     false, NULL,
> >>>>>>>>> ROUTE_SOURCE_LB,
> >>>>>>>>> +                                     &op->nbrp-
> >>>>>>>>>> header_,
> >>>>>>>>> routes);
> >>>>>>>>> +                }
> >>>>>>>>> +            }
> >>>>>>>>> +        }
> >>>>>>>>> +    }
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>>  void
> >>>>>>>>>  build_parsed_routes(const struct ovn_datapath *od,
> >>>>>>>>> const
> >>>>>>>>> struct hmap *lr_ports,
> >>>>>>>>>                       const struct hmap
> >>>>>>>>> *bfd_connections,
> >>>>>>>>> struct hmap *routes,
> >>>>>>>>> @@ -11457,6 +11547,8 @@ build_parsed_routes(const
> >>>>>>>>> struct
> >>>>>>>>> ovn_datapath *od, const struct hmap *lr_ports,
> >>>>>>>>>      const struct ovn_port *op;
> >>>>>>>>>      HMAP_FOR_EACH (op, dp_node, &od->ports) {
> >>>>>>>>>          parsed_routes_add_connected(od, op, routes);
> >>>>>>>>> +        parsed_routes_add_nat(od, op, routes);
> >>>>>>>>> +        parsed_routes_add_lb(od, op, routes);
> >>>>>>>>>      }
> >>>>>>>>
> >>>>>>>> We did not get to finish the end to end review of the
> >>>>>>>> state of
> >>>>>>>> the
> >>>>>>>> epic in context of downstream use with CMSs such as
> >>>>>>>> OpenStack
> >>>>>>>> before
> >>>>>>>> you posted these patches, so I know that support for NAT
> >>>>>>>> and LB
> >>>>>>>> "add_route" option was not on the radar at that point in
> >>>>>>>> time.
> >>>>>>>>
> >>>>>>>> After having reviewed it in this context I think we would
> >>>>>>>> benefit
> >>>>>>>> greatly from adding support for that here, something
> >>>>>>>> like:
> >>>>>
> >>>>> Thanks for these two diffs below. I'll include them in v2.
> >>>>>
> >>>>>>>> diff --git a/northd/northd.c b/northd/northd.c
> >>>>>>>> index 7057bb03a..bb29013ef 100644
> >>>>>>>> --- a/northd/northd.c
> >>>>>>>> +++ b/northd/northd.c
> >>>>>>>> @@ -11438,7 +11438,8 @@ parsed_routes_add_connected(const
> >>>>>>>> struct
> >>>>>>>> ovn_datapath *od,
> >>>>>>>>  static void
> >>>>>>>>  parsed_routes_add_nat(const struct ovn_datapath *od,
> >>>>>>>>                        const struct ovn_port *op,
> >>>>>>>> -                      struct hmap *routes)
> >>>>>>>> +                      struct hmap *routes,
> >>>>>>>> +                      bool routable_only)
> >>>>>>>>  {
> >>>>>>>>      if (!op->nbrp || !smap_get_bool(&op->nbrp->options,
> >>>>>>>>                                      "redistribute-nat",
> >>>>>>>> false))
> >>>>>>>> {
> >>>>>>>> @@ -11447,7 +11448,7 @@ parsed_routes_add_nat(const
> >>>>>>>> struct
> >>>>>>>> ovn_datapath *od,
> >>>>>>>>
> >>>>>>>>      size_t n_nats = 0;
> >>>>>>>>      char **nats = NULL;
> >>>>>>>> -    nats = get_nat_addresses(op, &n_nats, false, false,
> >>>>>>>> NULL,
> >>>>>>>> true);
> >>>>>>>> +    nats = get_nat_addresses(op, &n_nats, routable_only,
> >>>>>>>> false,
> >>>>>>>> NULL, true);
> >>>>>>>>
> >>>>>>>>      for (size_t i = 0; i < n_nats; i++) {
> >>>>>>>>          struct lport_addresses *laddrs = xzalloc(sizeof
> >>>>>>>> *laddrs);
> >>>>>>>> @@ -11481,7 +11482,8 @@ parsed_routes_add_nat(const
> >>>>>>>> struct
> >>>>>>>> ovn_datapath *od,
> >>>>>>>>  static void
> >>>>>>>>  parsed_routes_add_lb(const struct ovn_datapath *od,
> >>>>>>>>                       const struct ovn_port *op,
> >>>>>>>> -                     struct hmap *routes)
> >>>>>>>> +                     struct hmap *routes,
> >>>>>>>> +                     bool routable_only)
> >>>>>>>>  {
> >>>>>>>>      if (!op->nbrp || !smap_get_bool(&op->nbrp->options,
> >>>>>>>>                                      "redistribute-lb-
> >>>>>>>> vips",
> >>>>>>>> false)) {
> >>>>>>>> @@ -11547,8 +11549,19 @@ build_parsed_routes(const struct
> >>>>>>>> ovn_datapath
> >>>>>>>> *od, const struct hmap *lr_ports,
> >>>>>>>>      const struct ovn_port *op;
> >>>>>>>>      HMAP_FOR_EACH (op, dp_node, &od->ports) {
> >>>>>>>>          parsed_routes_add_connected(od, op, routes);
> >>>>>>>> -        parsed_routes_add_nat(od, op, routes);
> >>>>>>>> -        parsed_routes_add_lb(od, op, routes);
> >>>>>>>> +        parsed_routes_add_nat(od, op, routes, false);
> >>>>>>>> +        parsed_routes_add_lb(od, op, routes, false);
> >>>>>>>> +    }
> >>>>>>>> +
> >>>>>>>> +    for (size_t i = 0; od->is_gw_router && i < od-
> >>>>>>>>> n_ls_peers;
> >>>>>>>> i++) {
> >>>>>>>> +        for (size_t j = 0; j < od->ls_peers[i]-
> >>>>>>>>> n_router_ports;
> >>>>>>>> j++) {
> >>>>>>>> +            struct ovn_port *router_port;
> >>>>>>>> +
> >>>>>>>> +            router_port = od->ls_peers[i]-
> >>>>>>>>> router_ports[j]-
> >>>>>>>>> peer;
> >>>>>>>> +
> >>>>>>>> +            parsed_routes_add_nat(od, router_port,
> >>>>>>>> routes,
> >>>>>>>> true);
> >>>>>>>> +            parsed_routes_add_lb(od, router_port,
> >>>>>>>> routes, true);
> >>>>>>>> +        }
> >>>>>>>>      }
> >>>>>>>>
> >>>>>>>>      HMAP_FOR_EACH_SAFE (pr, key_node, routes) {
> >>>>>>>>
> >>>>>>>> ---
> >>>>>>>>
> >>>>>>>> The original controller side patches did controller-side
> >>>>>>>> filtering
> >>>>>>>> based on the instances behind the addresses actually
> >>>>>>>> being hosted
> >>>>>>>> on
> >>>>>>>> the local chassis, and this would still be relevant to
> >>>>>>>> consume
> >>>>>>>> something like the above, ensuring that /32 routes in the
> >>>>>>>> Advertise_Route table is only announced by the one
> >>>>>>>> gateway router
> >>>>>>>> local to the backing instance.
> >>>>>>>>
> >>>>>>>> A test case showing more detail on topology is added
> >>>>>>>> below.
> >>>>>>>>
> >>>>>>>>>      HMAP_FOR_EACH_SAFE (pr, key_node, routes) {
> >>>>>>>>> @@ -11638,6 +11730,8 @@ route_source_to_offset(enum
> >>>>>>>>> route_source source)
> >>>>>>>>>  {
> >>>>>>>>>      switch (source) {
> >>>>>>>>>          case ROUTE_SOURCE_CONNECTED:
> >>>>>>>>> +        case ROUTE_SOURCE_NAT:
> >>>>>>>>> +        case ROUTE_SOURCE_LB:
> >>>>>>>>>              return ROUTE_PRIO_OFFSET_CONNECTED;
> >>>>>>>>>          case ROUTE_SOURCE_STATIC:
> >>>>>>>>>              return ROUTE_PRIO_OFFSET_STATIC;
> >>>>>>>>> @@ -13915,7 +14009,9 @@ build_route_flows_for_lrouter(
> >>>>>>>>>      struct parsed_route *route;
> >>>>>>>>>      HMAP_FOR_EACH_WITH_HASH (route, key_node,
> >>>>>>>>> uuid_hash(&od-
> >>>>>>>>>> key),
> >>>>>>>>>                               parsed_routes) {
> >>>>>>>>> -        if (route->source == ROUTE_SOURCE_CONNECTED) {
> >>>>>>>>> +        if (route->source == ROUTE_SOURCE_CONNECTED ||
> >>>>>>>>> +                route->source == ROUTE_SOURCE_NAT ||
> >>>>>>>>> +                route->source == ROUTE_SOURCE_LB) {
> >>>>>>>>>              unique_routes_add(&unique_routes, route);
> >>>>>>>>>              continue;
> >>>>>>>>>          }
> >>>>>>>>> diff --git a/northd/northd.h b/northd/northd.h
> >>>>>>>>> index 3bc6f6f04..117b7421f 100644
> >>>>>>>>> --- a/northd/northd.h
> >>>>>>>>> +++ b/northd/northd.h
> >>>>>>>>> @@ -702,6 +702,10 @@ enum route_source {
> >>>>>>>>>      ROUTE_SOURCE_CONNECTED,
> >>>>>>>>>      /* The route is derived from a northbound static
> >>>>>>>>> route
> >>>>>>>>> entry. */
> >>>>>>>>>      ROUTE_SOURCE_STATIC,
> >>>>>>>>> +    /* Host route generated from NAT's external IP. */
> >>>>>>>>> +    ROUTE_SOURCE_NAT,
> >>>>>>>>> +    /* Host route generated from LB's external IP. */
> >>>>>>>>> +    ROUTE_SOURCE_LB,
> >>>>>>>>>      /* the route is learned by an ovn-controller */
> >>>>>>>>>      ROUTE_SOURCE_LEARNED,
> >>>>>>>>>  };
> >>>>>>>>> diff --git a/ovn-nb.xml b/ovn-nb.xml
> >>>>>>>>> index c5f182f24..417088a3a 100644
> >>>>>>>>> --- a/ovn-nb.xml
> >>>>>>>>> +++ b/ovn-nb.xml
> >>>>>>>>> @@ -2961,6 +2961,10 @@ or
> >>>>>>>>>                 table="Logical_Router_Port"/>
> >>>>>>>>>          * <ref column="options" key="dynamic-routing-
> >>>>>>>>> static"
> >>>>>>>>>                 table="Logical_Router_Port"/>
> >>>>>>>>> +        * <ref column="options" key="redistribute-lb-
> >>>>>>>>> vips"
> >>>>>>>>> +               table="Logical_Router_Port"/>
> >>>>>>>>> +        * <ref column="options" key="redistribute-nat"
> >>>>>>>>> +               table="Logical_Router_Port"/>
> >>>>>>>>>        </column>
> >>>>>>>>>
> >>>>>>>>>        <column name="options" key="dynamic-routing-
> >>>>>>>>> connected"
> >>>>>>>>> @@ -3798,6 +3802,33 @@ or
> >>>>>>>>>            This allows a single chassis to learn
> >>>>>>>>> different
> >>>>>>>>> routes on separate
> >>>>>>>>>            LRPs bound to this chassis.
> >>>>>>>>>        </column>
> >>>>>>>>> +
> >>>>>>>>> +      <column name="options" key="redistribute-lb-
> >>>>>>>>> vips"
> >>>>>>>>> +              type='{"type": "boolean"}'>
> >>>>>>>>> +        <p>
> >>>>>>>>> +          Only relevant if <ref column="options"
> >>>>>>>>> key="dynamic-
> >>>>>>>>> routing"
> >>>>>>>>> +          table="Logical_Router"/> on the respective
> >>>>>>>>> Logical_Router is set
> >>>>>>>>> +          to <code>true</code>.
> >>>>>>>>> +
> >>>>>>>>> +          If this option is <code>true</code>, northd
> >>>>>>>>> will
> >>>>>>>>> create host route
> >>>>>>>>> +          entries in the southbound <ref
> >>>>>>>>> table="Advertised_Route"
> >>>>>>>>> +          db="OVN_Southbound"/> table, associated with
> >>>>>>>>> this
> >>>>>>>>> LRP, for each LB
> >>>>>>>>> +          VIP.
> >>>>>>>>> +        </p>
> >>>>>>>>> +      </column>
> >>>>>>>>> +
> >>>>>>>>> +      <column name="options" key="redistribute-nat"
> >>>>>>>>> type='{"type": "boolean"}'>
> >>>>>>>>> +        <p>
> >>>>>>>>> +          Only relevant if <ref column="options"
> >>>>>>>>> key="dynamic-
> >>>>>>>>> routing"
> >>>>>>>>> +          table="Logical_Router"/> on the respective
> >>>>>>>>> Logical_Router is set
> >>>>>>>>> +          to <code>true</code>.
> >>>>>>>>> +
> >>>>>>>>> +          If this option is <code>true</code>, northd
> >>>>>>>>> will
> >>>>>>>>> create host route
> >>>>>>>>> +          entries in the southbound <ref
> >>>>>>>>> table="Advertised_Route"
> >>>>>>>>> +          db="OVN_Southbound"/> table, for external IP
> >>>>>>>>> addresses of NAT rules
> >>>>>>>>> +          associated with this LRP.
> >>>>>>>>> +        </p>
> >>>>>>>>> +      </column>
> >>>>>>>>>      </group>
> >>>>>>>>>
> >>>>>>>>>      <group title="Attachment">
> >>>>>>>>> diff --git a/tests/system-ovn.at b/tests/system-ovn.at
> >>>>>>>>> index 9dddfc399..1bcab802f 100644
> >>>>>>>>> --- a/tests/system-ovn.at
> >>>>>>>>> +++ b/tests/system-ovn.at
> >>>>>>>>> @@ -15283,3 +15283,382 @@
> >>>>>>>>> OVS_TRAFFIC_VSWITCHD_STOP(["/.*error
> >>>>>>>>> receiving.*/d
> >>>>>>>>>  AT_CLEANUP
> >>>>>>>>>  ])
> >>>>>>>>>
> >>>>>>>>> +OVN_FOR_EACH_NORTHD([
> >>>>>>>>> +AT_SETUP([route-exchange for LB VIPs with gateway
> >>>>>>>>> router
> >>>>>>>>> IPv4])
> >>>>>>>>> +AT_KEYWORDS([route-exchange])
> >>>>>>>>> +
> >>>>>>>>> +CHECK_VRF()
> >>>>>>>>> +CHECK_CONNTRACK()
> >>>>>>>>> +CHECK_CONNTRACK_NAT()
> >>>>>>>>> +ovn_start
> >>>>>>>>> +OVS_TRAFFIC_VSWITCHD_START()
> >>>>>>>>> +ADD_BR([br-int])
> >>>>>>>>> +ADD_BR([br-ext], [set Bridge br-ext fail-
> >>>>>>>>> mode=standalone])
> >>>>>>>>> +
> >>>>>>>>> +# Set external-ids in br-int needed for ovn-controller
> >>>>>>>>> +ovs-vsctl \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:system-
> >>>>>>>>> id=hv1 \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:ovn-
> >>>>>>>>> remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:ovn-encap-
> >>>>>>>>> type=geneve \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:ovn-encap-
> >>>>>>>>> ip=169.0.0.1 \
> >>>>>>>>> +        -- set bridge br-int fail-mode=secure other-
> >>>>>>>>> config:disable-in-band=true
> >>>>>>>>> +
> >>>>>>>>> +# Start ovn-controller
> >>>>>>>>> +start_daemon ovn-controller
> >>>>>>>>> +
> >>>>>>>>> +ovn-appctl vlog/set route_exchange
> >>>>>>>>> +check ovn-nbctl -- lr-add R1 \
> >>>>>>>>> +                -- set Logical_Router R1
> >>>>>>>>> options:requested-
> >>>>>>>>> tnl-key=1000 options:dynamic-routing=true
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl ls-add sw0
> >>>>>>>>> +check ovn-nbctl ls-add public
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl --wait=hv sync
> >>>>>>>>> +
> >>>>>>>>> +AT_CHECK([ip link | grep -q ovnvrf1000:.*UP], [1])
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lrp-add R1 rp-sw0 00:00:01:01:02:03
> >>>>>>>>> 192.168.1.1/24
> >>>>>>>>> +check ovn-nbctl -- lrp-add R1 rp-public
> >>>>>>>>> 00:00:02:01:02:03
> >>>>>>>>> 172.16.1.1/24 \
> >>>>>>>>> +                -- lrp-set-options rp-public \
> >>>>>>>>> +                       maintain-vrf=true \
> >>>>>>>>> +                       redistribute-lb-vips=true
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl set logical_router R1
> >>>>>>>>> options:chassis=hv1
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lsp-add sw0 sw0-rp -- set
> >>>>>>>>> Logical_Switch_Port
> >>>>>>>>> sw0-rp \
> >>>>>>>>> +    type=router options:router-port=rp-sw0 \
> >>>>>>>>> +    -- lsp-set-addresses sw0-rp router
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lsp-add public public-rp -- set
> >>>>>>>>> Logical_Switch_Port public-rp \
> >>>>>>>>> +    type=router options:router-port=rp-public \
> >>>>>>>>> +    -- lsp-set-addresses public-rp router
> >>>>>>>>> +
> >>>>>>>>> +check ovs-vsctl set Open_vSwitch . external-ids:ovn-
> >>>>>>>>> bridge-
> >>>>>>>>> mappings=phynet:br-ext
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lsp-add public public1 \
> >>>>>>>>> +        -- lsp-set-addresses public1 unknown \
> >>>>>>>>> +        -- lsp-set-type public1 localnet \
> >>>>>>>>> +        -- lsp-set-options public1 network_name=phynet
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl --wait=hv sync
> >>>>>>>>> +
> >>>>>>>>> +AT_CHECK([test `ip route show table 1000 | wc -l` -eq
> >>>>>>>>> 1], [1])
> >>>>>>>>> +
> >>>>>>>>> +
> >>>>>>>>> +# Create a load balancer and associate to R1
> >>>>>>>>> +check ovn-nbctl lb-add lb1 172.16.1.150:80
> >>>>>>>>> 172.16.1.100:80
> >>>>>>>>> +check ovn-nbctl lr-lb-add R1 lb1
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl --wait=hv sync
> >>>>>>>>> +
> >>>>>>>>> +AT_CHECK([ip link | grep -q ovnvrf1000:.*UP])
> >>>>>>>>> +AT_CHECK([test `ip route show table 1000 | wc -l` -eq
> >>>>>>>>> 1])
> >>>>>>>>> +AT_CHECK([ip route show table 1000 | grep -q
> >>>>>>>>> 172.16.1.150])
> >>>>>>>>> +
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovn-controller])
> >>>>>>>>> +
> >>>>>>>>> +# Ensure system resources are cleaned up
> >>>>>>>>> +AT_CHECK([ip link | grep -q ovnvrf1000:.*UP], [1])
> >>>>>>>>> +AT_CHECK([test `ip route show table 1000 | wc -l` -eq
> >>>>>>>>> 1], [1])
> >>>>>>>>> +
> >>>>>>>>> +as ovn-sb
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> >>>>>>>>> +
> >>>>>>>>> +as ovn-nb
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> >>>>>>>>> +
> >>>>>>>>> +as northd
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovn-northd])
> >>>>>>>>> +
> >>>>>>>>> +as
> >>>>>>>>> +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port
> >>>>>>>>> patch-.*/d
> >>>>>>>>> +/Failed to acquire.*/d
> >>>>>>>>> +/connection dropped.*/d"])
> >>>>>>>>> +AT_CLEANUP
> >>>>>>>>> +])
> >>>>>>>>> +
> >>>>>>>>> +OVN_FOR_EACH_NORTHD([
> >>>>>>>>> +AT_SETUP([route-exchange for LB VIPs with gateway
> >>>>>>>>> router
> >>>>>>>>> IPv6])
> >>>>>>>>> +AT_KEYWORDS([route-exchange])
> >>>>>>>>> +
> >>>>>>>>> +CHECK_VRF()
> >>>>>>>>> +CHECK_CONNTRACK()
> >>>>>>>>> +CHECK_CONNTRACK_NAT()
> >>>>>>>>> +ovn_start
> >>>>>>>>> +OVS_TRAFFIC_VSWITCHD_START()
> >>>>>>>>> +ADD_BR([br-int])
> >>>>>>>>> +ADD_BR([br-ext], [set Bridge br-ext fail-
> >>>>>>>>> mode=standalone])
> >>>>>>>>> +
> >>>>>>>>> +# Set external-ids in br-int needed for ovn-controller
> >>>>>>>>> +ovs-vsctl \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:system-
> >>>>>>>>> id=hv1 \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:ovn-
> >>>>>>>>> remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:ovn-encap-
> >>>>>>>>> type=geneve \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:ovn-encap-
> >>>>>>>>> ip=169.0.0.1 \
> >>>>>>>>> +        -- set bridge br-int fail-mode=secure other-
> >>>>>>>>> config:disable-in-band=true
> >>>>>>>>> +
> >>>>>>>>> +# Start ovn-controller
> >>>>>>>>> +start_daemon ovn-controller
> >>>>>>>>> +
> >>>>>>>>> +ovn-appctl vlog/set route_exchange
> >>>>>>>>> +check ovn-nbctl -- lr-add R1 \
> >>>>>>>>> +                -- set Logical_Router R1
> >>>>>>>>> options:requested-
> >>>>>>>>> tnl-key=1001 options:dynamic-routing=true
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl ls-add sw0
> >>>>>>>>> +check ovn-nbctl ls-add public
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl --wait=hv sync
> >>>>>>>>> +
> >>>>>>>>> +AT_CHECK([ip link | grep -q ovnvrf1001:.*UP], [1])
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lrp-add R1 rp-sw0 00:00:01:01:02:03
> >>>>>>>>> 2001:db8:100::1/64
> >>>>>>>>> +check ovn-nbctl -- lrp-add R1 rp-public
> >>>>>>>>> 00:00:02:01:02:03
> >>>>>>>>> 2001:db8:1001::1/64 \
> >>>>>>>>> +                -- lrp-set-options rp-public \
> >>>>>>>>> +                       maintain-vrf=true \
> >>>>>>>>> +                       redistribute-lb-vips=true
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl set logical_router R1
> >>>>>>>>> options:chassis=hv1
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lsp-add sw0 sw0-rp -- set
> >>>>>>>>> Logical_Switch_Port
> >>>>>>>>> sw0-rp \
> >>>>>>>>> +    type=router options:router-port=rp-sw0 \
> >>>>>>>>> +    -- lsp-set-addresses sw0-rp router
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lsp-add public public-rp -- set
> >>>>>>>>> Logical_Switch_Port public-rp \
> >>>>>>>>> +    type=router options:router-port=rp-public \
> >>>>>>>>> +    -- lsp-set-addresses public-rp router
> >>>>>>>>> +
> >>>>>>>>> +check ovs-vsctl set Open_vSwitch . external-ids:ovn-
> >>>>>>>>> bridge-
> >>>>>>>>> mappings=phynet:br-ext
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lsp-add public public1 \
> >>>>>>>>> +        -- lsp-set-addresses public1 unknown \
> >>>>>>>>> +        -- lsp-set-type public1 localnet \
> >>>>>>>>> +        -- lsp-set-options public1 network_name=phynet
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl --wait=hv sync
> >>>>>>>>> +
> >>>>>>>>> +AT_CHECK([test `ip -6 route show table 1001 | wc -l` -
> >>>>>>>>> eq 1],
> >>>>>>>>> [1])
> >>>>>>>>> +
> >>>>>>>>> +# Create a load balancer and associate to R1
> >>>>>>>>> +check ovn-nbctl lb-add lb1 [[2001:db8:1001::150]]:80
> >>>>>>>>> [[2001:db8:1001::100]]:80
> >>>>>>>>> +check ovn-nbctl lr-lb-add R1 lb1
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl --wait=hv sync
> >>>>>>>>> +
> >>>>>>>>> +AT_CHECK([ip link | grep -q ovnvrf1001:.*UP])
> >>>>>>>>> +AT_CHECK([test `ip -6 route show table 1001 | wc -l` -
> >>>>>>>>> eq 1])
> >>>>>>>>> +AT_CHECK([ip -6 route show table 1001 | grep -q
> >>>>>>>>> 2001:db8:1001::150])
> >>>>>>>>> +
> >>>>>>>>> +
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovn-controller])
> >>>>>>>>> +
> >>>>>>>>> +# Ensure system resources are cleaned up
> >>>>>>>>> +AT_CHECK([ip link | grep -q ovnvrf1001:.*UP], [1])
> >>>>>>>>> +AT_CHECK([test `ip -6 route show table 1001 | wc -l` -
> >>>>>>>>> eq 1],
> >>>>>>>>> [1])
> >>>>>>>>> +
> >>>>>>>>> +as ovn-sb
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> >>>>>>>>> +
> >>>>>>>>> +as ovn-nb
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> >>>>>>>>> +
> >>>>>>>>> +as northd
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovn-northd])
> >>>>>>>>> +
> >>>>>>>>> +as
> >>>>>>>>> +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port
> >>>>>>>>> patch-.*/d
> >>>>>>>>> +/Failed to acquire.*/d
> >>>>>>>>> +/connection dropped.*/d"])
> >>>>>>>>> +AT_CLEANUP
> >>>>>>>>> +])
> >>>>>>>>> +
> >>>>>>>>> +OVN_FOR_EACH_NORTHD([
> >>>>>>>>> +AT_SETUP([route-exchange for DNAT and DNAT_AND_SNAT
> >>>>>>>>> with
> >>>>>>>>> gateway router IPv4])
> >>>>>>>>> +AT_KEYWORDS([route-exchange])
> >>>>>>>>> +
> >>>>>>>>> +CHECK_VRF()
> >>>>>>>>> +CHECK_CONNTRACK()
> >>>>>>>>> +CHECK_CONNTRACK_NAT()
> >>>>>>>>> +ovn_start
> >>>>>>>>> +OVS_TRAFFIC_VSWITCHD_START()
> >>>>>>>>> +ADD_BR([br-int])
> >>>>>>>>> +ADD_BR([br-ext], [set Bridge br-ext fail-
> >>>>>>>>> mode=standalone])
> >>>>>>>>> +
> >>>>>>>>> +# Set external-ids in br-int needed for ovn-controller
> >>>>>>>>> +ovs-vsctl \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:system-
> >>>>>>>>> id=hv1 \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:ovn-
> >>>>>>>>> remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:ovn-encap-
> >>>>>>>>> type=geneve \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:ovn-encap-
> >>>>>>>>> ip=169.0.0.1 \
> >>>>>>>>> +        -- set bridge br-int fail-mode=secure other-
> >>>>>>>>> config:disable-in-band=true
> >>>>>>>>> +
> >>>>>>>>> +# Start ovn-controller
> >>>>>>>>> +start_daemon ovn-controller
> >>>>>>>>> +
> >>>>>>>>> +ovn-appctl vlog/set route_exchange
> >>>>>>>>> +check ovn-nbctl -- lr-add R1 \
> >>>>>>>>> +                -- set Logical_Router R1
> >>>>>>>>> options:requested-
> >>>>>>>>> tnl-key=1002 options:dynamic-routing=true
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl ls-add sw0
> >>>>>>>>> +check ovn-nbctl ls-add public
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl --wait=hv sync
> >>>>>>>>> +
> >>>>>>>>> +AT_CHECK([ip link | grep -q ovnvrf1002:.*UP], [1])
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lrp-add R1 rp-sw0 00:00:01:01:02:03
> >>>>>>>>> 192.168.1.1/24
> >>>>>>>>> +check ovn-nbctl -- lrp-add R1 rp-public
> >>>>>>>>> 00:00:02:01:02:03
> >>>>>>>>> 172.16.1.1/24 \
> >>>>>>>>> +                -- lrp-set-options rp-public \
> >>>>>>>>> +                       maintain-vrf=true \
> >>>>>>>>> +                       redistribute-nat=true
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl set logical_router R1
> >>>>>>>>> options:chassis=hv1
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lsp-add sw0 sw0-rp -- set
> >>>>>>>>> Logical_Switch_Port
> >>>>>>>>> sw0-rp \
> >>>>>>>>> +    type=router options:router-port=rp-sw0 \
> >>>>>>>>> +    -- lsp-set-addresses sw0-rp router
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lsp-add public public-rp -- set
> >>>>>>>>> Logical_Switch_Port public-rp \
> >>>>>>>>> +    type=router options:router-port=rp-public \
> >>>>>>>>> +    -- lsp-set-addresses public-rp router
> >>>>>>>>> +
> >>>>>>>>> +check ovs-vsctl set Open_vSwitch . external-ids:ovn-
> >>>>>>>>> bridge-
> >>>>>>>>> mappings=phynet:br-ext
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lsp-add public public1 \
> >>>>>>>>> +        -- lsp-set-addresses public1 unknown \
> >>>>>>>>> +        -- lsp-set-type public1 localnet \
> >>>>>>>>> +        -- lsp-set-options public1 network_name=phynet
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl --wait=hv sync
> >>>>>>>>> +
> >>>>>>>>> +AT_CHECK([test `ip route show table 1002 | wc -l` -eq
> >>>>>>>>> 2], [1])
> >>>>>>>>> +
> >>>>>>>>> +# Create dnat_and_snat, dnat rules in R1
> >>>>>>>>> +check ovn-nbctl lr-nat-add R1 dnat_and_snat
> >>>>>>>>> 172.16.1.10
> >>>>>>>>> 192.168.1.10
> >>>>>>>>> +check ovn-nbctl lr-nat-add R1 dnat 172.16.1.11
> >>>>>>>>> 192.168.1.11
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl --wait=hv sync
> >>>>>>>>> +
> >>>>>>>>> +AT_CHECK([ip link | grep -q ovnvrf1002:.*UP])
> >>>>>>>>> +AT_CHECK([test `ip route show table 1002 | wc -l` -eq
> >>>>>>>>> 2])
> >>>>>>>>> +AT_CHECK([ip route show table 1002 | grep -q
> >>>>>>>>> 172.16.1.10])
> >>>>>>>>> +AT_CHECK([ip route show table 1002 | grep -q
> >>>>>>>>> 172.16.1.11])
> >>>>>>>>> +
> >>>>>>>>> +
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovn-controller])
> >>>>>>>>> +
> >>>>>>>>> +# Ensure system resources are cleaned up
> >>>>>>>>> +AT_CHECK([ip link | grep -q ovnvrf1000:.*UP], [1])
> >>>>>>>>> +AT_CHECK([test `ip route show table 1002 | wc -l` -eq
> >>>>>>>>> 1], [1])
> >>>>>>>>> +
> >>>>>>>>> +as ovn-sb
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> >>>>>>>>> +
> >>>>>>>>> +as ovn-nb
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> >>>>>>>>> +
> >>>>>>>>> +as northd
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovn-northd])
> >>>>>>>>> +
> >>>>>>>>> +as
> >>>>>>>>> +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port
> >>>>>>>>> patch-.*/d
> >>>>>>>>> +/Failed to acquire.*/d
> >>>>>>>>> +/connection dropped.*/d"])
> >>>>>>>>> +AT_CLEANUP
> >>>>>>>>> +])
> >>>>>>>>> +
> >>>>>>>>> +OVN_FOR_EACH_NORTHD([
> >>>>>>>>> +AT_SETUP([route-exchange for DNAT and DNAT_AND_SNAT
> >>>>>>>>> with
> >>>>>>>>> gateway router IPv6])
> >>>>>>>>> +AT_KEYWORDS([route-exchange])
> >>>>>>>>> +
> >>>>>>>>> +CHECK_VRF()
> >>>>>>>>> +CHECK_CONNTRACK()
> >>>>>>>>> +CHECK_CONNTRACK_NAT()
> >>>>>>>>> +ovn_start
> >>>>>>>>> +OVS_TRAFFIC_VSWITCHD_START()
> >>>>>>>>> +ADD_BR([br-int])
> >>>>>>>>> +ADD_BR([br-ext], [set Bridge br-ext fail-
> >>>>>>>>> mode=standalone])
> >>>>>>>>> +
> >>>>>>>>> +# Set external-ids in br-int needed for ovn-controller
> >>>>>>>>> +ovs-vsctl \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:system-
> >>>>>>>>> id=hv1 \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:ovn-
> >>>>>>>>> remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:ovn-encap-
> >>>>>>>>> type=geneve \
> >>>>>>>>> +        -- set Open_vSwitch . external-ids:ovn-encap-
> >>>>>>>>> ip=169.0.0.1 \
> >>>>>>>>> +        -- set bridge br-int fail-mode=secure other-
> >>>>>>>>> config:disable-in-band=true
> >>>>>>>>> +
> >>>>>>>>> +# Start ovn-controller
> >>>>>>>>> +start_daemon ovn-controller
> >>>>>>>>> +
> >>>>>>>>> +ovn-appctl vlog/set route_exchange
> >>>>>>>>> +check ovn-nbctl -- lr-add R1 \
> >>>>>>>>> +                -- set Logical_Router R1
> >>>>>>>>> options:requested-
> >>>>>>>>> tnl-key=1003 options:dynamic-routing=true
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl ls-add sw0
> >>>>>>>>> +check ovn-nbctl ls-add public
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl --wait=hv sync
> >>>>>>>>> +
> >>>>>>>>> +AT_CHECK([ip link | grep -q ovnvrf1003:.*UP], [1])
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lrp-add R1 rp-sw0 00:00:01:01:02:03
> >>>>>>>>> 2001:db8:100::1/64
> >>>>>>>>> +check ovn-nbctl -- lrp-add R1 rp-public
> >>>>>>>>> 00:00:02:01:02:03
> >>>>>>>>> 2001:db8:1003::1/64 \
> >>>>>>>>> +                -- lrp-set-options rp-public \
> >>>>>>>>> +                       maintain-vrf=true \
> >>>>>>>>> +                       redistribute-nat=true
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl set logical_router R1
> >>>>>>>>> options:chassis=hv1
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lsp-add sw0 sw0-rp -- set
> >>>>>>>>> Logical_Switch_Port
> >>>>>>>>> sw0-rp \
> >>>>>>>>> +    type=router options:router-port=rp-sw0 \
> >>>>>>>>> +    -- lsp-set-addresses sw0-rp router
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lsp-add public public-rp -- set
> >>>>>>>>> Logical_Switch_Port public-rp \
> >>>>>>>>> +    type=router options:router-port=rp-public \
> >>>>>>>>> +    -- lsp-set-addresses public-rp router
> >>>>>>>>> +
> >>>>>>>>> +check ovs-vsctl set Open_vSwitch . external-ids:ovn-
> >>>>>>>>> bridge-
> >>>>>>>>> mappings=phynet:br-ext
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl lsp-add public public1 \
> >>>>>>>>> +        -- lsp-set-addresses public1 unknown \
> >>>>>>>>> +        -- lsp-set-type public1 localnet \
> >>>>>>>>> +        -- lsp-set-options public1 network_name=phynet
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl --wait=hv sync
> >>>>>>>>> +
> >>>>>>>>> +AT_CHECK([test `ip -6 route show table 1003 | wc -l` -
> >>>>>>>>> eq 2],
> >>>>>>>>> [1])
> >>>>>>>>> +
> >>>>>>>>> +# Create dnat_and_snat, dnat rules in R1
> >>>>>>>>> +check ovn-nbctl lr-nat-add R1 \
> >>>>>>>>> +    dnat_and_snat 2001:db8:1003::150 2001:db8:100::100
> >>>>>>>>> +check ovn-nbctl lr-nat-add R1 \
> >>>>>>>>> +    dnat 2001:db8:1003::151 2001:db8:100::100
> >>>>>>>>> +
> >>>>>>>>> +check ovn-nbctl --wait=hv sync
> >>>>>>>>> +
> >>>>>>>>> +AT_CHECK([ip link | grep -q ovnvrf1003:.*UP])
> >>>>>>>>> +AT_CHECK([test `ip -6 route show table 1003 | wc -l` -
> >>>>>>>>> eq 2])
> >>>>>>>>> +AT_CHECK([ip -6 route show table 1003 | grep -q
> >>>>>>>>> 2001:db8:1003::150])
> >>>>>>>>> +AT_CHECK([ip -6 route show table 1003 | grep -q
> >>>>>>>>> 2001:db8:1003::151])
> >>>>>>>>> +
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovn-controller])
> >>>>>>>>> +
> >>>>>>>>> +# Ensure system resources are cleaned up
> >>>>>>>>> +AT_CHECK([ip link | grep -q ovnvrf1003:.*UP], [1])
> >>>>>>>>> +AT_CHECK([test `ip -6 route show table 1003 | wc -l` -
> >>>>>>>>> eq 2],
> >>>>>>>>> [1])
> >>>>>>>>> +
> >>>>>>>>> +as ovn-sb
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> >>>>>>>>> +
> >>>>>>>>> +as ovn-nb
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> >>>>>>>>> +
> >>>>>>>>> +as northd
> >>>>>>>>> +OVS_APP_EXIT_AND_WAIT([ovn-northd])
> >>>>>>>>> +
> >>>>>>>>> +as
> >>>>>>>>> +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port
> >>>>>>>>> patch-.*/d
> >>>>>>>>> +/Failed to acquire.*/d
> >>>>>>>>> +/connection dropped.*/d"])
> >>>>>>>>> +AT_CLEANUP
> >>>>>>>>> +])
> >>>>>>>>> +
> >>>>>>>>> --
> >>>>>>>>> 2.43.0
> >>>>>>>>
> >>>>>>>> We could also have a unit test for this for quicker
> >>>>>>>> iteration, I
> >>>>>>>> wrote
> >>>>>>>> one while working on the diff injected above:
> >>>>>>>> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> >>>>>>>> index 47efd8258..676db246d 100644
> >>>>>>>> --- a/tests/ovn-northd.at
> >>>>>>>> +++ b/tests/ovn-northd.at
> >>>>>>>> @@ -14678,3 +14678,137 @@ AT_CHECK([ovn-sbctl --columns
> >>>>>>>> ip_prefix
> >>>>>>>> --bare find Advertised_Route datapath=$d
> >>>>>>>>  AT_CLEANUP
> >>>>>>>>  ])
> >>>>>>>>
> >>>>>>>> +OVN_FOR_EACH_NORTHD_NO_HV([
> >>>>>>>> +AT_SETUP([dynamic-routing - nat sync to sb])
> >>>>>>>> +AT_KEYWORDS([dynamic-routing])
> >>>>>>>> +ovn_start
> >>>>>>>> +
> >>>>>>>> +# Start with GW router and a single LRP
> >>>>>>>> +check ovn-nbctl lr-add lr0
> >>>>>>>> +check ovn-nbctl \
> >>>>>>>> +    -- \
> >>>>>>>> +    set Logical_Router lr0 options:dynamic-routing=true
> >>>>>>>> \
> >>>>>>>> +                           options:chassis=hv1
> >>>>>>>> +check ovn-nbctl --wait=sb \
> >>>>>>>> +    -- \
> >>>>>>>> +    lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
> >>>>>>>> +
> >>>>>>>> +check_row_count Advertised_Route 0
> >>>>>>>> +
> >>>>>>>> +datapath=$(ovn-sbctl --bare --columns _uuid list
> >>>>>>>> datapath_binding lr0)
> >>>>>>>> +pb=$(ovn-sbctl --bare --columns _uuid list port_binding
> >>>>>>>> lr0-sw0)
> >>>>>>>> +
> >>>>>>>> +# Adding LRP dynamic-routing-nat option and NAT rule
> >>>>>>>> advertises
> >>>>>>>> a route entry
> >>>>>>>> +check ovn-nbctl --wait=sb \
> >>>>>>>> +    -- \
> >>>>>>>> +    lrp-set-options lr0-sw0 redistribute-nat=true \
> >>>>>>>> +    -- \
> >>>>>>>> +    lr-nat-add lr0 dnat_and_snat 172.16.1.10
> >>>>>>>> 192.168.1.10
> >>>>>>>> +
> >>>>>>>> +ovn-nbctl list NAT
> >>>>>>>> +ovn-sbctl list Advertised_Route
> >>>>>>>> +ovn-sbctl lflow-list
> >>>>>>>> +
> >>>>>>>> +check_row_count Advertised_Route 1
> >>>>>>>> +# XXX the missing /32 in the ip_prefix below is probably
> >>>>>>>> incorrect?
> >>>>>>>> +AT_CHECK([ovn-sbctl --columns ip_prefix --bare find
> >>>>>>>> Advertised_Route
> >>>>>>>> datapath=$datapath logical_port=$pb], [0], [dnl
> >>>>>>>> +172.16.1.10
> >>>>>>>> +])
> >>>>>>>> +
> >>>>>>>> +# Add LR with distributed LRP connected to GW router
> >>>>>>>> through
> >>>>>>>> join LS
> >>>>>>>> +check ovn-nbctl \
> >>>>>>>> +    -- \
> >>>>>>>> +    lrp-add lr0 lr0-join 00:00:00:00:ff:02 10.42.0.1/24
> >>>>>>>> \
> >>>>>>>> +    -- \
> >>>>>>>> +    ls-add ls-join \
> >>>>>>>> +    -- \
> >>>>>>>> +    lsp-add ls-join lsp-join-to-lr0 \
> >>>>>>>> +    -- \
> >>>>>>>> +    lsp-set-type lsp-join-to-lr0 router \
> >>>>>>>> +    -- \
> >>>>>>>> +    lsp-set-options lsp-join-to-lr0 router-port=lr0-join
> >>>>>>>> \
> >>>>>>>> +    -- \
> >>>>>>>> +    lsp-set-addresses lsp-join-to-lr0 router \
> >>>>>>>> +    -- \
> >>>>>>>> +    lr-add lr-guest0 \
> >>>>>>>> +    -- \
> >>>>>>>> +    lrp-add lr-guest0 lrp-guest0-sw0 00:00:00:00:fe:01
> >>>>>>>> 10.51.0.1/24 \
> >>>>>>>> +    -- \
> >>>>>>>> +    lrp-add lr-guest0 lrp-guest0-join 00:00:00:00:fe:02
> >>>>>>>> 10.42.0.2/24 \
> >>>>>>>> +    -- \
> >>>>>>>> +    lrp-set-options lrp-guest0-join redistribute-
> >>>>>>>> nat=true \
> >>>>>>>> +    -- \
> >>>>>>>> +    lsp-add ls-join lsp-join-to-guest0 \
> >>>>>>>> +    -- \
> >>>>>>>> +    lsp-set-type lsp-join-to-guest0 router \
> >>>>>>>> +    -- \
> >>>>>>>> +    lsp-set-options lsp-join-to-guest0 router-port=lrp-
> >>>>>>>> guest0-
> >>>>>>>> join \
> >>>>>>>> +    -- \
> >>>>>>>> +    lrp-set-gateway-chassis lrp-guest0-join hv1
> >>>>>>>> +
> >>>>>>>> +pb2=$(ovn-sbctl --bare --columns _uuid list port_binding
> >>>>>>>> lrp-
> >>>>>>>> guest0-join)
> >>>>>>>> +
> >>>>>>>> +check ovn-nbctl --wait=sb \
> >>>>>>>> +    --add-route lr-nat-add lr-guest0 dnat_and_snat
> >>>>>>>> 172.16.2.10
> >>>>>>>> 192.168.2.10
> >>>>>>>> +
> >>>>>>>> +check_row_count Advertised_Route 2
> >>>>>>>> +# XXX the missing /32 in the ip_prefix below is probably
> >>>>>>>> incorrect?
> >>>>>>>> +AT_CHECK([ovn-sbctl --columns ip_prefix --bare find
> >>>>>>>> Advertised_Route
> >>>>>>>> datapath=$datapath logical_port=$pb], [0], [dnl
> >>>>>>>> +172.16.1.10
> >>>>>>>> +])
> >>>>>>>> +# XXX the missing /32 in the ip_prefix below is probably
> >>>>>>>> incorrect?
> >>>>>>>> +AT_CHECK([ovn-sbctl --columns ip_prefix --bare find
> >>>>>>>> Advertised_Route
> >>>>>>>> datapath=$datapath logical_port=$pb2], [0], [dnl
> >>>>>>>> +172.16.2.10
> >>>>>>>> +])
> >>>>>>>> +
> >>>>>>>> +# Add nonlocal LR with distributed LRP connected to GW
> >>>>>>>> router
> >>>>>>>> through join LS
> >>>>>>>> +check ovn-nbctl \
> >>>>>>>> +    -- \
> >>>>>>>> +    lr-add lr-guest1 \
> >>>>>>>> +    -- \
> >>>>>>>> +    lrp-add lr-guest1 lrp-guest1-sw0 00:00:00:00:fd:01
> >>>>>>>> 10.51.1.1/24 \
> >>>>>>>> +    -- \
> >>>>>>>> +    lrp-add lr-guest1 lrp-guest1-join 00:00:00:00:fd:02
> >>>>>>>> 10.42.0.3/24 \
> >>>>>>>> +    -- \
> >>>>>>>> +    lrp-set-options lrp-guest1-join redistribute-
> >>>>>>>> nat=true \
> >>>>>>>> +    -- \
> >>>>>>>> +    lsp-add ls-join lsp-join-to-guest1 \
> >>>>>>>> +    -- \
> >>>>>>>> +    lsp-set-type lsp-join-to-guest1 router \
> >>>>>>>> +    -- \
> >>>>>>>> +    lsp-set-options lsp-join-to-guest1 router-port=lrp-
> >>>>>>>> guest1-
> >>>>>>>> join \
> >>>>>>>> +    -- \
> >>>>>>>> +    lrp-set-gateway-chassis lrp-guest1-join nonlocalhv
> >>>>>>>> +
> >>>>>>>> +pb3=$(ovn-sbctl --bare --columns _uuid list port_binding
> >>>>>>>> lrp-
> >>>>>>>> guest1-join)
> >>>>>>>> +
> >>>>>>>> +check ovn-nbctl --wait=sb \
> >>>>>>>> +    --add-route lr-nat-add lr-guest1 dnat_and_snat
> >>>>>>>> 172.16.3.10
> >>>>>>>> 192.168.3.10
> >>>>>>>> +check_row_count Advertised_Route 3
> >>>>>>>> +# XXX the missing /32 in the ip_prefix below is probably
> >>>>>>>> incorrect?
> >>>>>>>> +AT_CHECK([ovn-sbctl --columns ip_prefix --bare find
> >>>>>>>> Advertised_Route
> >>>>>>>> datapath=$datapath logical_port=$pb], [0], [dnl
> >>>>>>>> +172.16.1.10
> >>>>>>>> +])
> >>>>>>>> +# XXX the missing /32 in the ip_prefix below is probably
> >>>>>>>> incorrect?
> >>>>>>>> +AT_CHECK([ovn-sbctl --columns ip_prefix --bare find
> >>>>>>>> Advertised_Route
> >>>>>>>> datapath=$datapath logical_port=$pb2], [0], [dnl
> >>>>>>>> +172.16.2.10
> >>>>>>>> +])
> >>>>>>>> +# XXX the missing /32 in the ip_prefix below is probably
> >>>>>>>> incorrect?
> >>>>>>>> +AT_CHECK([ovn-sbctl --columns ip_prefix --bare find
> >>>>>>>> Advertised_Route
> >>>>>>>> datapath=$datapath logical_port=$pb3], [0], [dnl
> >>>>>>>> +172.16.3.10
> >>>>>>>> +])
> >>>>>>>> +
> >>>>>>>> +# removing the option:dynamic-routing removes all routes
> >>>>>>>> +check ovn-nbctl --wait=sb remove Logical_Router lr0
> >>>>>>>> option
> >>>>>>>> dynamic-routing
> >>>>>>>> +check_row_count Advertised_Route 0
> >>>>>>>> +
> >>>>>>>> +# and setting it again adds them again
> >>>>>>>> +check ovn-nbctl --wait=sb set Logical_Router lr0
> >>>>>>>> option:dynamic-
> >>>>>>>> routing=true
> >>>>>>>> +check_row_count Advertised_Route 3
> >>>>>>>> +
> >>>>>>>> +# removing the lr will remove all routes
> >>>>>>>> +check ovn-nbctl --wait=sb lr-del lr0
> >>>>>>>> +check_row_count Advertised_Route 0
> >>>>>>>> +
> >>>>>>>> +AT_CLEANUP
> >>>>>>>> +])
> >>>>>>>> ---
> >>>>>>>>
> >>>>>>>> --
> >>>>>>>> Frode Nordahl
> >>>>
> >>>> Regards,
> >>>> Dumitru
> >>>>
> > 
> 
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to