@@ -6428,11 +6428,15 @@ get_nat_addresses_and_keys(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_port_binding *pb;
pb = lport_lookup_by_name(sbrec_port_binding_by_name, gw_port);
- if (!pb) {
+ if (!pb || !pb->datapath) {
continue;
}
- if (pb->n_nat_addresses) {
+ /* We only want to consider nat_addresses column for LS datapaths. */
+ const char *logical_switch = smap_get(&pb->datapath->external_ids,
+ "logical-switch");
+
+ if (pb->n_nat_addresses && logical_switch) {
for (int i = 0; i < pb->n_nat_addresses; i++) {
consider_nat_address(sbrec_port_binding_by_name,
pb->nat_addresses[i], pb,
@@ -3912,6 +3912,8 @@ sync_pb_for_lrp(struct ovn_port *op,
smap_init(&new);
const char *chassis_name = smap_get(&op->od->nbr->options, "chassis");
+ bool redistribute_nat = smap_get_bool(&op->nbrp->options,
+ "redistribute-nat", false);
if (is_cr_port(op)) {
const struct lr_stateful_record *lr_stateful_rec =
lr_stateful_table_find_by_index(lr_stateful_table, op->od->index);
@@ -3950,6 +3952,28 @@ sync_pb_for_lrp(struct ovn_port *op,
}
if (chassis_name) {
smap_add(&new, "l3gateway-chassis", chassis_name);
+ if (smap_get_bool(&op->nbrp->options, "maintain-vrf", false)) {
+ smap_add(&new, "maintain-vrf", "true");
+ }
+ if (redistribute_nat) {
+ smap_add(&new, "redistribute-nat", "true");
+
+ size_t n_nats = 0;
+ char **nats = NULL;
+ nats = get_nat_addresses(op, &n_nats, false, false, NULL,
+ true);
+ sbrec_port_binding_set_nat_addresses(op->sb,
+ (const char **) nats,
+ n_nats);
+ for (size_t i = 0; i < n_nats; i++) {
+ free(nats[i]);
+ }
+ free(nats);
+ }
+ if (smap_get_bool(&op->nbrp->options,
+ "redistribute-lb-vips", false)) {
+ smap_add(&new, "redistribute-lb-vips", "true");
+ }
}
}
@@ -3960,6 +3984,10 @@ sync_pb_for_lrp(struct ovn_port *op,
sbrec_port_binding_set_options(op->sb, &new);
smap_destroy(&new);
+
+ if (!chassis_name || !redistribute_nat) {
+ sbrec_port_binding_set_nat_addresses(op->sb, NULL, 0);
+ }
}
static void ovn_update_ipv6_options(struct hmap *lr_ports);
@@ -3467,6 +3467,51 @@ or
<ref column="options" key="gateway_mtu"/> option.
</p>
</column>
+
+ <column name="options" key="redistribute-lb-vips">
+ <p>
+ When configured the <code>ovn-controller</code> will redistribute
+ host routes to Load Balancer VIPs that are local to its chassis and
+ associated with the LR datapath.
+
+ This option only works on gateway routers (routers that have
+ <ref column="options" key="chassis" table="Logical_Router"/> set)
+ when OVN is built on a system with Netlink support.
+ </p>
+ </column>
+
+ <column name="options" key="redistribute-nat">
+ <p>
+ When configured the <code>ovn-controller</code> will redistribute
+ host routes to NAT records associated with logical ports local to
+ its chassis in relateion to the LR datapath.
+
+ This option only works on gateway routers (routers that have
+ <ref column="options" key="chassis" table="Logical_Router"/> set)
+ when OVN is built on a system with Netlink support.
+ </p>
+ </column>
+
+ <column name="options" key="maintain-vrf">
+ <p>
+ When configured the <code>ovn-controller</code> will maintain a VRF
+ in the system for exporting host routes to NAT addresses (see
+ <ref column="options" key="redistribute-nat"/> option) and Load
+ Balancer VIPs (see <ref column="options" key="redistribute-lb-vips"/>
+ option).
+
+ Route table ID to use can be influenced by setting the
+ <ref column="options" key="requested-tnl-key"
+ table="Logical_Router"/> option in the
+ <ref table="Logical_Router"/> table. If not set,
+ <code>ovn-northd</code> will allocate one.
+
+ This option only works on gateway routers (routers that have
+ <ref column="options" key="chassis" table="Logical_Router"/> set)
+ when OVN is built on a system with Netlink support.
+ </p>
+ </column>
+
</group>
<group title="Attachment">
@@ -3594,14 +3594,63 @@ tcp.flags = RST;
The <code>chassis</code> in which the port resides.
</column>
+ <column name="options" key="redistribute-lb-vips">
+ <p>
+ The value is copied from the column
+ <ref table="Logical_Router_Port" column="options"
+ db="OVN_Northbound"/> and when configured the
+ <code>ovn-controller</code> will redistribute host routes to Load
+ Balancer VIPs that are local to its chassis and associated with the
+ LR datapath.
+ </p>
+ </column>
+
+ <column name="options" key="redistribute-nat">
+ <p>
+ The value is copied from the column
+ <ref table="Logical_Router_Port" column="options"
+ db="OVN_Northbound"/> and when configured the
+ <code>ovn-controller</code> will redistribute host routes to
+ <ref table="NAT" db="OVN_Northbound"/> records associated with
+ logical ports local to this chassis in relateion to the LR datapath.
+ </p>
+ </column>
+
+ <column name="options" key="maintain-vrf">
+ <p>
+ The value is copied from the column
+ <ref table="Logical_Router_Port" column="options"
+ db="OVN_Northbound"/> and when configured the
+ <code>ovn-controller</code> will maintain a VRF in the system for
+ exporting host routes to NAT addresses (see
+ <ref column="options" key="redistribute-nat"/> option) and Load
+ Balancer VIPs (see <ref column="options" key="redistribute-lb-vips"/>
+ option).
+ </p>
+ </column>
+
<column name="nat_addresses">
MAC address of the <code>l3gateway</code> port followed by a list of
- SNAT and DNAT external IP addresses. This is used to send gratuitous
+ SNAT and DNAT external IP addresses.
+
+ Both sides of a LRP-LSP peer relationship have records in the
+ <ref table="Port_Binding"/> table.
+
+ When the record is associated with a
+ <ref table="Datapath_Binding" column="external_ids"
+ key="logical-switch"/> record, this is used to send gratuitous
ARPs for SNAT and DNAT external IP addresses via <code>localnet</code>.
Example: <code>80:fa:5b:06:72:b7 158.36.44.22 158.36.44.24</code>.
This would result in generation of gratuitous ARPs for IP addresses
158.36.44.22 and 158.36.44.24 with a MAC address of 80:fa:5b:06:72:b7.
This is used in OVS version 2.8 and later versions.
+
+ When the record is associated with a
+ <ref table="Datapath_Binding" column="external_ids"
+ key="logical-router"/> record, this is used to redistribute host
+ routes to <ref table="NAT" db="OVN_Northbound"/> records associated
+ with logical ports local to this chassis in relateion to the LR
+ datapath.
</column>
</group>
@@ -12459,3 +12459,45 @@ AT_CHECK([ovn-sbctl dump-flows lr | grep lr_in_dnat | ovn_strip_lflows], [0], [d
AT_CLEANUP
])
+
+OVN_FOR_EACH_NORTHD_NO_HV([
+AT_SETUP([check route-exchange redistribute-nat option])
+ovn_start
+
+ovn-nbctl lr-add R1
+ovn-nbctl set Logical_Router R1 options:chassis=hv1
+ovn-nbctl lrp-add R1 R1-S1 02:ac:10:01:00:01 172.16.1.1/24
+
+ovn-nbctl ls-add S1
+ovn-nbctl lsp-add S1 S1-R1
+ovn-nbctl lsp-set-type S1-R1 router
+ovn-nbctl lsp-set-addresses S1-R1 02:ac:10:01:00:01
+ovn-nbctl --wait=sb lsp-set-options S1-R1 \
+ router-port=R1-S1 \
+ nat-addresses="router"
+
+ovn-nbctl lr-nat-add R1 snat 172.16.1.1 10.0.0.0/24
+ovn-nbctl lr-nat-add R1 dnat 172.16.1.2 10.0.0.1
+ovn-nbctl --wait=sb sync
+
+AT_CHECK([dnl
+ovn-sbctl get Port_Binding S1-R1 nat_addresses | grep -q 172.16.1.2], [0])
+AT_CHECK([dnl
+ovn-sbctl get Port_Binding R1-S1 nat_addresses | grep -q 172.16.1.2], [1])
+
+ovn-nbctl --wait=sb lrp-set-options R1-S1 redistribute-nat=true
+
+AT_CHECK([dnl
+ovn-sbctl get Port_Binding S1-R1 nat_addresses | grep -q 172.16.1.2], [0])
+AT_CHECK([dnl
+ovn-sbctl get Port_Binding R1-S1 nat_addresses | grep -q 172.16.1.2], [0])
+
+ovn-nbctl --wait=sb lrp-set-options R1-S1 redistribute-nat=false
+
+AT_CHECK([dnl
+ovn-sbctl get Port_Binding S1-R1 nat_addresses | grep -q 172.16.1.2], [0])
+AT_CHECK([dnl
+ovn-sbctl get Port_Binding R1-S1 nat_addresses | grep -q 172.16.1.2], [1])
+
+AT_CLEANUP
+])
Add three new options for Logical Router Ports that control ovn-controller route exchange for NAT addresses and LB VIPs. Load Balancers already have structured data in the Southbound database which the ovn-controller can use directly. NAT addresses are however currently only expressed as specialized rules in the Port_Binding table nat_addresses column on LSP peer records for LRPs, used for (G)ARP processing, as well as logical flow rules for OpenFlow processing. Options considered for how to redistribute these addresses to the ovn-controllers in a structured way: * Introduce even more conditional processing of the lsp nat_addresses column. * Parse ct_dnat records in the Logical_Flow table. * Add column to the Port_Binding table. * Copy the Northbound NAT table over to the Southbound database, similar to what is done with Load Balancers. * Populate Port_Binding table nat_addresses column on LRPs peer record (the proposed approach). The Port_Binding table LRP peer records nat_addresses column is currently unused, populate it with NAT addresses for route exchange, when the redistribute-nat LRP option is set to 'true'. The options are only processed for gateway routers. Signed-off-by: Frode Nordahl <fnordahl@ubuntu.com> --- controller/pinctrl.c | 8 +++++-- northd/northd.c | 28 ++++++++++++++++++++++++ ovn-nb.xml | 45 ++++++++++++++++++++++++++++++++++++++ ovn-sb.xml | 51 +++++++++++++++++++++++++++++++++++++++++++- tests/ovn-northd.at | 42 ++++++++++++++++++++++++++++++++++++ 5 files changed, 171 insertions(+), 3 deletions(-)