Skip to content

Commit

Permalink
controller: Introduce route node.
Browse files Browse the repository at this point in the history
this engine node determines the routes that the ovn-controller should
export.

Signed-off-by: Felix Huettner <[email protected]>
Signed-off-by: 0-day Robot <[email protected]>
  • Loading branch information
felixhuettner authored and ovsrobot committed Dec 19, 2024
1 parent a0a99e7 commit 89470fe
Show file tree
Hide file tree
Showing 5 changed files with 464 additions and 2 deletions.
4 changes: 3 additions & 1 deletion controller/automake.mk
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ controller_ovn_controller_SOURCES = \
controller/ct-zone.h \
controller/ct-zone.c \
controller/ovn-dns.c \
controller/ovn-dns.h
controller/ovn-dns.h \
controller/route.h \
controller/route.c

controller_ovn_controller_LDADD = lib/libovn.la $(OVS_LIBDIR)/libopenvswitch.la
man_MANS += controller/ovn-controller.8
Expand Down
191 changes: 190 additions & 1 deletion controller/ovn-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
#include "lib/dns-resolve.h"
#include "ct-zone.h"
#include "ovn-dns.h"
#include "route.h"

VLOG_DEFINE_THIS_MODULE(main);

Expand Down Expand Up @@ -864,7 +865,8 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl)
SB_NODE(fdb, "fdb") \
SB_NODE(meter, "meter") \
SB_NODE(static_mac_binding, "static_mac_binding") \
SB_NODE(chassis_template_var, "chassis_template_var")
SB_NODE(chassis_template_var, "chassis_template_var") \
SB_NODE(advertised_route, "advertised_route")

enum sb_engine_node {
#define SB_NODE(NAME, NAME_STR) SB_##NAME,
Expand Down Expand Up @@ -4804,6 +4806,175 @@ pflow_lflow_output_sb_chassis_handler(struct engine_node *node,
return true;
}

struct ed_type_route {
/* Contains struct tracked_datapath entries for local datapaths subject to
* route exchange. */
struct hmap tracked_route_datapaths;
/* Contains struct advertise_datapath_entry */
struct hmap announce_routes;
};

static void
en_route_run(struct engine_node *node, void *data)
{
struct ed_type_route *re_data = data;
route_cleanup(&re_data->announce_routes);

const struct ovsrec_open_vswitch_table *ovs_table =
EN_OVSDB_GET(engine_get_input("OVS_open_vswitch", node));
const char *chassis_id = get_ovs_chassis_id(ovs_table);
ovs_assert(chassis_id);

struct ovsdb_idl_index *sbrec_chassis_by_name =
engine_ovsdb_node_get_index(
engine_get_input("SB_chassis", node),
"name");
const struct sbrec_chassis *chassis
= chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id);
ovs_assert(chassis);

struct ovsdb_idl_index *sbrec_port_binding_by_name =
engine_ovsdb_node_get_index(
engine_get_input("SB_port_binding", node),
"name");
struct ed_type_runtime_data *rt_data =
engine_get_input_data("runtime_data", node);

struct ovsdb_idl_index *sbrec_advertised_route_by_datapath =
engine_ovsdb_node_get_index(
engine_get_input("SB_advertised_route", node),
"datapath");

struct route_ctx_in r_ctx_in = {
.ovnsb_idl_txn = engine_get_context()->ovnsb_idl_txn,
.sbrec_port_binding_by_name = sbrec_port_binding_by_name,
.chassis = chassis,
.active_tunnels = &rt_data->active_tunnels,
.local_datapaths = &rt_data->local_datapaths,
.local_lports = &rt_data->local_lports,
.sbrec_advertised_route_by_datapath =
sbrec_advertised_route_by_datapath,
};

struct route_ctx_out r_ctx_out = {
.tracked_re_datapaths = &re_data->tracked_route_datapaths,
.announce_routes = &re_data->announce_routes,
};

route_run(&r_ctx_in, &r_ctx_out);

engine_set_node_state(node, EN_UPDATED);
}


static void *
en_route_init(struct engine_node *node OVS_UNUSED,
struct engine_arg *arg OVS_UNUSED)
{
struct ed_type_route *data = xzalloc(sizeof *data);

hmap_init(&data->tracked_route_datapaths);
hmap_init(&data->announce_routes);

return data;
}

static void
en_route_cleanup(void *data)
{
struct ed_type_route *re_data = data;

tracked_datapaths_destroy(&re_data->tracked_route_datapaths);
route_cleanup(&re_data->announce_routes);
hmap_destroy(&re_data->announce_routes);
}

static bool
route_runtime_data_handler(struct engine_node *node, void *data)
{
struct ed_type_route *re_data = data;
struct ed_type_runtime_data *rt_data =
engine_get_input_data("runtime_data", node);

if (!rt_data->tracked) {
return false;
}

struct tracked_datapath *t_dp;
HMAP_FOR_EACH (t_dp, node, &rt_data->tracked_dp_bindings) {
struct tracked_datapath *re_t_dp =
tracked_datapath_find(&re_data->tracked_route_datapaths, t_dp->dp);

if (re_t_dp) {
/* Until we get I-P support for route exchange we need to request
* recompute. */
return false;
}

struct shash_node *shash_node;
SHASH_FOR_EACH (shash_node, &t_dp->lports) {
struct tracked_lport *lport = shash_node->data;
if (route_exchange_relevant_port(lport->pb)) {
/* Until we get I-P support for route exchange we need to
* request recompute. */
return false;
}
}
}

return true;
}

