Create a handler for deleted and updated static routes,
and change the handler from engine route which check if
it has a new static route created.
Test with 2000 static routes created in the same logical router
and add a new one:
Without the incremental processing:
ovn-nbctl --print-wait-time --wait=sb lr-route-add lr1-2 10.0.0.1/32
192.168.20.2
Time spent on processing nb_cfg 4:
ovn-northd delay before processing: 4ms
ovn-northd completion: 62ms
With the incremental processing:
ovn-nbctl --print-wait-time --wait=sb lr-route-add lr1-2 10.0.0.1/32
192.168.20.2
Time spent on processing nb_cfg 6:
ovn-northd delay before processing: 4ms
ovn-northd completion: 21ms
Test with 2000 static routes created in the same logical router
and delete one:
Without the incremental processing:
ovn-nbctl --print-wait-time --wait=sb lr-route-del lr1-2 10.0.0.1/32
192.168.20.2
Time spent on processing nb_cfg 5:
ovn-northd delay before processing: 3ms
ovn-northd completion: 62ms
With the incremental processing:
ovn-nbctl --print-wait-time --wait=sb lr-route-del lr1-2 10.0.0.1/32
192.168.20.2
Time spent on processing nb_cfg 9:
ovn-northd delay before processing: 2ms
ovn-northd completion: 32ms
Signed-off-by: Lucas Vargas Dias <[email protected]>
---
northd/en-group-ecmp-route.c | 55 ++++++++++++
northd/en-group-ecmp-route.h | 4 +
northd/en-lflow.c | 20 +++++
northd/en-lflow.h | 2 +
northd/en-northd.c | 144 +++++++++++++++++++++++++++----
northd/en-northd.h | 5 +-
northd/inc-proc-northd.c | 13 ++-
northd/northd.c | 106 +++++++++++++++++------
northd/northd.h | 37 +++++++-
tests/ovn-inc-proc-graph-dump.at | 6 +-
tests/ovn-northd.at | 18 ++--
11 files changed, 349 insertions(+), 61 deletions(-)
diff --git a/northd/en-group-ecmp-route.c b/northd/en-group-ecmp-route.c
index cd4cdb991..0405fb5d8 100644
--- a/northd/en-group-ecmp-route.c
+++ b/northd/en-group-ecmp-route.c
@@ -510,3 +510,58 @@ group_ecmp_route_learned_route_change_handler(struct
engine_node *eng_node,
}
return EN_HANDLED_UNCHANGED;
}
+
+enum engine_input_handler_result
+group_ecmp_static_route_change_handler(struct engine_node *eng_node,
+ void *_data)
+{
+ struct routes_data *routes_data
+ = engine_get_input_data("routes", eng_node);
+ struct group_ecmp_route_data *data = _data;
+ if (!routes_data->tracked) {
+ data->tracked = false;
+ return EN_UNHANDLED;
+ }
+
+ struct parsed_route *pr;
+ struct hmapx updated_routes = HMAPX_INITIALIZER(&updated_routes);
+
+ const struct hmapx_node *hmapx_node;
+ HMAPX_FOR_EACH (hmapx_node,
+ &routes_data->trk_data.trk_deleted_parsed_route) {
+ pr = hmapx_node->data;
+ if (!handle_deleted_route(data, pr, &updated_routes)) {
+ hmapx_destroy(&updated_routes);
+ return EN_UNHANDLED;
+ }
+ hmap_remove(&routes_data->parsed_routes, &pr->key_node);
+ parsed_route_free(pr);
+ }
+
+ HMAPX_FOR_EACH (hmapx_node,
+ &routes_data->trk_data.trk_crupdated_parsed_route) {
+ pr = hmapx_node->data;
+ handle_added_route(data, pr, &updated_routes);
+ }
+
+
+ HMAPX_FOR_EACH (hmapx_node, &updated_routes) {
+ struct group_ecmp_datapath *node = hmapx_node->data;
+ if (hmap_is_empty(&node->unique_routes) &&
+ hmap_is_empty(&node->ecmp_groups)) {
+ hmapx_add(&data->trk_data.deleted_datapath_routes, node);
+ hmap_remove(&data->datapaths, &node->hmap_node);
+ } else {
+ hmapx_add(&data->trk_data.crupdated_datapath_routes, node);
+ }
+ }
+
+ hmapx_destroy(&updated_routes);
+
+ if (!(hmapx_is_empty(&data->trk_data.crupdated_datapath_routes) &&
+ hmapx_is_empty(&data->trk_data.deleted_datapath_routes))) {
+ data->tracked = true;
+ return EN_HANDLED_UPDATED;
+ }
+ return EN_HANDLED_UNCHANGED;
+}
diff --git a/northd/en-group-ecmp-route.h b/northd/en-group-ecmp-route.h
index 784004347..874c8ddd7 100644
--- a/northd/en-group-ecmp-route.h
+++ b/northd/en-group-ecmp-route.h
@@ -97,6 +97,10 @@ enum engine_input_handler_result
group_ecmp_route_learned_route_change_handler(struct engine_node *,
void *data);
+enum engine_input_handler_result
+group_ecmp_static_route_change_handler(struct engine_node *,
+ void *data);
+
struct group_ecmp_datapath *group_ecmp_datapath_lookup(
const struct group_ecmp_route_data *data,
const struct ovn_datapath *od);
diff --git a/northd/en-lflow.c b/northd/en-lflow.c
index d4351edb9..22cd8fe91 100644
--- a/northd/en-lflow.c
+++ b/northd/en-lflow.c
@@ -297,6 +297,21 @@ lflow_multicast_igmp_handler(struct engine_node *node,
void *data)
return EN_HANDLED_UPDATED;
}
+enum engine_input_handler_result
+lflow_group_route_change_handler(struct engine_node *node,
+ void *data OVS_UNUSED)
+{
+ struct routes_data *route_data =
+ engine_get_input_data("routes", node);
+
+ /* If we do not have tracked data we need to recompute. */
+ if (!route_data->tracked) {
+ return EN_UNHANDLED;
+ }
+
+ return EN_HANDLED_UNCHANGED;
+}
+
enum engine_input_handler_result
lflow_group_ecmp_route_change_handler(struct engine_node *node,
void *data OVS_UNUSED)
@@ -346,6 +361,11 @@ lflow_group_ecmp_route_change_handler(struct engine_node
*node,
route_node->od, lflow_data->lflow_table,
route_node, lflow_input.bfd_ports);
+ build_arp_request_flows_for_lrouter(route_node->od,
+ lflow_data->lflow_table,
+ lflow_input.meter_groups,
+ route_node->lflow_ref);
+
bool handled = lflow_ref_sync_lflows(
route_node->lflow_ref, lflow_data->lflow_table,
eng_ctx->ovnsb_idl_txn, lflow_input.dps,
diff --git a/northd/en-lflow.h b/northd/en-lflow.h
index d2a92e49f..aa320615f 100644
--- a/northd/en-lflow.h
+++ b/northd/en-lflow.h
@@ -31,5 +31,7 @@ lflow_multicast_igmp_handler(struct engine_node *node, void
*data);
enum engine_input_handler_result
lflow_group_ecmp_route_change_handler(struct engine_node *node, void *data);
enum engine_input_handler_result
+lflow_group_route_change_handler(struct engine_node *node, void *data);
+enum engine_input_handler_result
lflow_ic_learned_svc_mons_handler(struct engine_node *node, void *data);
#endif /* EN_LFLOW_H */
diff --git a/northd/en-northd.c b/northd/en-northd.c
index a828f9a5f..e97642b71 100644
--- a/northd/en-northd.c
+++ b/northd/en-northd.c
@@ -203,7 +203,8 @@ northd_nb_logical_router_handler(struct engine_node *node,
}
if (northd_has_lr_nats_in_tracked_data(&nd->trk_data) ||
- northd_has_lrouters_in_tracked_data(&nd->trk_data)) {
+ northd_has_lrouters_in_tracked_data(&nd->trk_data) ||
+ northd_has_lr_routes_in_tracked_data(&nd->trk_data)) {
return EN_HANDLED_UPDATED;
}
@@ -325,30 +326,130 @@ en_route_policies_run(struct engine_node *node, void
*data)
enum engine_input_handler_result
routes_northd_change_handler(struct engine_node *node,
- void *data OVS_UNUSED)
+ void *data)
{
struct northd_data *northd_data = engine_get_input_data("northd", node);
if (!northd_has_tracked_data(&northd_data->trk_data)) {
return EN_UNHANDLED;
}
- /* This node uses the below data from the en_northd engine node.
- * See (lr_stateful_get_input_data())
- * 1. northd_data->lr_datapaths
- * 2. northd_data->lr_ports
- * This data gets updated when a logical router or logical router port
- * is created or deleted.
- * Northd engine node presently falls back to full recompute when
- * this happens and so does this node.
- * Note: When we add I-P to the created/deleted logical routers or
- * logical router ports, we need to revisit this handler.
- *
- * This node also accesses the static routes of the logical router.
- * When these static routes gets updated, en_northd engine recomputes
- * and so does this node.
- * Note: When we add I-P to handle static routes changes, we need
- * to revisit this handler.
- */
+ if (!northd_has_lr_route_in_tracked_data(&northd_data->trk_data)) {
+ return EN_HANDLED_UNCHANGED;
+ }
+
+ struct bfd_data *bfd_data = engine_get_input_data("bfd", node);
+ struct routes_data *routes_data = data;
+ struct hmapx_node *hmapx_node;
+ struct ovn_datapath *od;
+ HMAPX_FOR_EACH (hmapx_node, &northd_data->trk_data.trk_lrs_routes) {
+ od = hmapx_node->data;
+ struct parsed_route *pr;
+
+ for (int i = 0; i < od->nbr->n_static_routes; i++) {
+ struct nbrec_logical_router_static_route *static_route =
+ od->nbr->static_routes[i];
+ if (nbrec_logical_router_static_route_is_new(static_route)) {
+ pr = parsed_routes_add_static(
+ od, &northd_data->lr_ports,
+ static_route,
+ &bfd_data->bfd_connections,
+ &routes_data->parsed_routes,
+ &routes_data->route_tables,
+ &routes_data->bfd_active_connections);
+ if (!pr) {
+ continue;
+ }
+ pr->stale = false;
+
+ hmapx_add(&routes_data->trk_data.trk_crupdated_parsed_route,
+ pr);
+ }
+ }
+ }
+
+ if (!hmapx_is_empty(&routes_data->trk_data.trk_crupdated_parsed_route)) {
+ routes_data->tracked = true;
+ return EN_HANDLED_UPDATED;
+ }
+
+ if (hmapx_is_empty(&routes_data->trk_data.trk_crupdated_parsed_route) &&
+ hmapx_is_empty(&routes_data->trk_data.trk_deleted_parsed_route)) {
+ return EN_UNHANDLED;
+ }
+
+ return EN_HANDLED_UNCHANGED;
+}
+enum engine_input_handler_result
+routes_static_route_change_handler(struct engine_node *node,
+ void *data)
+{
+ struct routes_data *routes_data = data;
+
+ const struct nbrec_logical_router_static_route_table *
+ nb_lr_static_route_table =
+ EN_OVSDB_GET(engine_get_input("NB_logical_router_static_route", node));
+
+ struct northd_data *northd_data = engine_get_input_data("northd", node);
+ struct bfd_data *bfd_data = engine_get_input_data("bfd", node);
+
+ const struct nbrec_logical_router_static_route *changed_static_route;
+ NBREC_LOGICAL_ROUTER_STATIC_ROUTE_TABLE_FOR_EACH (
+ changed_static_route, nb_lr_static_route_table) {
+
+ if (nbrec_logical_router_static_route_is_new(changed_static_route)) {
+ continue;
+ }
+ bool is_deleted = nbrec_logical_router_static_route_is_deleted(
+ changed_static_route);
+ if (is_deleted) {
+ struct parsed_route *pr = parsed_route_lookup_by_source(
+ ROUTE_SOURCE_STATIC,
+ &changed_static_route->header_,
+ &routes_data->parsed_routes);
+ if (pr) {
+ pr->stale = true;
+ }
+ hmapx_add(&routes_data->trk_data.trk_deleted_parsed_route, pr);
+ continue;
+ }
+ if (nbrec_logical_router_static_route_is_updated(
+ changed_static_route,
+ NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_NEXTHOP)
+ || nbrec_logical_router_static_route_is_updated(
+ changed_static_route,
+ NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_OUTPUT_PORT)
+ || nbrec_logical_router_static_route_is_updated(
+ changed_static_route,
+ NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_POLICY)
+ || nbrec_logical_router_static_route_is_updated(
+ changed_static_route,
+ NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_ROUTE_TABLE)
+ || nbrec_logical_router_static_route_is_updated(
+ changed_static_route,
+ NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_SELECTION_FIELDS)) {
+ struct parsed_route *pr = parsed_route_lookup_by_source(
+ ROUTE_SOURCE_STATIC,
+ &changed_static_route->header_,
+ &routes_data->parsed_routes);
+ if (!pr || !pr->od || !northd_data || !bfd_data) {
+ continue;
+ }
+ parsed_routes_add_static(pr->od, &northd_data->lr_ports,
+ changed_static_route,
+ &bfd_data->bfd_connections,
+ &routes_data->parsed_routes,
+ &routes_data->route_tables,
+ &routes_data->bfd_active_connections);
+ hmapx_add(&routes_data->trk_data.trk_crupdated_parsed_route,
+ pr);
+ }
+ }
+ if (!hmapx_is_empty(&routes_data->trk_data.trk_crupdated_parsed_route) ||
+ !hmapx_is_empty(&routes_data->trk_data.trk_deleted_parsed_route)) {
+ routes_data->tracked = true;
+ return EN_HANDLED_UPDATED;
+ }
+
return EN_HANDLED_UNCHANGED;
}
@@ -586,6 +687,11 @@ en_routes_cleanup(void *data)
routes_destroy(data);
}
+void
+en_routes_clear_tracked_data(void *data)
+{
+ routes_clear_tracked(data);
+}
void
en_bfd_cleanup(void *data)
{
diff --git a/northd/en-northd.h b/northd/en-northd.h
index 7794739b9..5247f3e11 100644
--- a/northd/en-northd.h
+++ b/northd/en-northd.h
@@ -39,9 +39,12 @@ enum engine_node_state en_route_policies_run(struct
engine_node *node,
void *data);
void *en_route_policies_init(struct engine_node *node OVS_UNUSED,
struct engine_arg *arg OVS_UNUSED);
+void en_routes_clear_tracked_data(void *data);
void en_routes_cleanup(void *data);
enum engine_input_handler_result
-routes_northd_change_handler(struct engine_node *node, void *data OVS_UNUSED);
+routes_northd_change_handler(struct engine_node *node, void *data);
+enum engine_input_handler_result
+routes_static_route_change_handler(struct engine_node *node, void *data);
enum engine_node_state en_routes_run(struct engine_node *node, void *data);
void *en_bfd_init(struct engine_node *node OVS_UNUSED,
struct engine_arg *arg OVS_UNUSED);
diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
index 10bad4bab..7d03dd7ef 100644
--- a/northd/inc-proc-northd.c
+++ b/northd/inc-proc-northd.c
@@ -76,7 +76,9 @@ static unixctl_cb_func chassis_features_list;
NB_NODE(sampling_app) \
NB_NODE(network_function) \
NB_NODE(network_function_group) \
- NB_NODE(logical_switch_port_health_check)
+ NB_NODE(logical_switch_port_health_check) \
+ NB_NODE(logical_router_static_route)
+
enum nb_engine_node {
#define NB_NODE(NAME) NB_##NAME,
@@ -178,7 +180,7 @@ static ENGINE_NODE(lr_stateful, CLEAR_TRACKED_DATA);
static ENGINE_NODE(ls_stateful, CLEAR_TRACKED_DATA);
static ENGINE_NODE(ls_arp, CLEAR_TRACKED_DATA);
static ENGINE_NODE(route_policies);
-static ENGINE_NODE(routes);
+static ENGINE_NODE(routes, CLEAR_TRACKED_DATA);
static ENGINE_NODE(bfd);
static ENGINE_NODE(bfd_sync, SB_WRITE);
static ENGINE_NODE(ecmp_nexthop, SB_WRITE);
@@ -335,6 +337,8 @@ 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_nb_logical_router_static_route,
+ routes_static_route_change_handler);
engine_add_input(&en_bfd_sync, &en_bfd, NULL);
engine_add_input(&en_bfd_sync, &en_nb_bfd, NULL);
@@ -374,7 +378,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
engine_add_input(&en_learned_route_sync, &en_northd,
learned_route_sync_northd_change_handler);
- engine_add_input(&en_group_ecmp_route, &en_routes, NULL);
+ engine_add_input(&en_group_ecmp_route, &en_routes,
+ group_ecmp_static_route_change_handler);
engine_add_input(&en_group_ecmp_route, &en_learned_route_sync,
group_ecmp_route_learned_route_change_handler);
@@ -393,7 +398,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
engine_add_input(&en_lflow, &en_sb_logical_dp_group, NULL);
engine_add_input(&en_lflow, &en_bfd_sync, NULL);
engine_add_input(&en_lflow, &en_route_policies, NULL);
- engine_add_input(&en_lflow, &en_routes, NULL);
+ engine_add_input(&en_lflow, &en_routes, lflow_group_route_change_handler);
/* XXX: The incremental processing only supports changes to learned routes.
* All other changes trigger a full recompute. */
engine_add_input(&en_lflow, &en_group_ecmp_route,
diff --git a/northd/northd.c b/northd/northd.c
index 05702bb49..602b84fc6 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -4411,6 +4411,7 @@ destroy_northd_data_tracked_changes(struct northd_data
*nd)
destroy_tracked_ovn_ports(&trk_changes->trk_lsps);
destroy_tracked_lbs(&trk_changes->trk_lbs);
hmapx_clear(&trk_changes->trk_nat_lrs);
+ hmapx_clear(&trk_changes->trk_lrs_routes);
hmapx_clear(&trk_changes->ls_with_changed_lbs);
hmapx_clear(&trk_changes->ls_with_changed_acls);
hmapx_clear(&trk_changes->ls_with_changed_ipam);
@@ -4434,6 +4435,7 @@ init_northd_tracked_data(struct northd_data *nd)
hmapx_init(&trk_data->trk_lbs.crupdated);
hmapx_init(&trk_data->trk_lbs.deleted);
hmapx_init(&trk_data->trk_nat_lrs);
+ hmapx_init(&trk_data->trk_lrs_routes);
hmapx_init(&trk_data->ls_with_changed_lbs);
hmapx_init(&trk_data->ls_with_changed_acls);
hmapx_init(&trk_data->ls_with_changed_ipam);
@@ -4452,6 +4454,7 @@ destroy_northd_tracked_data(struct northd_data *nd)
hmapx_destroy(&trk_data->trk_lbs.crupdated);
hmapx_destroy(&trk_data->trk_lbs.deleted);
hmapx_destroy(&trk_data->trk_nat_lrs);
+ hmapx_destroy(&trk_data->trk_lrs_routes);
hmapx_destroy(&trk_data->ls_with_changed_lbs);
hmapx_destroy(&trk_data->ls_with_changed_acls);
hmapx_destroy(&trk_data->ls_with_changed_ipam);
@@ -5257,7 +5260,8 @@ lr_changes_can_be_handled(const struct
nbrec_logical_router *lr)
if (nbrec_logical_router_is_updated(lr, col)) {
if (col == NBREC_LOGICAL_ROUTER_COL_LOAD_BALANCER
|| col == NBREC_LOGICAL_ROUTER_COL_LOAD_BALANCER_GROUP
- || col == NBREC_LOGICAL_ROUTER_COL_NAT) {
+ || col == NBREC_LOGICAL_ROUTER_COL_NAT
+ || col == NBREC_LOGICAL_ROUTER_COL_STATIC_ROUTES) {
continue;
}
return false;
@@ -5313,6 +5317,12 @@ is_lr_nats_changed(const struct nbrec_logical_router
*nbr) {
|| is_lr_nats_seqno_changed(nbr));
}
+static bool
+is_lr_static_routes_changed(const struct nbrec_logical_router *nbr) {
+ return nbrec_logical_router_is_updated(nbr,
+ NBREC_LOGICAL_ROUTER_COL_STATIC_ROUTES);
+}
+
/* Return true if changes are handled incrementally, false otherwise.
*
* Note: Changes to load balancer and load balancer groups associated with
@@ -5380,6 +5390,19 @@ northd_handle_lr_changes(const struct northd_input *ni,
}
hmapx_add(&nd->trk_data.trk_nat_lrs, od);
+ } else if (is_lr_static_routes_changed(changed_lr)) {
+ struct ovn_datapath *od = ovn_datapath_find_(
+ &nd->lr_datapaths.datapaths,
+ &changed_lr->header_.uuid);
+
+ if (!od) {
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
+ VLOG_WARN_RL(&rl, "Internal error: a tracked updated LR "
+ "doesn't exist in lr_datapaths: "UUID_FMT,
+ UUID_ARGS(&changed_lr->header_.uuid));
+ goto fail;
+ }
+ hmapx_add(&nd->trk_data.trk_lrs_routes, od);
}
}
@@ -5421,6 +5444,9 @@ northd_handle_lr_changes(const struct northd_input *ni,
if (!hmapx_is_empty(&nd->trk_data.trk_nat_lrs)) {
nd->trk_data.type |= NORTHD_TRACKED_LR_NATS;
}
+ if (!hmapx_is_empty(&nd->trk_data.trk_lrs_routes)) {
+ nd->trk_data.type |= NORTHD_TRACKED_LR_ROUTES;
+ }
if (!hmapx_is_empty(&nd->trk_data.trk_routers.crupdated) ||
!hmapx_is_empty(&nd->trk_data.trk_routers.deleted)) {
nd->trk_data.type |= NORTHD_TRACKED_ROUTERS;
@@ -11926,8 +11952,17 @@ parsed_route_lookup(struct hmap *routes, size_t hash,
continue;
}
- if (pr->nexthop && ipv6_addr_equals(pr->nexthop, new_pr->nexthop)) {
- continue;
+ if (pr->nexthop) {
+ if (IN6_IS_ADDR_V4MAPPED(pr->nexthop)) {
+ if (in6_addr_get_mapped_ipv4(pr->nexthop) !=
+ in6_addr_get_mapped_ipv4(new_pr->nexthop)) {
+ continue;
+ }
+ } else {
+ if (!ipv6_addr_equals(pr->nexthop, new_pr->nexthop)) {
+ continue;
+ }
+ }
}
if (memcmp(&pr->prefix, &new_pr->prefix, sizeof(struct in6_addr))) {
@@ -12109,7 +12144,7 @@ parsed_route_add(const struct ovn_datapath *od,
}
}
-static void
+struct parsed_route *
parsed_routes_add_static(const struct ovn_datapath *od,
const struct hmap *lr_ports,
const struct nbrec_logical_router_static_route *route,
@@ -12130,8 +12165,9 @@ parsed_routes_add_static(const struct ovn_datapath *od,
UUID_FMT, route->nexthop,
UUID_ARGS(&route->header_.uuid));
free(nexthop);
- return;
+ return NULL;
}
+
if ((IN6_IS_ADDR_V4MAPPED(nexthop) && plen != 32) ||
(!IN6_IS_ADDR_V4MAPPED(nexthop) && plen != 128)) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
@@ -12139,7 +12175,7 @@ parsed_routes_add_static(const struct ovn_datapath *od,
UUID_FMT, route->nexthop,
UUID_ARGS(&route->header_.uuid));
free(nexthop);
- return;
+ return NULL;
}
}
@@ -12151,7 +12187,7 @@ parsed_routes_add_static(const struct ovn_datapath *od,
UUID_FMT, route->ip_prefix,
UUID_ARGS(&route->header_.uuid));
free(nexthop);
- return;
+ return NULL;
}
/* Verify that ip_prefix and nexthop are on the same network. */
@@ -12162,7 +12198,7 @@ parsed_routes_add_static(const struct ovn_datapath *od,
IN6_IS_ADDR_V4MAPPED(&prefix),
&lrp_addr_s, &out_port)) {
free(nexthop);
- return;
+ return NULL;
}
const struct nbrec_bfd *nb_bt = route->bfd;
@@ -12172,7 +12208,7 @@ parsed_routes_add_static(const struct ovn_datapath *od,
nb_bt->dst_ip);
if (!bfd_e) {
free(nexthop);
- return;
+ return NULL;
}
/* This static route is linked to an active bfd session. */
@@ -12191,8 +12227,8 @@ parsed_routes_add_static(const struct ovn_datapath *od,
if (!strcmp(bfd_sr->status, "down")) {
- free(nexthop);
- return;
+ free(nexthop);
+ return NULL;
}
}
@@ -12229,11 +12265,15 @@ parsed_routes_add_static(const struct ovn_datapath
*od,
source = ROUTE_SOURCE_STATIC;
}
- parsed_route_add(od, nexthop, &prefix, plen, is_discard_route, lrp_addr_s,
- out_port, route_table_id, is_src_route,
- ecmp_symmetric_reply, &ecmp_selection_fields, source,
- &route->header_, NULL, routes);
+ struct parsed_route *pr = parsed_route_add(od, nexthop, &prefix, plen,
+ is_discard_route, lrp_addr_s,
+ out_port, route_table_id,
+ is_src_route,
+ ecmp_symmetric_reply,
+ &ecmp_selection_fields, source,
+ &route->header_, NULL, routes);
sset_destroy(&ecmp_selection_fields);
+ return pr;
}
static void
@@ -16097,13 +16137,14 @@ build_lr_gateway_redirect_flows_for_nats(
* In the common case where the Ethernet destination has been resolved,
* this table outputs the packet (priority 0). Otherwise, it composes
* and sends an ARP/IPv6 NA request (priority 100). */
-static void
+void
build_arp_request_flows_for_lrouter(
- struct ovn_datapath *od, struct lflow_table *lflows,
- struct ds *match, struct ds *actions,
+ const struct ovn_datapath *od, struct lflow_table *lflows,
const struct shash *meter_groups,
struct lflow_ref *lflow_ref)
{
+ struct ds match = DS_EMPTY_INITIALIZER;
+ struct ds actions = DS_EMPTY_INITIALIZER;
ovs_assert(od->nbr);
for (int i = 0; i < od->nbr->n_static_routes; i++) {
const struct nbrec_logical_router_static_route *route;
@@ -16117,8 +16158,8 @@ build_arp_request_flows_for_lrouter(
continue;
}
- ds_clear(match);
- ds_put_format(match, "eth.dst == 00:00:00:00:00:00 && "
+ ds_clear(&match);
+ ds_put_format(&match, "eth.dst == 00:00:00:00:00:00 && "
REGBIT_NEXTHOP_IS_IPV4" == 0 && "
REG_NEXT_HOP_IPV6 " == %s",
route->nexthop);
@@ -16130,8 +16171,8 @@ build_arp_request_flows_for_lrouter(
char sn_addr_s[INET6_ADDRSTRLEN + 1];
ipv6_string_mapped(sn_addr_s, &sn_addr);
- ds_clear(actions);
- ds_put_format(actions,
+ ds_clear(&actions);
+ ds_put_format(&actions,
"nd_ns { "
"eth.dst = "ETH_ADDR_FMT"; "
"ip6.dst = %s; "
@@ -16141,7 +16182,7 @@ build_arp_request_flows_for_lrouter(
route->nexthop);
ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 200,
- ds_cstr(match), ds_cstr(actions), lflow_ref,
+ ds_cstr(&match), ds_cstr(&actions), lflow_ref,
WITH_CTRL_METER(copp_meter_get(COPP_ND_NS_RESOLVE,
od->nbr->copp,
meter_groups)),
@@ -16173,6 +16214,8 @@ build_arp_request_flows_for_lrouter(
meter_groups)));
ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 0, "1", "next;",
lflow_ref);
+ ds_destroy(&match);
+ ds_destroy(&actions);
}
static void
@@ -19296,8 +19339,7 @@ build_lswitch_and_lrouter_iterate_by_lr(struct
ovn_datapath *od,
build_gateway_redirect_flows_for_lrouter(od, lsi->lflows, &lsi->match,
&lsi->actions,
od->datapath_lflows);
- build_arp_request_flows_for_lrouter(od, lsi->lflows, &lsi->match,
- &lsi->actions,
+ build_arp_request_flows_for_lrouter(od, lsi->lflows,
lsi->meter_groups,
od->datapath_lflows);
build_ecmp_stateful_egr_flows_for_lrouter(od, lsi->lflows,
@@ -20855,6 +20897,9 @@ routes_init(struct routes_data *data)
hmap_init(&data->parsed_routes);
simap_init(&data->route_tables);
hmap_init(&data->bfd_active_connections);
+ data->tracked = false;
+ hmapx_init(&data->trk_data.trk_deleted_parsed_route);
+ hmapx_init(&data->trk_data.trk_crupdated_parsed_route);
}
void
@@ -20985,6 +21030,17 @@ routes_destroy(struct routes_data *data)
simap_destroy(&data->route_tables);
__bfd_destroy(&data->bfd_active_connections);
+ data->tracked = false;
+ hmapx_destroy(&data->trk_data.trk_crupdated_parsed_route);
+ hmapx_destroy(&data->trk_data.trk_deleted_parsed_route);
+}
+
+void
+routes_clear_tracked(struct routes_data *data)
+{
+ data->tracked = false;
+ hmapx_clear(&data->trk_data.trk_crupdated_parsed_route);
+ hmapx_clear(&data->trk_data.trk_deleted_parsed_route);
}
void
diff --git a/northd/northd.h b/northd/northd.h
index 4165b6fdd..ba8ddc430 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -159,6 +159,7 @@ enum northd_tracked_data_type {
NORTHD_TRACKED_LS_ACLS = (1 << 4),
NORTHD_TRACKED_SWITCHES = (1 << 5),
NORTHD_TRACKED_ROUTERS = (1 << 6),
+ NORTHD_TRACKED_LR_ROUTES = (1 << 7),
};
/* Track what's changed in the northd engine node.
@@ -176,6 +177,10 @@ struct northd_tracked_data {
* hmapx node is 'struct ovn_datapath *'. */
struct hmapx trk_nat_lrs;
+ /* Tracked logical routers whose static routes have changed.
+ * hmapx node is 'struct ovn_datapath *'. */
+ struct hmapx trk_lrs_routes;
+
/* Tracked logical switches whose load balancers have changed.
* hmapx node is 'struct ovn_datapath *'. */
struct hmapx ls_with_changed_lbs;
@@ -216,10 +221,23 @@ struct route_policy {
uint32_t jump_chain_id;
};
+struct route_tracked_data {
+ /* Contains references to group_ecmp_route_node. Each of the referenced
+ * datapaths contains at least one route. */
+ struct hmapx trk_crupdated_parsed_route;
+
+ /* Contains references to group_ecmp_route_node. Each of the referenced
+ * datapath previously had some routes. The datapath now no longer
+ * contains any route.*/
+ struct hmapx trk_deleted_parsed_route;
+};
+
struct routes_data {
struct hmap parsed_routes; /* Stores struct parsed_route. */
struct simap route_tables;
struct hmap bfd_active_connections;
+ bool tracked;
+ struct route_tracked_data trk_data;
};
struct route_policies_data {
@@ -874,6 +892,14 @@ struct parsed_route *parsed_route_add(
const struct ovn_port *tracked_port,
struct hmap *routes);
+struct parsed_route * parsed_routes_add_static(
+ const struct ovn_datapath *od,
+ const struct hmap *lr_ports,
+ const struct nbrec_logical_router_static_route *route,
+ const struct hmap *bfd_connections,
+ struct hmap *routes, struct simap *route_tables,
+ struct hmap *bfd_active_connections);
+
struct svc_monitors_map_data {
const struct hmap *local_svc_monitors_map;
const struct hmap *ic_learned_svc_monitors_map;
@@ -918,7 +944,7 @@ void build_parsed_routes(const struct ovn_datapath *, const
struct hmap *,
uint32_t get_route_table_id(struct simap *, const char *);
void routes_init(struct routes_data *);
void routes_destroy(struct routes_data *);
-
+void routes_clear_tracked(struct routes_data *);
void bfd_init(struct bfd_data *);
void bfd_destroy(struct bfd_data *);
@@ -944,6 +970,10 @@ void build_route_data_flows_for_lrouter(
const struct ovn_datapath *od, struct lflow_table *lflows,
const struct group_ecmp_datapath *route_node,
const struct sset *bfd_ports);
+void build_arp_request_flows_for_lrouter(
+ const struct ovn_datapath *od, struct lflow_table *lflows,
+ const struct shash *meter_groups,
+ struct lflow_ref *lflow_ref);
bool lflow_handle_northd_lr_changes(struct ovsdb_idl_txn *ovnsh_txn,
struct tracked_dps *,
@@ -1034,6 +1064,11 @@ northd_has_lr_nats_in_tracked_data(struct
northd_tracked_data *trk_nd_changes)
{
return trk_nd_changes->type & NORTHD_TRACKED_LR_NATS;
}
+static inline bool
+northd_has_lr_route_in_tracked_data(struct northd_tracked_data *trk_nd_changes)
+{
+ return trk_nd_changes->type & NORTHD_TRACKED_LR_ROUTES;
+}
static inline bool
northd_has_ls_lbs_in_tracked_data(struct northd_tracked_data *trk_nd_changes)
diff --git a/tests/ovn-inc-proc-graph-dump.at b/tests/ovn-inc-proc-graph-dump.at
index 69b4bee98..de1c4696b 100644
--- a/tests/ovn-inc-proc-graph-dump.at
+++ b/tests/ovn-inc-proc-graph-dump.at
@@ -149,9 +149,11 @@ digraph "Incremental-Processing-Engine" {
bfd [[style=filled, shape=box, fillcolor=white, label="bfd"]];
NB_bfd -> bfd [[label=""]];
SB_bfd -> bfd [[label=""]];
+ NB_logical_router_static_route [[style=filled, shape=box,
fillcolor=white, label="NB_logical_router_static_route"]];
routes [[style=filled, shape=box, fillcolor=white, label="routes"]];
bfd -> routes [[label=""]];
northd -> routes [[label="routes_northd_change_handler"]];
+ NB_logical_router_static_route -> routes
[[label="routes_static_route_change_handler"]];
route_policies [[style=filled, shape=box, fillcolor=white,
label="route_policies"]];
bfd -> route_policies [[label=""]];
northd -> route_policies
[[label="route_policies_northd_change_handler"]];
@@ -166,7 +168,7 @@ digraph "Incremental-Processing-Engine" {
SB_learned_route -> learned_route_sync
[[label="learned_route_sync_sb_learned_route_change_handler"]];
northd -> learned_route_sync
[[label="learned_route_sync_northd_change_handler"]];
group_ecmp_route [[style=filled, shape=box, fillcolor=white,
label="group_ecmp_route"]];
- routes -> group_ecmp_route [[label=""]];
+ routes -> group_ecmp_route
[[label="group_ecmp_static_route_change_handler"]];
learned_route_sync -> group_ecmp_route
[[label="group_ecmp_route_learned_route_change_handler"]];
ls_stateful [[style=filled, shape=box, fillcolor=white,
label="ls_stateful"]];
northd -> ls_stateful [[label="ls_stateful_northd_handler"]];
@@ -187,7 +189,7 @@ digraph "Incremental-Processing-Engine" {
SB_logical_dp_group -> lflow [[label=""]];
bfd_sync -> lflow [[label=""]];
route_policies -> lflow [[label=""]];
- routes -> lflow [[label=""]];
+ routes -> lflow [[label="lflow_group_route_change_handler"]];
group_ecmp_route -> lflow
[[label="lflow_group_ecmp_route_change_handler"]];
global_config -> lflow [[label="node_global_config_handler"]];
sampling_app -> lflow [[label=""]];
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index fd049d096..305d6d160 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -4153,7 +4153,7 @@ check ovn-nbctl --bfd=$uuid lr-route-add r0 100.0.0.0/8
192.168.1.2
wait_column down bfd status logical_port=r0-sw1
AT_CHECK([ovn-nbctl lr-route-list r0 | grep 192.168.1.2 | grep -q bfd], [0],
[], [ignore])
-check_engine_stats northd recompute nocompute
+check_engine_stats northd recompute incremental
check_engine_stats bfd recompute nocompute
check_engine_stats routes recompute nocompute
check_engine_stats lflow recompute nocompute
@@ -4169,7 +4169,7 @@ check ovn-nbctl --bfd lr-route-add r0 240.0.0.0/8
192.168.5.2 r0-sw5
wait_column down bfd status logical_port=r0-sw5
AT_CHECK([ovn-nbctl lr-route-list r0 | grep 192.168.5.2 | grep -q bfd], [0],
[], [ignore])
-check_engine_stats northd recompute nocompute
+check_engine_stats northd recompute incremental
check_engine_stats bfd recompute nocompute
check_engine_stats routes recompute nocompute
check_engine_stats lflow recompute nocompute
@@ -4181,7 +4181,7 @@ check ovn-nbctl --bfd --policy=src-ip lr-route-add r0
192.168.6.1/32 192.168.10.
wait_column down bfd status logical_port=r0-sw6
AT_CHECK([ovn-nbctl lr-route-list r0 | grep 192.168.6.1 | grep -q bfd], [0],
[], [ignore])
-check_engine_stats northd recompute nocompute
+check_engine_stats northd recompute incremental
check_engine_stats bfd recompute nocompute
check_engine_stats route_policies recompute nocompute
check_engine_stats lflow recompute nocompute
@@ -4216,7 +4216,7 @@ wait_column down bfd status logical_port=r0-sw8
bfd_route_policy_uuid=$(fetch_column nb:bfd _uuid logical_port=r0-sw8)
AT_CHECK([ovn-nbctl list logical_router_policy | grep -q
$bfd_route_policy_uuid])
-check_engine_stats northd recompute nocompute
+check_engine_stats northd recompute incremental
check_engine_stats bfd recompute nocompute
check_engine_stats routes recompute nocompute
check_engine_stats lflow recompute nocompute
@@ -16150,12 +16150,12 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
check ovn-nbctl --wait=sb lr-route-add lr0 192.168.0.0/24 10.0.0.10
-check_engine_compute northd recompute
-check_engine_compute routes recompute
+check_engine_compute northd incremental
+check_engine_compute routes incremental
check_engine_compute advertised_route_sync recompute
-check_engine_compute learned_route_sync recompute
-check_engine_compute group_ecmp_route recompute
-check_engine_compute lflow recompute
+check_engine_compute learned_route_sync incremental
+check_engine_compute group_ecmp_route incremental
+check_engine_compute lflow incremental
CHECK_NO_CHANGE_AFTER_RECOMPUTE
check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
--
2.43.0
--
_'Esta mensagem é direcionada apenas para os endereços constantes no
cabeçalho inicial. Se você não está listado nos endereços constantes no
cabeçalho, pedimos-lhe que desconsidere completamente o conteúdo dessa
mensagem e cuja cópia, encaminhamento e/ou execução das ações citadas estão
imediatamente anuladas e proibidas'._
* **'Apesar do Magazine Luiza tomar
todas as precauções razoáveis para assegurar que nenhum vírus esteja
presente nesse e-mail, a empresa não poderá aceitar a responsabilidade por
quaisquer perdas ou danos causados por esse e-mail ou por seus anexos'.*
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev