Skip to content

Commit

Permalink
northd: Support active-active lrps.
Browse files Browse the repository at this point in the history
In case we find a LRP (or a LSP connected to a LRP) that has
options:active-active-lrp set we ignore it during normal processing in
join_logical_ports.

We add an additional section at the end where we then use these ports to
generate derived Port_Bindings for each LRP + LSP combination once for
each matching ovn-aa-port-mappings entry.

In the end this gives us the same result as if someone would have
precreated a LRP + LSP combination for each ovn-aa-port-mappings in the
northbound. However it allows our users to benefit from active-active
routing without their CMS needing to know about this feature (besides
the active-active-lrp setting).

Signed-off-by: Felix Huettner <[email protected]>
Signed-off-by: 0-day Robot <[email protected]>
  • Loading branch information
felixhuettner authored and ovsrobot committed Dec 18, 2024
1 parent 82f8192 commit 80bcaf2
Show file tree
Hide file tree
Showing 14 changed files with 832 additions and 14 deletions.
6 changes: 6 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ Post v24.09.0
and "routing-protocols" are now also usable on distributed gateway ports.
- ovn-nb: Changed schema of ovn-nb to make networks optional within Logical
Router Ports.
- Add the option "active-active-lrp" to LRPs. If set northd will clone this
LRP based on its HA_Chassis_Group and the
other_config:ovn-active-active-mapping of the defined chassis. In
combination with the dynamic routing features this allows operators to
integrate OVN into the network fabric in a highly available way without
significant (or any) changes to the CMS.

OVN v24.09.0 - 13 Sep 2024
--------------------------
Expand Down
30 changes: 30 additions & 0 deletions controller/ovn-controller.8.xml
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,36 @@
If the value is zero, it disables the inactivity probe.
</p>
</dd>
<dt><code>external_ids:ovn-active-active-mappings</code></dt>
<dd>
<p>
Setting is used for the chassis specific values of the
<code>options:active-active-lrp</code> in the northbound database.

The following is an example of such an option:
<code>ovn-active-active-mappings="phys;00:fe:fe:fe:fe:01,172.16.0.10/25;00:fe:fe:fe:fe:33,172.17.0.10/25|phys2;00:aa:bb:cc:dd:ee,192.168.0.10/24"</code>

This configures 2 separate active-active mapping for two external
networks.

<ul>
<li>
For the external network named <code>phys</code>
there will be two LRPs generated for this chassis. One with MAC
<code>00:fe:fe:fe:fe:01</code> and IP
<code>172.16.0.10/25</code>. The other with MAC
<code>00:fe:fe:fe:fe:33</code> and IP
<code>172.17.0.10/25</code>.
</li>
<li>
For the external network named <code>phys2</code>
there will be one LRPs generated for this chassis. With MAC
<code>00:aa:bb:cc:dd:ee</code> and IP
<code>192.168.0.10/24</code>.
</li>
</ul>
</p>
</dd>
</dl>

<p>
Expand Down
2 changes: 2 additions & 0 deletions lib/automake.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ lib_libovn_la_SOURCES = \
lib/ovn-parallel-hmap.c \
lib/ip-mcast-index.c \
lib/ip-mcast-index.h \
lib/lrp-index.c \
lib/lrp-index.h \
lib/mac-binding-index.c \
lib/mac-binding-index.h \
lib/mcast-group-index.c \
Expand Down
43 changes: 43 additions & 0 deletions lib/lrp-index.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <config.h>
#include "lib/lrp-index.h"
#include "lib/ovn-nb-idl.h"

struct ovsdb_idl_index *
lrp_index_create(struct ovsdb_idl *idl)
{
return ovsdb_idl_index_create1(idl, &nbrec_logical_router_port_col_name);
}


/* Finds and returns the lrp with the given 'name', or NULL if no such
* lrp exists. */
const struct nbrec_logical_router_port *
lrp_lookup_by_name(struct ovsdb_idl_index *nbrec_lrp_by_name,
const char *name)
{
struct nbrec_logical_router_port *target =
nbrec_logical_router_port_index_init_row(nbrec_lrp_by_name);
nbrec_logical_router_port_index_set_name(target, name);

struct nbrec_logical_router_port *retval =
nbrec_logical_router_port_index_find(nbrec_lrp_by_name, target);

nbrec_logical_router_port_index_destroy_row(target);

return retval;
}

25 changes: 25 additions & 0 deletions lib/lrp-index.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef OVN_LRP_INDEX_H
#define OVN_LRP_INDEX_H 1

struct ovsdb_idl;

struct ovsdb_idl_index *lrp_index_create(struct ovsdb_idl *);

const struct nbrec_logical_router_port *lrp_lookup_by_name(
struct ovsdb_idl_index *nbrec_lrp_by_name, const char *name);

#endif /* lib/lrp-index.h */
97 changes: 97 additions & 0 deletions lib/ovn-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,103 @@ get_chassis_external_id_value_bool(const struct smap *external_ids,
return ret;
}