static bool
route_sb_port_binding_data_handler(struct engine_node *node, void *data)
{
struct ed_type_route *re_data = data;
const struct sbrec_port_binding_table *pb_table =
EN_OVSDB_GET(engine_get_input("SB_port_binding", node));

const struct sbrec_port_binding *sbrec_pb;
SBREC_PORT_BINDING_TABLE_FOR_EACH_TRACKED (sbrec_pb, pb_table) {
struct tracked_datapath *re_t_dp =
tracked_datapath_find(&re_data->tracked_route_datapaths,
sbrec_pb->datapath);
if (re_t_dp) {
/* Until we get I-P support for route exchange we need to request
* recompute. */
return false;
}

if (route_exchange_relevant_port(sbrec_pb)) {
/* Until we get I-P support for route exchange we need to
* request recompute. */
return false;
}

}
return true;
}

static bool
route_sb_advertised_route_data_handler(struct engine_node *node, void *data)
{
struct ed_type_route *re_data = data;
const struct sbrec_advertised_route_table *advertised_route_table =
EN_OVSDB_GET(engine_get_input("SB_advertised_route", node));

const struct sbrec_advertised_route *sbrec_route;
SBREC_ADVERTISED_ROUTE_TABLE_FOR_EACH_TRACKED (sbrec_route,
advertised_route_table) {
struct tracked_datapath *re_t_dp =
tracked_datapath_find(&re_data->tracked_route_datapaths,
sbrec_route->datapath);
if (re_t_dp) {
/* Until we get I-P support for route exchange we need to request
* recompute. */
return false;
}
}
return true;
}

/* Returns false if the northd internal version stored in SB_Global
* and ovn-controller internal version don't match.
*/
Expand Down Expand Up @@ -5012,6 +5183,9 @@ main(int argc, char *argv[])
struct ovsdb_idl_index *sbrec_chassis_template_var_index_by_chassis
= ovsdb_idl_index_create1(ovnsb_idl_loop.idl,
&sbrec_chassis_template_var_col_chassis);
struct ovsdb_idl_index *sbrec_advertised_route_index_by_datapath
= ovsdb_idl_index_create1(ovnsb_idl_loop.idl,
&sbrec_advertised_route_col_datapath);

ovsdb_idl_track_add_all(ovnsb_idl_loop.idl);
ovsdb_idl_omit_alert(ovnsb_idl_loop.idl,
Expand Down Expand Up @@ -5095,6 +5269,7 @@ main(int argc, char *argv[])
ENGINE_NODE(mac_cache, "mac_cache");
ENGINE_NODE(bfd_chassis, "bfd_chassis");
ENGINE_NODE(dns_cache, "dns_cache");
ENGINE_NODE(route, "route");

#define SB_NODE(NAME, NAME_STR) ENGINE_NODE_SB(NAME, NAME_STR);
SB_NODES
Expand All @@ -5117,6 +5292,15 @@ main(int argc, char *argv[])
engine_add_input(&en_lb_data, &en_runtime_data,
lb_data_runtime_data_handler);

engine_add_input(&en_route, &en_ovs_open_vswitch, NULL);
engine_add_input(&en_route, &en_sb_chassis, NULL);
engine_add_input(&en_route, &en_sb_port_binding,
route_sb_port_binding_data_handler);
engine_add_input(&en_route, &en_runtime_data,
route_runtime_data_handler);
engine_add_input(&en_route, &en_sb_advertised_route,
route_sb_advertised_route_data_handler);

engine_add_input(&en_addr_sets, &en_sb_address_set,
addr_sets_sb_address_set_handler);
engine_add_input(&en_port_groups, &en_sb_port_group,
Expand Down Expand Up @@ -5302,6 +5486,9 @@ main(int argc, char *argv[])
controller_output_mac_cache_handler);
engine_add_input(&en_controller_output, &en_bfd_chassis,
controller_output_bfd_chassis_handler);
/* This is just temporary until the route output is actually used. */
engine_add_input(&en_controller_output, &en_route,
controller_output_bfd_chassis_handler);

struct engine_arg engine_arg = {
.sb_idl = ovnsb_idl_loop.idl,
Expand Down Expand Up @@ -5332,6 +5519,8 @@ main(int argc, char *argv[])
sbrec_static_mac_binding_by_datapath);
engine_ovsdb_node_add_index(&en_sb_chassis_template_var, "chassis",
sbrec_chassis_template_var_index_by_chassis);
engine_ovsdb_node_add_index(&en_sb_advertised_route, "datapath",
sbrec_advertised_route_index_by_datapath);
engine_ovsdb_node_add_index(&en_ovs_flow_sample_collector_set, "id",
ovsrec_flow_sample_collector_set_by_id);
engine_ovsdb_node_add_index(&en_ovs_port, "qos", ovsrec_port_by_qos);
Expand Down
Loading

0 comments on commit 89470fe

Please sign in to comment.