bool
chassis_find_active_active_networks(const struct sbrec_chassis *chassis,
const char *network_name,
struct chassis_aa_network
*chassis_aa_network) {
memset(chassis_aa_network, 0, sizeof *chassis_aa_network);

const char *aa_ports = smap_get(&chassis->other_config,
"ovn-active-active-mappings");
bool found = false;
char *curnet, *nextnet, *curport, *nextport, *start;

/* Structure
* ovn-active-active-mappings="<network>|<network>"
* network="<network_name>;<port>;<port>"
* port="<mac>,<ip>" */
nextnet = start = xstrdup(aa_ports);
while ((curnet = strsep(&nextnet, "|")) && *curnet) {
nextport = curnet;
char *network = strsep(&nextport, ";");
if (strcmp(network, network_name)) {
continue;
}
found = true;
chassis_aa_network->network_name = xstrdup(network);
chassis_aa_network->n_addresses = 0;
while ((curport = strsep(&nextport, ";")) && *curport) {
char *mac, *ip;

mac = strsep(&curport, ",");
ip = curport;

if (!mac || !ip || !*mac || !*ip) {
VLOG_ERR("Invalid format for "
"ovn-active-active-mappings '%s'",
aa_ports);
continue;
}

chassis_aa_network->addresses = xrealloc(
chassis_aa_network->addresses,
(chassis_aa_network->n_addresses + 1
) * sizeof *chassis_aa_network->addresses);
struct lport_addresses *address =
&chassis_aa_network->addresses[
chassis_aa_network->n_addresses];
init_lport_addresses(address);

if (!eth_addr_from_string(mac, &address->ea)) {
VLOG_ERR("Invalid mac address in "
"ovn-active-active-mappings '%s'",
aa_ports);
free(address);
continue;
}
snprintf(address->ea_s, sizeof address->ea_s, ETH_ADDR_FMT,
ETH_ADDR_ARGS(address->ea));

ovs_be32 ip4;
struct in6_addr ip6;
unsigned int plen;
char *error;

error = ip_parse_cidr(ip, &ip4, &plen);
if (!error) {
if (!ip4) {
VLOG_ERR("Invalid ip address in "
"ovn-active-active-mappings '%s'",
aa_ports);
destroy_lport_addresses(address);
continue;
}

add_ipv4_netaddr(address, ip4, plen);
} else {
free(error);

error = ipv6_parse_cidr(ip, &ip6, &plen);
if (!error) {
add_ipv6_netaddr(address, ip6, plen);
} else {
VLOG_ERR("Invalid ip address in "
"ovn-active-active-mappings '%s'",
aa_ports);
destroy_lport_addresses(address);
free(error);
continue;
}
}
chassis_aa_network->n_addresses++;
}
}

free(start);
return found;
}

void flow_collector_ids_init(struct flow_collector_ids *ids)
{
ovs_list_init(&ids->list);
Expand Down
11 changes: 11 additions & 0 deletions lib/ovn-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct ovsrec_flow_sample_collector_set_table;
struct sbrec_datapath_binding;
struct sbrec_logical_flow;
struct sbrec_port_binding;
struct sbrec_chassis;
struct smap;
struct svec;
struct uuid;
Expand Down Expand Up @@ -353,6 +354,16 @@ int64_t daemon_startup_ts(void);
char *lr_lb_address_set_name(uint32_t lr_tunnel_key, int addr_family);
char *lr_lb_address_set_ref(uint32_t lr_tunnel_key, int addr_family);

struct chassis_aa_network {
char *network_name;
struct lport_addresses *addresses;
size_t n_addresses;
};

bool chassis_find_active_active_networks(const struct sbrec_chassis *,
const char *,
struct chassis_aa_network *);

const char *
get_chassis_external_id_value(const struct smap *,
const char *chassis_id,
Expand Down
4 changes: 4 additions & 0 deletions northd/en-northd.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ static void
northd_get_input_data(struct engine_node *node,
struct northd_input *input_data)
{
input_data->nbrec_lrp_by_name =
engine_ovsdb_node_get_index(
engine_get_input("NB_logical_router", node),
"nbrec_lrp_by_name");
input_data->sbrec_chassis_by_name =
engine_ovsdb_node_get_index(
engine_get_input("SB_chassis", node),
Expand Down
6 changes: 6 additions & 0 deletions northd/inc-proc-northd.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <stdio.h>

#include "chassis-index.h"
#include "lrp-index.h"
#include "ip-mcast-index.h"
#include "lib/inc-proc-eng.h"
#include "lib/mac-binding-index.h"
Expand Down Expand Up @@ -350,6 +351,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
.sb_idl = sb->idl,
};

struct ovsdb_idl_index *nbrec_lrp_by_name =
lrp_index_create(nb->idl);
struct ovsdb_idl_index *sbrec_chassis_by_name =
chassis_index_create(sb->idl);
struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name =
Expand All @@ -367,6 +370,9 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,

engine_init(&en_northd_output, &engine_arg);

engine_ovsdb_node_add_index(&en_nb_logical_router,
"nbrec_lrp_by_name",
nbrec_lrp_by_name);
engine_ovsdb_node_add_index(&en_sb_chassis,
"sbrec_chassis_by_name",
sbrec_chassis_by_name);
Expand Down
Loading

0 comments on commit 80bcaf2

Please sign in to comment.