[ovs-dev] [PATCH ovn v4 1/5] controller: Move 'struct local_datapath' to a separate file.
Numan Siddique
numans at ovn.org
Mon Aug 2 23:03:54 UTC 2021
On Mon, Aug 2, 2021 at 5:20 PM Han Zhou <hzhou at ovn.org> wrote:
>
> On Mon, Aug 2, 2021 at 1:49 PM <numans at ovn.org> wrote:
> >
> > From: Numan Siddique <numans at ovn.org>
> >
> > This would uncomplicate the binding.c code a bit. The tracking
> > data and the related functions are also moved to the file - local_data.c.
> > This would help in an upcoming patch.
> >
> > Signed-off-by: Numan Siddique <numans at ovn.org>
> > ---
> > controller/automake.mk | 4 +-
> > controller/binding.c | 386 ++++--------------------------------
> > controller/binding.h | 13 --
> > controller/lflow.c | 1 +
> > controller/local_data.c | 357 +++++++++++++++++++++++++++++++++
> > controller/local_data.h | 111 +++++++++++
> > controller/lport.c | 40 ++++
> > controller/lport.h | 7 +-
> > controller/ovn-controller.c | 56 ++----
> > controller/ovn-controller.h | 30 ---
> > controller/patch.c | 1 +
> > controller/physical.c | 1 +
> > controller/pinctrl.c | 1 +
> > 13 files changed, 581 insertions(+), 427 deletions(-)
> > create mode 100644 controller/local_data.c
> > create mode 100644 controller/local_data.h
> >
> > diff --git a/controller/automake.mk b/controller/automake.mk
> > index 2f6c50890..41f907d6e 100644
> > --- a/controller/automake.mk
> > +++ b/controller/automake.mk
> > @@ -33,7 +33,9 @@ controller_ovn_controller_SOURCES = \
> > controller/physical.c \
> > controller/physical.h \
> > controller/mac-learn.c \
> > - controller/mac-learn.h
> > + controller/mac-learn.h \
> > + controller/local_data.c \
> > + controller/local_data.h
> >
> > controller_ovn_controller_LDADD = lib/libovn.la $(OVS_LIBDIR)/
> libopenvswitch.la
> > man_MANS += controller/ovn-controller.8
> > diff --git a/controller/binding.c b/controller/binding.c
> > index ad89739ee..96dc906f9 100644
> > --- a/controller/binding.c
> > +++ b/controller/binding.c
> > @@ -14,13 +14,8 @@
> > */
> >
> > #include <config.h>
> > -#include "binding.h"
> > -#include "ha-chassis.h"
> > -#include "if-status.h"
> > -#include "lflow.h"
> > -#include "lport.h"
> > -#include "patch.h"
> >
> > +/* OVS includes. */
> > #include "lib/bitmap.h"
> > #include "openvswitch/poll-loop.h"
> > #include "lib/sset.h"
> > @@ -29,9 +24,18 @@
> > #include "lib/vswitch-idl.h"
> > #include "openvswitch/hmap.h"
> > #include "openvswitch/vlog.h"
> > +
> > +/* OVN includes. */
> > +#include "binding.h"
> > +#include "ha-chassis.h"
> > +#include "if-status.h"
> > +#include "lflow.h"
> > #include "lib/chassis-index.h"
> > #include "lib/ovn-sb-idl.h"
> > +#include "local_data.h"
> > +#include "lport.h"
> > #include "ovn-controller.h"
> > +#include "patch.h"
> >
> > VLOG_DEFINE_THIS_MODULE(binding);
> >
> > @@ -76,117 +80,9 @@ binding_register_ovs_idl(struct ovsdb_idl *ovs_idl)
> > ovsdb_idl_add_column(ovs_idl, &ovsrec_qos_col_type);
> > }
> >
> > -static struct tracked_binding_datapath *tracked_binding_datapath_create(
> > - const struct sbrec_datapath_binding *,
> > - bool is_new, struct hmap *tracked_dps);
> > -static struct tracked_binding_datapath *tracked_binding_datapath_find(
> > - struct hmap *, const struct sbrec_datapath_binding *);
> > -static void tracked_binding_datapath_lport_add(
> > - const struct sbrec_port_binding *, struct hmap *tracked_datapaths);
> > static void update_lport_tracking(const struct sbrec_port_binding *pb,
> > - struct hmap *tracked_dp_bindings);
> > -
> > -static void
> > -add_local_datapath__(struct ovsdb_idl_index
> *sbrec_datapath_binding_by_key,
> > - struct ovsdb_idl_index
> *sbrec_port_binding_by_datapath,
> > - struct ovsdb_idl_index *sbrec_port_binding_by_name,
> > - const struct sbrec_datapath_binding *datapath,
> > - int depth, struct hmap *local_datapaths,
> > - struct hmap *tracked_datapaths)
> > -{
> > - uint32_t dp_key = datapath->tunnel_key;
> > - struct local_datapath *ld = get_local_datapath(local_datapaths,
> dp_key);
> > - if (ld) {
> > - return;
> > - }
> > -
> > - ld = xzalloc(sizeof *ld);
> > - hmap_insert(local_datapaths, &ld->hmap_node, dp_key);
> > - ld->datapath = datapath;
> > - ld->localnet_port = NULL;
> > - shash_init(&ld->external_ports);
> > -
> > - if (tracked_datapaths) {
> > - struct tracked_binding_datapath *tdp =
> > - tracked_binding_datapath_find(tracked_datapaths, datapath);
> > - if (!tdp) {
> > - tracked_binding_datapath_create(datapath, true,
> tracked_datapaths);
> > - } else {
> > - /* Its possible that there is already an entry in tracked
> datapaths
> > - * for this 'datapath'. tracked_binding_datapath_lport_add()
> may
> > - * have created it. Since the 'datapath' is added to the
> > - * local datapaths, set 'tdp->is_new' to true so that the
> flows
> > - * for this datapath are programmed properly.
> > - * */
> > - tdp->is_new = true;
> > - }
> > - }
> > -
> > - if (depth >= 100) {
> > - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
> > - VLOG_WARN_RL(&rl, "datapaths nested too deep");
> > - return;
> > - }
> > -
> > - struct sbrec_port_binding *target =
> > -
> sbrec_port_binding_index_init_row(sbrec_port_binding_by_datapath);
> > - sbrec_port_binding_index_set_datapath(target, datapath);
> > -
> > - const struct sbrec_port_binding *pb;
> > - SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target,
> > - sbrec_port_binding_by_datapath) {
> > - if (!strcmp(pb->type, "patch") || !strcmp(pb->type,
> "l3gateway")) {
> > - const char *peer_name = smap_get(&pb->options, "peer");
> > - if (peer_name) {
> > - const struct sbrec_port_binding *peer;
> > -
> > - peer = lport_lookup_by_name(sbrec_port_binding_by_name,
> > - peer_name);
> > -
> > - if (peer && peer->datapath) {
> > - if (!strcmp(pb->type, "patch")) {
> > - /* Add the datapath to local datapath only for
> patch
> > - * ports. For l3gateway ports, since gateway
> router
> > - * resides on one chassis, we don't need to add.
> > - * Otherwise, all other chassis might create
> patch
> > - * ports between br-int and the provider bridge.
> */
> > -
> add_local_datapath__(sbrec_datapath_binding_by_key,
> > -
> sbrec_port_binding_by_datapath,
> > - sbrec_port_binding_by_name,
> > - peer->datapath,
> > - depth + 1, local_datapaths,
> > - tracked_datapaths);
> > - }
> > - ld->n_peer_ports++;
> > - if (ld->n_peer_ports > ld->n_allocated_peer_ports) {
> > - ld->peer_ports =
> > - x2nrealloc(ld->peer_ports,
> > - &ld->n_allocated_peer_ports,
> > - sizeof *ld->peer_ports);
> > - }
> > - ld->peer_ports[ld->n_peer_ports - 1].local = pb;
> > - ld->peer_ports[ld->n_peer_ports - 1].remote = peer;
> > - }
> > - }
> > - }
> > - }
> > - sbrec_port_binding_index_destroy_row(target);
> > -}
> > -
> > -static void
> > -add_local_datapath(struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
> > - struct ovsdb_idl_index
> *sbrec_port_binding_by_datapath,
> > - struct ovsdb_idl_index *sbrec_port_binding_by_name,
> > - const struct sbrec_datapath_binding *datapath,
> > - struct hmap *local_datapaths,
> > - struct hmap *tracked_datapaths)
> > -{
> > - add_local_datapath__(sbrec_datapath_binding_by_key,
> > - sbrec_port_binding_by_datapath,
> > - sbrec_port_binding_by_name,
> > - datapath, 0, local_datapaths,
> > - tracked_datapaths);
> > -}
> > + struct hmap *tracked_dp_bindings,
> > + bool claimed);
> >
> > static void
> > get_qos_params(const struct sbrec_port_binding *pb, struct hmap
> *queue_map)
> > @@ -554,7 +450,8 @@ update_related_lport(const struct sbrec_port_binding
> *pb,
> >
> > if (b_ctx->tracked_dp_bindings) {
> > /* Add the 'pb' to the tracked_datapaths. */
> > - tracked_binding_datapath_lport_add(pb,
> b_ctx->tracked_dp_bindings);
> > + tracked_datapath_lport_add(pb, TRACKED_RESOURCE_NEW,
> > + b_ctx->tracked_dp_bindings);
> > }
> > }
> > sset_add(&b_ctx->related_lports->lport_names, pb->logical_port);
> > @@ -577,7 +474,8 @@ remove_related_lport(const struct sbrec_port_binding
> *pb,
> >
> > if (b_ctx->tracked_dp_bindings) {
> > /* Add the 'pb' to the tracked_datapaths. */
> > - tracked_binding_datapath_lport_add(pb,
> b_ctx->tracked_dp_bindings);
> > + tracked_datapath_lport_add(pb, TRACKED_RESOURCE_REMOVED,
> > + b_ctx->tracked_dp_bindings);
> > }
> > }
> > }
> > @@ -927,74 +825,6 @@ is_lport_vif(const struct sbrec_port_binding *pb)
> > return !pb->type[0];
> > }
> >
> > -static struct tracked_binding_datapath *
> > -tracked_binding_datapath_create(const struct sbrec_datapath_binding *dp,
> > - bool is_new,
> > - struct hmap *tracked_datapaths)
> > -{
> > - struct tracked_binding_datapath *t_dp = xzalloc(sizeof *t_dp);
> > - t_dp->dp = dp;
> > - t_dp->is_new = is_new;
> > - shash_init(&t_dp->lports);
> > - hmap_insert(tracked_datapaths, &t_dp->node,
> uuid_hash(&dp->header_.uuid));
> > - return t_dp;
> > -}
> > -
> > -static struct tracked_binding_datapath *
> > -tracked_binding_datapath_find(struct hmap *tracked_datapaths,
> > - const struct sbrec_datapath_binding *dp)
> > -{
> > - struct tracked_binding_datapath *t_dp;
> > - size_t hash = uuid_hash(&dp->header_.uuid);
> > - HMAP_FOR_EACH_WITH_HASH (t_dp, node, hash, tracked_datapaths) {
> > - if (uuid_equals(&t_dp->dp->header_.uuid, &dp->header_.uuid)) {
> > - return t_dp;
> > - }
> > - }
> > -
> > - return NULL;
> > -}
> > -
> > -static void
> > -tracked_binding_datapath_lport_add(const struct sbrec_port_binding *pb,
> > - struct hmap *tracked_datapaths)
> > -{
> > - if (!tracked_datapaths) {
> > - return;
> > - }
> > -
> > - struct tracked_binding_datapath *tracked_dp =
> > - tracked_binding_datapath_find(tracked_datapaths, pb->datapath);
> > - if (!tracked_dp) {
> > - tracked_dp = tracked_binding_datapath_create(pb->datapath, false,
> > - tracked_datapaths);
> > - }
> > -
> > - /* Check if the lport is already present or not.
> > - * If it is already present, then just update the 'pb' field. */
> > - struct tracked_binding_lport *lport =
> > - shash_find_data(&tracked_dp->lports, pb->logical_port);
> > -
> > - if (!lport) {
> > - lport = xmalloc(sizeof *lport);
> > - shash_add(&tracked_dp->lports, pb->logical_port, lport);
> > - }
> > -
> > - lport->pb = pb;
> > -}
> > -
> > -void
> > -binding_tracked_dp_destroy(struct hmap *tracked_datapaths)
> > -{
> > - struct tracked_binding_datapath *t_dp;
> > - HMAP_FOR_EACH_POP (t_dp, node, tracked_datapaths) {
> > - shash_destroy_free_data(&t_dp->lports);
> > - free(t_dp);
> > - }
> > -
> > - hmap_destroy(tracked_datapaths);
> > -}
> > -
> > static enum en_lport_type
> > get_lport_type(const struct sbrec_port_binding *pb)
> > {
> > @@ -1129,7 +959,7 @@ claim_lport(const struct sbrec_port_binding *pb,
> > sbrec_port_binding_set_chassis(pb, chassis_rec);
> >
> > if (tracked_datapaths) {
> > - update_lport_tracking(pb, tracked_datapaths);
> > + update_lport_tracking(pb, tracked_datapaths, true);
> > }
> > }
> >
> > @@ -1178,7 +1008,7 @@ release_lport(const struct sbrec_port_binding *pb,
> bool sb_readonly,
> > sbrec_port_binding_set_virtual_parent(pb, NULL);
> > }
> >
> > - update_lport_tracking(pb, tracked_datapaths);
> > + update_lport_tracking(pb, tracked_datapaths, false);
> > if_status_mgr_release_iface(if_mgr, pb->logical_port);
> > VLOG_INFO("Releasing lport %s from this chassis.", pb->logical_port);
> > return true;
> > @@ -1264,11 +1094,10 @@ consider_vif_lport_(const struct
> sbrec_port_binding *pb,
> > return false;
> > }
> >
> > - add_local_datapath(b_ctx_in->sbrec_datapath_binding_by_key,
> > + local_datapath_add(b_ctx_out->local_datapaths, pb->datapath,
> > + b_ctx_in->sbrec_datapath_binding_by_key,
> > b_ctx_in->sbrec_port_binding_by_datapath,
> > b_ctx_in->sbrec_port_binding_by_name,
> > - pb->datapath,
> > - b_ctx_out->local_datapaths,
> > b_ctx_out->tracked_dp_bindings);
> > update_related_lport(pb, b_ctx_out);
> > update_local_lports(pb->logical_port, b_ctx_out);
> > @@ -1478,11 +1307,10 @@ consider_nonvif_lport_(const struct
> sbrec_port_binding *pb,
> > {
> > if (our_chassis) {
> > update_local_lports(pb->logical_port, b_ctx_out);
> > - add_local_datapath(b_ctx_in->sbrec_datapath_binding_by_key,
> > + local_datapath_add(b_ctx_out->local_datapaths, pb->datapath,
> > + b_ctx_in->sbrec_datapath_binding_by_key,
> > b_ctx_in->sbrec_port_binding_by_datapath,
> > b_ctx_in->sbrec_port_binding_by_name,
> > - pb->datapath,
> > - b_ctx_out->local_datapaths,
> > b_ctx_out->tracked_dp_bindings);
>
> nit: It would be better to keep the original order of the parameters with
> input arguments in front of the output arguments. Also better to keep the
> original functions names to avoid unnecessary code changes at several
> similar places. (This is trivial and can be updated before applying without
> another version)
>
> Acked-by: Han Zhou <hzhou at ovn.org>
Thanks Han (and Mark M) for the reviews.
I applied the series to the main branch with your suggested changes on the
parameters and the function names.
Below are the changes I did on top of the p1.
**********************************************************
diff --git a/controller/binding.c b/controller/binding.c
index 96dc906f9..1ba784d52 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -1094,10 +1094,11 @@ consider_vif_lport_(const struct sbrec_port_binding *pb,
return false;
}
- local_datapath_add(b_ctx_out->local_datapaths, pb->datapath,
- b_ctx_in->sbrec_datapath_binding_by_key,
+ add_local_datapath(b_ctx_in->sbrec_datapath_binding_by_key,
b_ctx_in->sbrec_port_binding_by_datapath,
b_ctx_in->sbrec_port_binding_by_name,
+ pb->datapath,
+ b_ctx_out->local_datapaths,
b_ctx_out->tracked_dp_bindings);
update_related_lport(pb, b_ctx_out);
update_local_lports(pb->logical_port, b_ctx_out);
@@ -1307,10 +1308,11 @@ consider_nonvif_lport_(const struct
sbrec_port_binding *pb,
{
if (our_chassis) {
update_local_lports(pb->logical_port, b_ctx_out);
- local_datapath_add(b_ctx_out->local_datapaths, pb->datapath,
- b_ctx_in->sbrec_datapath_binding_by_key,
+ add_local_datapath(b_ctx_in->sbrec_datapath_binding_by_key,
b_ctx_in->sbrec_port_binding_by_datapath,
b_ctx_in->sbrec_port_binding_by_name,
+ pb->datapath,
+ b_ctx_out->local_datapaths,
b_ctx_out->tracked_dp_bindings);
update_related_lport(pb, b_ctx_out);
@@ -1389,10 +1391,11 @@ consider_ha_lport(const struct sbrec_port_binding *pb,
* If the chassis is active, consider_nonvif_lport_() takes care
* of adding the datapath of this 'pb' to local datapaths.
* */
- local_datapath_add(b_ctx_out->local_datapaths, pb->datapath,
- b_ctx_in->sbrec_datapath_binding_by_key,
+ add_local_datapath(b_ctx_in->sbrec_datapath_binding_by_key,
b_ctx_in->sbrec_port_binding_by_datapath,
b_ctx_in->sbrec_port_binding_by_name,
+ pb->datapath,
+ b_ctx_out->local_datapaths,
b_ctx_out->tracked_dp_bindings);
update_related_lport(pb, b_ctx_out);
}
@@ -1662,7 +1665,7 @@ remove_pb_from_local_datapath(const struct
sbrec_port_binding *pb,
remove_related_lport(pb, b_ctx_out);
if (!strcmp(pb->type, "patch") ||
!strcmp(pb->type, "l3gateway")) {
- local_datapath_remove_peer_port(pb, ld, b_ctx_out->local_datapaths);
+ remove_local_datapath_peer_port(pb, ld, b_ctx_out->local_datapaths);
} else if (!strcmp(pb->type, "localnet")) {
if (ld->localnet_port && !strcmp(ld->localnet_port->logical_port,
pb->logical_port)) {
@@ -2290,11 +2293,12 @@ delete_done:
peer->datapath->tunnel_key);
}
if (peer_ld) {
- local_datapath_add(
- b_ctx_out->local_datapaths, pb->datapath,
+ add_local_datapath(
b_ctx_in->sbrec_datapath_binding_by_key,
b_ctx_in->sbrec_port_binding_by_datapath,
b_ctx_in->sbrec_port_binding_by_name,
+ pb->datapath,
+ b_ctx_out->local_datapaths,
b_ctx_out->tracked_dp_bindings);
}
@@ -2306,7 +2310,7 @@ delete_done:
* not present yet.
*/
if (ld) {
- local_datapath_add_peer_port(
+ add_local_datapath_peer_port(
pb, b_ctx_in->sbrec_datapath_binding_by_key,
b_ctx_in->sbrec_port_binding_by_datapath,
b_ctx_in->sbrec_port_binding_by_name,
diff --git a/controller/local_data.c b/controller/local_data.c
index c6dfd0be4..2eab3d40a 100644
--- a/controller/local_data.c
+++ b/controller/local_data.c
@@ -29,14 +29,12 @@
VLOG_DEFINE_THIS_MODULE(ldata);
-static struct local_datapath *local_datapath_add__(
- struct hmap *local_datapaths,
- const struct sbrec_datapath_binding *,
+static void add_local_datapath__(
struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
- int depth,
- struct hmap *tracked_datapaths);
+ int depth, const struct sbrec_datapath_binding *,
+ struct hmap *local_datapaths, struct hmap *tracked_datapaths);
static struct tracked_datapath *tracked_datapath_create(
const struct sbrec_datapath_binding *dp,
@@ -81,23 +79,23 @@ local_datapath_destroy(struct local_datapath *ld)
free(ld);
}
-struct local_datapath *
-local_datapath_add(struct hmap *local_datapaths,
- const struct sbrec_datapath_binding *dp,
- struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+void
+add_local_datapath(struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
+ const struct sbrec_datapath_binding *dp,
+ struct hmap *local_datapaths,
struct hmap *tracked_datapaths)
{
- return local_datapath_add__(local_datapaths, dp,
- sbrec_datapath_binding_by_key,
- sbrec_port_binding_by_datapath,
- sbrec_port_binding_by_name, 0,
- tracked_datapaths);
+ add_local_datapath__(sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name, 0,
+ dp, local_datapaths,
+ tracked_datapaths);
}
void
-local_datapath_add_peer_port(
+add_local_datapath_peer_port(
const struct sbrec_port_binding *pb,
struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
@@ -137,10 +135,10 @@ local_datapath_add_peer_port(
get_local_datapath(local_datapaths,
peer->datapath->tunnel_key);
if (!peer_ld) {
- local_datapath_add__(local_datapaths, peer->datapath,
- sbrec_datapath_binding_by_key,
+ add_local_datapath__(sbrec_datapath_binding_by_key,
sbrec_port_binding_by_datapath,
sbrec_port_binding_by_name, 1,
+ peer->datapath, local_datapaths,
tracked_datapaths);
return;
}
@@ -163,7 +161,7 @@ local_datapath_add_peer_port(
}
void
-local_datapath_remove_peer_port(const struct sbrec_port_binding *pb,
+remove_local_datapath_peer_port(const struct sbrec_port_binding *pb,
struct local_datapath *ld,
struct hmap *local_datapaths)
{
@@ -193,7 +191,7 @@ local_datapath_remove_peer_port(const struct
sbrec_port_binding *pb,
/* Remove the peer port from the peer datapath. The peer
* datapath also tries to remove its peer lport, but that would
* be no-op. */
- local_datapath_remove_peer_port(peer, peer_ld, local_datapaths);
+ remove_local_datapath_peer_port(peer, peer_ld, local_datapaths);
}
}
@@ -269,18 +267,18 @@ tracked_datapaths_destroy(struct hmap *tracked_datapaths)
}
/* static functions. */
-static struct local_datapath *
-local_datapath_add__(struct hmap *local_datapaths,
- const struct sbrec_datapath_binding *dp,
- struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+static void
+add_local_datapath__(struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
- int depth, struct hmap *tracked_datapaths)
+ int depth, const struct sbrec_datapath_binding *dp,
+ struct hmap *local_datapaths,
+ struct hmap *tracked_datapaths)
{
uint32_t dp_key = dp->tunnel_key;
struct local_datapath *ld = get_local_datapath(local_datapaths, dp_key);
if (ld) {
- return ld;
+ return;
}
ld = local_datapath_alloc(dp);
@@ -295,7 +293,7 @@ local_datapath_add__(struct hmap *local_datapaths,
if (depth >= 100) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
VLOG_WARN_RL(&rl, "datapaths nested too deep");
- return ld;
+ return;
}
struct sbrec_port_binding *target =
@@ -320,11 +318,11 @@ local_datapath_add__(struct hmap *local_datapaths,
* resides on one chassis, we don't need to add.
* Otherwise, all other chassis might create patch
* ports between br-int and the provider bridge. */
- local_datapath_add__(local_datapaths, peer->datapath,
- sbrec_datapath_binding_by_key,
+ add_local_datapath__(sbrec_datapath_binding_by_key,
sbrec_port_binding_by_datapath,
sbrec_port_binding_by_name,
- depth + 1, tracked_datapaths);
+ depth + 1, peer->datapath,
+ local_datapaths,
tracked_datapaths);
}
ld->n_peer_ports++;
if (ld->n_peer_ports > ld->n_allocated_peer_ports) {
@@ -340,7 +338,6 @@ local_datapath_add__(struct hmap *local_datapaths,
}
}
sbrec_port_binding_index_destroy_row(target);
- return ld;
}
static struct tracked_datapath *
diff --git a/controller/local_data.h b/controller/local_data.h
index 8b80110fe..f9103c397 100644
--- a/controller/local_data.h
+++ b/controller/local_data.h
@@ -56,16 +56,17 @@ struct local_datapath *local_datapath_alloc(
const struct sbrec_datapath_binding *);
struct local_datapath *get_local_datapath(const struct hmap *,
uint32_t tunnel_key);
-struct local_datapath * local_datapath_add(
- struct hmap *local_datapaths, const struct sbrec_datapath_binding *,
+void add_local_datapath(
struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
+ const struct sbrec_datapath_binding *datapath,
+ struct hmap *local_datapaths,
struct hmap *tracked_datapaths);
void local_datapaths_destroy(struct hmap *local_datapaths);
void local_datapath_destroy(struct local_datapath *ld);
-void local_datapath_add_peer_port(
+void add_local_datapath_peer_port(
const struct sbrec_port_binding *pb,
struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
@@ -74,7 +75,7 @@ void local_datapath_add_peer_port(
struct hmap *local_datapaths,
struct hmap *tracked_datapaths);
-void local_datapath_remove_peer_port(const struct sbrec_port_binding *pb,
+void remove_local_datapath_peer_port(const struct sbrec_port_binding *pb,
struct local_datapath *ld,
struct hmap *local_datapaths);
********************************************************************************
Numan
>
> >
> > update_related_lport(pb, b_ctx_out);
> > @@ -1561,11 +1389,10 @@ consider_ha_lport(const struct sbrec_port_binding
> *pb,
> > * If the chassis is active, consider_nonvif_lport_() takes care
> > * of adding the datapath of this 'pb' to local datapaths.
> > * */
> > - add_local_datapath(b_ctx_in->sbrec_datapath_binding_by_key,
> > + local_datapath_add(b_ctx_out->local_datapaths, pb->datapath,
> > + b_ctx_in->sbrec_datapath_binding_by_key,
> > b_ctx_in->sbrec_port_binding_by_datapath,
> > b_ctx_in->sbrec_port_binding_by_name,
> > - pb->datapath,
> > - b_ctx_out->local_datapaths,
> > b_ctx_out->tracked_dp_bindings);
> > update_related_lport(pb, b_ctx_out);
> > }
> > @@ -1827,143 +1654,6 @@ binding_cleanup(struct ovsdb_idl_txn
> *ovnsb_idl_txn,
> > return !any_changes;
> > }
> >
> > -static const struct sbrec_port_binding *
> > -get_peer_lport__(const struct sbrec_port_binding *pb,
> > - struct binding_ctx_in *b_ctx_in)
> > -{
> > - const char *peer_name = smap_get(&pb->options, "peer");
> > -
> > - if (!peer_name) {
> > - return NULL;
> > - }
> > -
> > - const struct sbrec_port_binding *peer;
> > - peer = lport_lookup_by_name(b_ctx_in->sbrec_port_binding_by_name,
> > - peer_name);
> > - return (peer && peer->datapath) ? peer : NULL;
> > -}
> > -
> > -static const struct sbrec_port_binding *
> > -get_l3gw_peer_lport(const struct sbrec_port_binding *pb,
> > - struct binding_ctx_in *b_ctx_in)
> > -{
> > - if (strcmp(pb->type, "l3gateway")) {
> > - return NULL;
> > - }
> > - return get_peer_lport__(pb, b_ctx_in);
> > -}
> > -
> > -static const struct sbrec_port_binding *
> > -get_peer_lport(const struct sbrec_port_binding *pb,
> > - struct binding_ctx_in *b_ctx_in)
> > -{
> > - if (strcmp(pb->type, "patch")) {
> > - return NULL;
> > - }
> > - return get_peer_lport__(pb, b_ctx_in);
> > -}
> > -
> > -/* This function adds the local datapath of the 'peer' of
> > - * lport 'pb' to the local datapaths if it is not yet added.
> > - */
> > -static void
> > -add_local_datapath_peer_port(const struct sbrec_port_binding *pb,
> > - struct binding_ctx_in *b_ctx_in,
> > - struct binding_ctx_out *b_ctx_out,
> > - struct local_datapath *ld)
> > -{
> > - const struct sbrec_port_binding *peer;
> > - peer = get_peer_lport(pb, b_ctx_in);
> > -
> > - if (!peer) {
> > - return;
> > - }
> > -
> > - bool present = false;
> > - for (size_t i = 0; i < ld->n_peer_ports; i++) {
> > - if (ld->peer_ports[i].local == pb) {
> > - present = true;
> > - break;
> > - }
> > - }
> > -
> > - if (!present) {
> > - ld->n_peer_ports++;
> > - if (ld->n_peer_ports > ld->n_allocated_peer_ports) {
> > - ld->peer_ports =
> > - x2nrealloc(ld->peer_ports,
> > - &ld->n_allocated_peer_ports,
> > - sizeof *ld->peer_ports);
> > - }
> > - ld->peer_ports[ld->n_peer_ports - 1].local = pb;
> > - ld->peer_ports[ld->n_peer_ports - 1].remote = peer;
> > - }
> > -
> > - struct local_datapath *peer_ld =
> > - get_local_datapath(b_ctx_out->local_datapaths,
> > - peer->datapath->tunnel_key);
> > - if (!peer_ld) {
> > - add_local_datapath__(b_ctx_in->sbrec_datapath_binding_by_key,
> > - b_ctx_in->sbrec_port_binding_by_datapath,
> > - b_ctx_in->sbrec_port_binding_by_name,
> > - peer->datapath,
> > - 1, b_ctx_out->local_datapaths,
> > - b_ctx_out->tracked_dp_bindings);
> > - return;
> > - }
> > -
> > - for (size_t i = 0; i < peer_ld->n_peer_ports; i++) {
> > - if (peer_ld->peer_ports[i].local == peer) {
> > - return;
> > - }
> > - }
> > -
> > - peer_ld->n_peer_ports++;
> > - if (peer_ld->n_peer_ports > peer_ld->n_allocated_peer_ports) {
> > - peer_ld->peer_ports =
> > - x2nrealloc(peer_ld->peer_ports,
> > - &peer_ld->n_allocated_peer_ports,
> > - sizeof *peer_ld->peer_ports);
> > - }
> > - peer_ld->peer_ports[peer_ld->n_peer_ports - 1].local = peer;
> > - peer_ld->peer_ports[peer_ld->n_peer_ports - 1].remote = pb;
> > -}
> > -
> > -static void
> > -remove_local_datapath_peer_port(const struct sbrec_port_binding *pb,
> > - struct local_datapath *ld,
> > - struct hmap *local_datapaths)
> > -{
> > - size_t i = 0;
> > - for (i = 0; i < ld->n_peer_ports; i++) {
> > - if (ld->peer_ports[i].local == pb) {
> > - break;
> > - }
> > - }
> > -
> > - if (i == ld->n_peer_ports) {
> > - return;
> > - }
> > -
> > - const struct sbrec_port_binding *peer = ld->peer_ports[i].remote;
> > -
> > - /* Possible improvement: We can shrink the allocated peer ports
> > - * if (ld->n_peer_ports < ld->n_allocated_peer_ports / 2).
> > - */
> > - ld->peer_ports[i].local = ld->peer_ports[ld->n_peer_ports - 1].local;
> > - ld->peer_ports[i].remote = ld->peer_ports[ld->n_peer_ports -
> 1].remote;
> > - ld->n_peer_ports--;
> > -
> > - struct local_datapath *peer_ld =
> > - get_local_datapath(local_datapaths, peer->datapath->tunnel_key);
> > - if (peer_ld) {
> > - /* Remove the peer port from the peer datapath. The peer
> > - * datapath also tries to remove its peer lport, but that would
> > - * be no-op. */
> > - remove_local_datapath_peer_port(peer, peer_ld, local_datapaths);
> > - }
> > -}
> > -
> > static void
> > remove_pb_from_local_datapath(const struct sbrec_port_binding *pb,
> > struct binding_ctx_out *b_ctx_out,
> > @@ -1972,7 +1662,7 @@ remove_pb_from_local_datapath(const struct
> sbrec_port_binding *pb,
> > remove_related_lport(pb, b_ctx_out);
> > if (!strcmp(pb->type, "patch") ||
> > !strcmp(pb->type, "l3gateway")) {
> > - remove_local_datapath_peer_port(pb, ld,
> b_ctx_out->local_datapaths);
> > + local_datapath_remove_peer_port(pb, ld,
> b_ctx_out->local_datapaths);
> > } else if (!strcmp(pb->type, "localnet")) {
> > if (ld->localnet_port && !strcmp(ld->localnet_port->logical_port,
> > pb->logical_port)) {
> > @@ -1985,13 +1675,16 @@ remove_pb_from_local_datapath(const struct
> sbrec_port_binding *pb,
> >
> > static void
> > update_lport_tracking(const struct sbrec_port_binding *pb,
> > - struct hmap *tracked_dp_bindings)
> > + struct hmap *tracked_dp_bindings,
> > + bool claimed)
> > {
> > if (!tracked_dp_bindings) {
> > return;
> > }
> >
> > - tracked_binding_datapath_lport_add(pb, tracked_dp_bindings);
> > + tracked_datapath_lport_add(
> > + pb, claimed ? TRACKED_RESOURCE_NEW : TRACKED_RESOURCE_REMOVED,
> > + tracked_dp_bindings);
> > }
> >
> > /* Considers the ovs iface 'iface_rec' for claiming.
> > @@ -2304,7 +1997,7 @@ handle_deleted_lport(const struct
> sbrec_port_binding *pb,
> > /* If the binding is not local, if 'pb' is a L3 gateway port, we
> should
> > * remove its peer, if that one is local.
> > */
> > - pb = get_l3gw_peer_lport(pb, b_ctx_in);
> > + pb = lport_get_l3gw_peer(pb, b_ctx_in->sbrec_port_binding_by_name);
> > if (pb) {
> > ld = get_local_datapath(b_ctx_out->local_datapaths,
> > pb->datapath->tunnel_key);
> > @@ -2587,19 +2280,21 @@ delete_done:
> > * */
> > const struct sbrec_port_binding *peer;
> > struct local_datapath *peer_ld = NULL;
> > - peer = get_peer_lport(pb, b_ctx_in);
> > + peer =
> > + lport_get_peer(pb,
> > +
> b_ctx_in->sbrec_port_binding_by_name);
> > +
> > if (peer) {
> > peer_ld =
> >
> get_local_datapath(b_ctx_out->local_datapaths,
> >
> peer->datapath->tunnel_key);
> > }
> > if (peer_ld) {
> > - add_local_datapath(
> > + local_datapath_add(
> > + b_ctx_out->local_datapaths, pb->datapath,
> > b_ctx_in->sbrec_datapath_binding_by_key,
> > b_ctx_in->sbrec_port_binding_by_datapath,
> > b_ctx_in->sbrec_port_binding_by_name,
> > - pb->datapath,
> > - b_ctx_out->local_datapaths,
> > b_ctx_out->tracked_dp_bindings);
> > }
> >
> > @@ -2611,7 +2306,12 @@ delete_done:
> > * not present yet.
> > */
> > if (ld) {
> > - add_local_datapath_peer_port(pb, b_ctx_in,
> b_ctx_out, ld);
> > + local_datapath_add_peer_port(
> > + pb, b_ctx_in->sbrec_datapath_binding_by_key,
> > + b_ctx_in->sbrec_port_binding_by_datapath,
> > + b_ctx_in->sbrec_port_binding_by_name,
> > + ld, b_ctx_out->local_datapaths,
> > + b_ctx_out->tracked_dp_bindings);
> > }
> > }
> >
> > diff --git a/controller/binding.h b/controller/binding.h
> > index 77197e742..b1717bd2b 100644
> > --- a/controller/binding.h
> > +++ b/controller/binding.h
> > @@ -121,19 +121,6 @@ void local_binding_set_up(struct shash
> *local_bindings, const char *pb_name,
> > void local_binding_set_down(struct shash *local_bindings, const char
> *pb_name,
> > bool sb_readonly, bool ovs_readonly);
> >
> > -/* Represents a tracked binding logical port. */
> > -struct tracked_binding_lport {
> > - const struct sbrec_port_binding *pb;
> > -};
> > -
> > -/* Represent a tracked binding datapath. */
> > -struct tracked_binding_datapath {
> > - struct hmap_node node;
> > - const struct sbrec_datapath_binding *dp;
> > - bool is_new;
> > - struct shash lports; /* shash of struct tracked_binding_lport. */
> > -};
> > -
> > void binding_register_ovs_idl(struct ovsdb_idl *);
> > void binding_run(struct binding_ctx_in *, struct binding_ctx_out *);
> > bool binding_cleanup(struct ovsdb_idl_txn *ovnsb_idl_txn,
> > diff --git a/controller/lflow.c b/controller/lflow.c
> > index 1eed1cccc..c1d55f378 100644
> > --- a/controller/lflow.c
> > +++ b/controller/lflow.c
> > @@ -18,6 +18,7 @@
> > #include "coverage.h"
> > #include "ha-chassis.h"
> > #include "lflow-cache.h"
> > +#include "local_data.h"
> > #include "lport.h"
> > #include "ofctrl.h"
> > #include "openvswitch/dynamic-string.h"
> > diff --git a/controller/local_data.c b/controller/local_data.c
> > new file mode 100644
> > index 000000000..c6dfd0be4
> > --- /dev/null
> > +++ b/controller/local_data.c
> > @@ -0,0 +1,357 @@
> > +/* Copyright (c) 2021, Red Hat, Inc.
> > + *
> > + * 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>
> > +
> > +/* OVS includes. */
> > +#include "include/openvswitch/json.h"
> > +#include "lib/hmapx.h"
> > +#include "lib/util.h"
> > +#include "openvswitch/vlog.h"
> > +
> > +/* OVN includes. */
> > +#include "lib/ovn-util.h"
> > +#include "lib/ovn-sb-idl.h"
> > +#include "local_data.h"
> > +#include "lport.h"
> > +
> > +VLOG_DEFINE_THIS_MODULE(ldata);
> > +
> > +static struct local_datapath *local_datapath_add__(
> > + struct hmap *local_datapaths,
> > + const struct sbrec_datapath_binding *,
> > + struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name,
> > + int depth,
> > + struct hmap *tracked_datapaths);
> > +
> > +static struct tracked_datapath *tracked_datapath_create(
> > + const struct sbrec_datapath_binding *dp,
> > + enum en_tracked_resource_type tracked_type,
> > + struct hmap *tracked_datapaths);
> > +
> > +struct local_datapath *
> > +get_local_datapath(const struct hmap *local_datapaths, uint32_t
> tunnel_key)
> > +{
> > + struct hmap_node *node = hmap_first_with_hash(local_datapaths,
> tunnel_key);
> > + return (node
> > + ? CONTAINER_OF(node, struct local_datapath, hmap_node)
> > + : NULL);
> > +}
> > +
> > +struct local_datapath *
> > +local_datapath_alloc(const struct sbrec_datapath_binding *dp)
> > +{
> > + struct local_datapath *ld = xzalloc(sizeof *ld);
> > + ld->datapath = dp;
> > + ld->is_switch = datapath_is_switch(dp);
> > + shash_init(&ld->external_ports);
> > + return ld;
> > +}
> > +
> > +void
> > +local_datapaths_destroy(struct hmap *local_datapaths)
> > +{
> > + struct local_datapath *ld;
> > + HMAP_FOR_EACH_POP (ld, hmap_node, local_datapaths) {
> > + local_datapath_destroy(ld);
> > + }
> > +
> > + hmap_destroy(local_datapaths);
> > +}
> > +
> > +void
> > +local_datapath_destroy(struct local_datapath *ld)
> > +{
> > + free(ld->peer_ports);
> > + shash_destroy(&ld->external_ports);
> > + free(ld);
> > +}
> > +
> > +struct local_datapath *
> > +local_datapath_add(struct hmap *local_datapaths,
> > + const struct sbrec_datapath_binding *dp,
> > + struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
> > + struct ovsdb_idl_index
> *sbrec_port_binding_by_datapath,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name,
> > + struct hmap *tracked_datapaths)
> > +{
> > + return local_datapath_add__(local_datapaths, dp,
> > + sbrec_datapath_binding_by_key,
> > + sbrec_port_binding_by_datapath,
> > + sbrec_port_binding_by_name, 0,
> > + tracked_datapaths);
> > +}
> > +
> > +void
> > +local_datapath_add_peer_port(
> > + const struct sbrec_port_binding *pb,
> > + struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name,
> > + struct local_datapath *ld,
> > + struct hmap *local_datapaths,
> > + struct hmap *tracked_datapaths)
> > +{
> > + const struct sbrec_port_binding *peer;
> > + peer = lport_get_peer(pb, sbrec_port_binding_by_name);
> > +
> > + if (!peer) {
> > + return;
> > + }
> > +
> > + bool present = false;
> > + for (size_t i = 0; i < ld->n_peer_ports; i++) {
> > + if (ld->peer_ports[i].local == pb) {
> > + present = true;
> > + break;
> > + }
> > + }
> > +
> > + if (!present) {
> > + ld->n_peer_ports++;
> > + if (ld->n_peer_ports > ld->n_allocated_peer_ports) {
> > + ld->peer_ports =
> > + x2nrealloc(ld->peer_ports,
> > + &ld->n_allocated_peer_ports,
> > + sizeof *ld->peer_ports);
> > + }
> > + ld->peer_ports[ld->n_peer_ports - 1].local = pb;
> > + ld->peer_ports[ld->n_peer_ports - 1].remote = peer;
> > + }
> > +
> > + struct local_datapath *peer_ld =
> > + get_local_datapath(local_datapaths,
> > + peer->datapath->tunnel_key);
> > + if (!peer_ld) {
> > + local_datapath_add__(local_datapaths, peer->datapath,
> > + sbrec_datapath_binding_by_key,
> > + sbrec_port_binding_by_datapath,
> > + sbrec_port_binding_by_name, 1,
> > + tracked_datapaths);
> > + return;
> > + }
> > +
> > + for (size_t i = 0; i < peer_ld->n_peer_ports; i++) {
> > + if (peer_ld->peer_ports[i].local == peer) {
> > + return;
> > + }
> > + }
> > +
> > + peer_ld->n_peer_ports++;
> > + if (peer_ld->n_peer_ports > peer_ld->n_allocated_peer_ports) {
> > + peer_ld->peer_ports =
> > + x2nrealloc(peer_ld->peer_ports,
> > + &peer_ld->n_allocated_peer_ports,
> > + sizeof *peer_ld->peer_ports);
> > + }
> > + peer_ld->peer_ports[peer_ld->n_peer_ports - 1].local = peer;
> > + peer_ld->peer_ports[peer_ld->n_peer_ports - 1].remote = pb;
> > +}
> > +
> > +void
> > +local_datapath_remove_peer_port(const struct sbrec_port_binding *pb,
> > + struct local_datapath *ld,
> > + struct hmap *local_datapaths)
> > +{
> > + size_t i = 0;
> > + for (i = 0; i < ld->n_peer_ports; i++) {
> > + if (ld->peer_ports[i].local == pb) {
> > + break;
> > + }
> > + }
> > +
> > + if (i == ld->n_peer_ports) {
> > + return;
> > + }
> > +
> > + const struct sbrec_port_binding *peer = ld->peer_ports[i].remote;
> > +
> > + /* Possible improvement: We can shrink the allocated peer ports
> > + * if (ld->n_peer_ports < ld->n_allocated_peer_ports / 2).
> > + */
> > + ld->peer_ports[i].local = ld->peer_ports[ld->n_peer_ports - 1].local;
> > + ld->peer_ports[i].remote = ld->peer_ports[ld->n_peer_ports -
> 1].remote;
> > + ld->n_peer_ports--;
> > +
> > + struct local_datapath *peer_ld =
> > + get_local_datapath(local_datapaths, peer->datapath->tunnel_key);
> > + if (peer_ld) {
> > + /* Remove the peer port from the peer datapath. The peer
> > + * datapath also tries to remove its peer lport, but that would
> > + * be no-op. */
> > + local_datapath_remove_peer_port(peer, peer_ld, local_datapaths);
> > + }
> > +}
> > +
> > +/* track datapath functions. */
> > +struct tracked_datapath *
> > +tracked_datapath_add(const struct sbrec_datapath_binding *dp,
> > + enum en_tracked_resource_type tracked_type,
> > + struct hmap *tracked_datapaths)
> > +{
> > + struct tracked_datapath *t_dp =
> > + tracked_datapath_find(tracked_datapaths, dp);
> > + if (!t_dp) {
> > + t_dp = tracked_datapath_create(dp, tracked_type,
> tracked_datapaths);
> > + } else {
> > + t_dp->tracked_type = tracked_type;
> > + }
> > +
> > + return t_dp;
> > +}
> > +
> > +struct tracked_datapath *
> > +tracked_datapath_find(struct hmap *tracked_datapaths,
> > + const struct sbrec_datapath_binding *dp)
> > +{
> > + struct tracked_datapath *t_dp;
> > + size_t hash = uuid_hash(&dp->header_.uuid);
> > + HMAP_FOR_EACH_WITH_HASH (t_dp, node, hash, tracked_datapaths) {
> > + if (uuid_equals(&t_dp->dp->header_.uuid, &dp->header_.uuid)) {
> > + return t_dp;
> > + }
> > + }
> > +
> > + return NULL;
> > +}
> > +
> > +void
> > +tracked_datapath_lport_add(const struct sbrec_port_binding *pb,
> > + enum en_tracked_resource_type tracked_type,
> > + struct hmap *tracked_datapaths)
> > +{
> > + struct tracked_datapath *tracked_dp =
> > + tracked_datapath_find(tracked_datapaths, pb->datapath);
> > + if (!tracked_dp) {
> > + tracked_dp = tracked_datapath_create(pb->datapath,
> > + TRACKED_RESOURCE_UPDATED,
> > + tracked_datapaths);
> > + }
> > +
> > + /* Check if the lport is already present or not.
> > + * If it is already present, then just update the 'pb' field. */
> > + struct tracked_lport *lport =
> > + shash_find_data(&tracked_dp->lports, pb->logical_port);
> > +
> > + if (!lport) {
> > + lport = xmalloc(sizeof *lport);
> > + shash_add(&tracked_dp->lports, pb->logical_port, lport);
> > + }
> > +
> > + lport->pb = pb;
> > + lport->tracked_type = tracked_type;
> > +}
> > +
> > +void
> > +tracked_datapaths_destroy(struct hmap *tracked_datapaths)
> > +{
> > + struct tracked_datapath *t_dp;
> > + HMAP_FOR_EACH_POP (t_dp, node, tracked_datapaths) {
> > + shash_destroy_free_data(&t_dp->lports);
> > + free(t_dp);
> > + }
> > +
> > + hmap_destroy(tracked_datapaths);
> > +}
> > +
> > +/* static functions. */
> > +static struct local_datapath *
> > +local_datapath_add__(struct hmap *local_datapaths,
> > + const struct sbrec_datapath_binding *dp,
> > + struct ovsdb_idl_index
> *sbrec_datapath_binding_by_key,
> > + struct ovsdb_idl_index
> *sbrec_port_binding_by_datapath,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name,
> > + int depth, struct hmap *tracked_datapaths)
> > +{
> > + uint32_t dp_key = dp->tunnel_key;
> > + struct local_datapath *ld = get_local_datapath(local_datapaths,
> dp_key);
> > + if (ld) {
> > + return ld;
> > + }
> > +
> > + ld = local_datapath_alloc(dp);
> > + hmap_insert(local_datapaths, &ld->hmap_node, dp_key);
> > + ld->datapath = dp;
> > +
> > + if (tracked_datapaths) {
> > + tracked_datapath_add(ld->datapath, TRACKED_RESOURCE_NEW,
> > + tracked_datapaths);
> > + }
> > +
> > + if (depth >= 100) {
> > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
> > + VLOG_WARN_RL(&rl, "datapaths nested too deep");
> > + return ld;
> > + }
> > +
> > + struct sbrec_port_binding *target =
> > +
> sbrec_port_binding_index_init_row(sbrec_port_binding_by_datapath);
> > + sbrec_port_binding_index_set_datapath(target, dp);
> > +
> > + const struct sbrec_port_binding *pb;
> > + SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target,
> > + sbrec_port_binding_by_datapath) {
> > + if (!strcmp(pb->type, "patch") || !strcmp(pb->type,
> "l3gateway")) {
> > + const char *peer_name = smap_get(&pb->options, "peer");
> > + if (peer_name) {
> > + const struct sbrec_port_binding *peer;
> > +
> > + peer = lport_lookup_by_name(sbrec_port_binding_by_name,
> > + peer_name);
> > +
> > + if (peer && peer->datapath) {
> > + if (!strcmp(pb->type, "patch")) {
> > + /* Add the datapath to local datapath only for
> patch
> > + * ports. For l3gateway ports, since gateway
> router
> > + * resides on one chassis, we don't need to add.
> > + * Otherwise, all other chassis might create
> patch
> > + * ports between br-int and the provider bridge.
> */
> > + local_datapath_add__(local_datapaths,
> peer->datapath,
> > +
> sbrec_datapath_binding_by_key,
> > +
> sbrec_port_binding_by_datapath,
> > + sbrec_port_binding_by_name,
> > + depth + 1,
> tracked_datapaths);
> > + }
> > + ld->n_peer_ports++;
> > + if (ld->n_peer_ports > ld->n_allocated_peer_ports) {
> > + ld->peer_ports =
> > + x2nrealloc(ld->peer_ports,
> > + &ld->n_allocated_peer_ports,
> > + sizeof *ld->peer_ports);
> > + }
> > + ld->peer_ports[ld->n_peer_ports - 1].local = pb;
> > + ld->peer_ports[ld->n_peer_ports - 1].remote = peer;
> > + }
> > + }
> > + }
> > + }
> > + sbrec_port_binding_index_destroy_row(target);
> > + return ld;
> > +}
> > +
> > +static struct tracked_datapath *
> > +tracked_datapath_create(const struct sbrec_datapath_binding *dp,
> > + enum en_tracked_resource_type tracked_type,
> > + struct hmap *tracked_datapaths)
> > +{
> > + struct tracked_datapath *t_dp = xzalloc(sizeof *t_dp);
> > + t_dp->dp = dp;
> > + t_dp->tracked_type = tracked_type;
> > + shash_init(&t_dp->lports);
> > + hmap_insert(tracked_datapaths, &t_dp->node,
> uuid_hash(&dp->header_.uuid));
> > + return t_dp;
> > +}
> > diff --git a/controller/local_data.h b/controller/local_data.h
> > new file mode 100644
> > index 000000000..8b80110fe
> > --- /dev/null
> > +++ b/controller/local_data.h
> > @@ -0,0 +1,111 @@
> > +/* Copyright (c) 2021, Red Hat, Inc.
> > + *
> > + * 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 LOCAL_DATA_H
> > +#define LOCAL_DATA_H 1
> > +
> > +/* OVS includes. */
> > +#include "include/openvswitch/shash.h"
> > +#include "lib/smap.h"
> > +
> > +struct sbrec_datapath_binding;
> > +struct sbrec_port_binding;
> > +struct ovsdb_idl_index;
> > +
> > +/* A logical datapath that has some relevance to this hypervisor. A
> logical
> > + * datapath D is relevant to hypervisor H if:
> > + *
> > + * - Some VIF or l2gateway or l3gateway port in D is located on H.
> > + *
> > + * - D is reachable over a series of hops across patch ports,
> starting from
> > + * a datapath relevant to H.
> > + *
> > + * The 'hmap_node''s hash value is 'datapath->tunnel_key'. */
> > +struct local_datapath {
> > + struct hmap_node hmap_node;
> > + const struct sbrec_datapath_binding *datapath;
> > + bool is_switch;
> > +
> > + /* The localnet port in this datapath, if any (at most one is
> allowed). */
> > + const struct sbrec_port_binding *localnet_port;
> > +
> > + struct {
> > + const struct sbrec_port_binding *local;
> > + const struct sbrec_port_binding *remote;
> > + } *peer_ports;
> > +
> > + size_t n_peer_ports;
> > + size_t n_allocated_peer_ports;
> > +
> > + struct shash external_ports;
> > +};
> > +
> > +struct local_datapath *local_datapath_alloc(
> > + const struct sbrec_datapath_binding *);
> > +struct local_datapath *get_local_datapath(const struct hmap *,
> > + uint32_t tunnel_key);
> > +struct local_datapath * local_datapath_add(
> > + struct hmap *local_datapaths, const struct sbrec_datapath_binding *,
> > + struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name,
> > + struct hmap *tracked_datapaths);
> > +
> > +void local_datapaths_destroy(struct hmap *local_datapaths);
> > +void local_datapath_destroy(struct local_datapath *ld);
> > +void local_datapath_add_peer_port(
> > + const struct sbrec_port_binding *pb,
> > + struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name,
> > + struct local_datapath *ld,
> > + struct hmap *local_datapaths,
> > + struct hmap *tracked_datapaths);
> > +
> > +void local_datapath_remove_peer_port(const struct sbrec_port_binding *pb,
> > + struct local_datapath *ld,
> > + struct hmap *local_datapaths);
> > +
> > +enum en_tracked_resource_type {
> > + TRACKED_RESOURCE_NEW,
> > + TRACKED_RESOURCE_REMOVED,
> > + TRACKED_RESOURCE_UPDATED
> > +};
> > +
> > +/* Represents a tracked logical port. */
> > +struct tracked_lport {
> > + const struct sbrec_port_binding *pb;
> > + enum en_tracked_resource_type tracked_type;
> > +};
> > +
> > +/* Represent a tracked datapath. */
> > +struct tracked_datapath {
> > + struct hmap_node node;
> > + const struct sbrec_datapath_binding *dp;
> > + enum en_tracked_resource_type tracked_type;
> > + struct shash lports; /* shash of struct tracked_binding_lport. */
> > +};
> > +
> > +struct tracked_datapath * tracked_datapath_add(
> > + const struct sbrec_datapath_binding *, enum en_tracked_resource_type,
> > + struct hmap *tracked_datapaths);
> > +struct tracked_datapath *tracked_datapath_find(
> > + struct hmap *tracked_datapaths, const struct sbrec_datapath_binding
> *);
> > +void tracked_datapath_lport_add(const struct sbrec_port_binding *,
> > + enum en_tracked_resource_type,
> > + struct hmap *tracked_datapaths);
> > +void tracked_datapaths_destroy(struct hmap *tracked_datapaths);
> > +
> > +#endif /* controller/local_data.h */
> > diff --git a/controller/lport.c b/controller/lport.c
> > index 478fcfd82..25b4ef200 100644
> > --- a/controller/lport.c
> > +++ b/controller/lport.c
> > @@ -23,6 +23,10 @@
> > #include "lib/ovn-sb-idl.h"
> > VLOG_DEFINE_THIS_MODULE(lport);
> >
> > +static const struct sbrec_port_binding *get_peer_lport(
> > + const struct sbrec_port_binding *pb,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name);
> > +
> > const struct sbrec_port_binding *
> > lport_lookup_by_name(struct ovsdb_idl_index *sbrec_port_binding_by_name,
> > const char *name)
> > @@ -84,6 +88,26 @@ lport_is_chassis_resident(struct ovsdb_idl_index
> *sbrec_port_binding_by_name,
> > }
> > }
> >
> > +const struct sbrec_port_binding *
> > +lport_get_peer(const struct sbrec_port_binding *pb,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name)
> > +{
> > + if (strcmp(pb->type, "patch")) {
> > + return NULL;
> > + }
> > + return get_peer_lport(pb, sbrec_port_binding_by_name);
> > +}
> > +
> > +const struct sbrec_port_binding *
> > +lport_get_l3gw_peer(const struct sbrec_port_binding *pb,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name)
> > +{
> > + if (strcmp(pb->type, "l3gateway")) {
> > + return NULL;
> > + }
> > + return get_peer_lport(pb, sbrec_port_binding_by_name);
> > +}
> > +
> > const struct sbrec_datapath_binding *
> > datapath_lookup_by_key(struct ovsdb_idl_index
> *sbrec_datapath_binding_by_key,
> > uint64_t dp_key)
> > @@ -120,3 +144,19 @@ mcgroup_lookup_by_dp_name(
> >
> > return retval;
> > }
> > +
> > +static const struct sbrec_port_binding *
> > +get_peer_lport(const struct sbrec_port_binding *pb,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name)
> > +{
> > + const char *peer_name = smap_get(&pb->options, "peer");
> > +
> > + if (!peer_name) {
> > + return NULL;
> > + }
> > +
> > + const struct sbrec_port_binding *peer;
> > + peer = lport_lookup_by_name(sbrec_port_binding_by_name,
> > + peer_name);
> > + return (peer && peer->datapath) ? peer : NULL;
> > +}
> > diff --git a/controller/lport.h b/controller/lport.h
> > index 345efc184..43b3d714d 100644
> > --- a/controller/lport.h
> > +++ b/controller/lport.h
> > @@ -54,5 +54,10 @@ lport_is_chassis_resident(struct ovsdb_idl_index
> *sbrec_port_binding_by_name,
> > const struct sbrec_chassis *chassis,
> > const struct sset *active_tunnels,
> > const char *port_name);
> > -
> > +const struct sbrec_port_binding *lport_get_peer(
> > + const struct sbrec_port_binding *,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name);
> > +const struct sbrec_port_binding *lport_get_l3gw_peer(
> > + const struct sbrec_port_binding *,
> > + struct ovsdb_idl_index *sbrec_port_binding_by_name);
> > #endif /* controller/lport.h */
> > diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
> > index 55b75f7b2..c299f1a2e 100644
> > --- a/controller/ovn-controller.c
> > +++ b/controller/ovn-controller.c
> > @@ -39,6 +39,7 @@
> > #include "lflow.h"
> > #include "lflow-cache.h"
> > #include "lib/vswitch-idl.h"
> > +#include "local_data.h"
> > #include "lport.h"
> > #include "memory.h"
> > #include "ofctrl.h"
> > @@ -138,15 +139,6 @@ struct pending_pkt {
> > /* Registered ofctrl seqno type for nb_cfg propagation. */
> > static size_t ofctrl_seq_type_nb_cfg;
> >
> > -struct local_datapath *
> > -get_local_datapath(const struct hmap *local_datapaths, uint32_t
> tunnel_key)
> > -{
> > - struct hmap_node *node = hmap_first_with_hash(local_datapaths,
> tunnel_key);
> > - return (node
> > - ? CONTAINER_OF(node, struct local_datapath, hmap_node)
> > - : NULL);
> > -}
> > -
> > uint32_t
> > get_tunnel_type(const char *name)
> > {
> > @@ -1075,14 +1067,14 @@ struct ed_type_runtime_data {
> > *
> > *
> ------------------------------------------------------------------------
> > * | | This is a hmap of
> |
> > - * | | 'struct tracked_binding_datapath' defined in
> |
> > - * | | binding.h. Runtime data handlers for OVS
> |
> > + * | | 'struct tracked_datapath' defined in
> |
> > + * | | ldata.h. Runtime data handlers for OVS
> |
> > * | | Interface and Port Binding changes store the
> |
> > * | @tracked_dp_bindings | changed datapaths (datapaths added/removed
> from |
> > * | | local_datapaths) and changed port bindings
> |
> > - * | | (added/updated/deleted in 'lbinding_data').
> |
> > + * | | (added/updated/deleted in 'lbinding_data').
> |
> > * | | So any changes to the runtime data -
> |
> > - * | | local_datapaths and lbinding_data is
> captured |
> > + * | | local_datapaths and lbinding_data is
> captured |
> > * | | here.
> |
> > *
> ------------------------------------------------------------------------
> > * | | This is a bool which represents if the
> runtime |
> > @@ -1109,7 +1101,7 @@ struct ed_type_runtime_data {
> > *
> > * ---------------------------------------------------------------------
> > * | local_datapaths | The changes to these runtime data is captured in
> |
> > - * | lbinding_data | the @tracked_dp_bindings indirectly and hence it |
> > + * | lbinding_data | the @tracked_dp_bindings indirectly and hence it
> |
> > * | local_lport_ids | is not tracked explicitly.
> |
> > * ---------------------------------------------------------------------
> > * | local_iface_ids | This is used internally within the runtime data
> |
> > @@ -1134,7 +1126,7 @@ en_runtime_data_clear_tracked_data(void *data_)
> > {
> > struct ed_type_runtime_data *data = data_;
> >
> > - binding_tracked_dp_destroy(&data->tracked_dp_bindings);
> > + tracked_datapaths_destroy(&data->tracked_dp_bindings);
> > hmap_init(&data->tracked_dp_bindings);
> > data->local_lports_changed = false;
> > data->tracked = false;
> > @@ -1172,15 +1164,7 @@ en_runtime_data_cleanup(void *data)
> > sset_destroy(&rt_data->active_tunnels);
> > sset_destroy(&rt_data->egress_ifaces);
> > smap_destroy(&rt_data->local_iface_ids);
> > - struct local_datapath *cur_node, *next_node;
> > - HMAP_FOR_EACH_SAFE (cur_node, next_node, hmap_node,
> > - &rt_data->local_datapaths) {
> > - free(cur_node->peer_ports);
> > - shash_destroy(&cur_node->external_ports);
> > - hmap_remove(&rt_data->local_datapaths, &cur_node->hmap_node);
> > - free(cur_node);
> > - }
> > - hmap_destroy(&rt_data->local_datapaths);
> > + local_datapaths_destroy(&rt_data->local_datapaths);
> > shash_destroy_free_data(&rt_data->local_active_ports_ipv6_pd);
> > shash_destroy_free_data(&rt_data->local_active_ports_ras);
> > local_binding_data_destroy(&rt_data->lbinding_data);
> > @@ -1292,14 +1276,7 @@ en_runtime_data_run(struct engine_node *node, void
> *data)
> > /* don't cleanup since there is no data yet */
> > first_run = false;
> > } else {
> > - struct local_datapath *cur_node, *next_node;
> > - HMAP_FOR_EACH_SAFE (cur_node, next_node, hmap_node,
> local_datapaths) {
> > - free(cur_node->peer_ports);
> > - shash_destroy(&cur_node->external_ports);
> > - hmap_remove(local_datapaths, &cur_node->hmap_node);
> > - free(cur_node);
> > - }
> > - hmap_clear(local_datapaths);
> > + local_datapaths_destroy(local_datapaths);
> > shash_clear_free_data(local_active_ipv6_pd);
> > shash_clear_free_data(local_active_ras);
> > local_binding_data_destroy(&rt_data->lbinding_data);
> > @@ -1308,6 +1285,7 @@ en_runtime_data_run(struct engine_node *node, void
> *data)
> > sset_destroy(active_tunnels);
> > sset_destroy(&rt_data->egress_ifaces);
> > smap_destroy(&rt_data->local_iface_ids);
> > + hmap_init(local_datapaths);
> > sset_init(local_lports);
> > related_lports_init(&rt_data->related_lports);
> > sset_init(active_tunnels);
> > @@ -1749,12 +1727,12 @@ port_groups_runtime_data_handler(struct
> engine_node *node, void *data)
> > pg_sb->name);
> > ovs_assert(pg_lports);
> >
> > - struct tracked_binding_datapath *tdp;
> > + struct tracked_datapath *tdp;
> > bool need_update = false;
> > HMAP_FOR_EACH (tdp, node, &rt_data->tracked_dp_bindings) {
> > struct shash_node *shash_node;
> > SHASH_FOR_EACH (shash_node, &tdp->lports) {
> > - struct tracked_binding_lport *lport = shash_node->data;
> > + struct tracked_lport *lport = shash_node->data;
> > if (sset_contains(pg_lports, lport->pb->logical_port)) {
> > /* At least one local port-binding change is related
> to the
> > * port_group, so the port_group_cs_local needs
> update. */
> > @@ -1907,9 +1885,9 @@ ct_zones_runtime_data_handler(struct engine_node
> *node, void *data OVS_UNUSED)
> > }
> >
> > struct hmap *tracked_dp_bindings = &rt_data->tracked_dp_bindings;
> > - struct tracked_binding_datapath *tdp;
> > + struct tracked_datapath *tdp;
> > HMAP_FOR_EACH (tdp, node, tracked_dp_bindings) {
> > - if (tdp->is_new) {
> > + if (tdp->tracked_type == TRACKED_RESOURCE_NEW) {
> > /* A new datapath has been added. Fall back to full
> recompute. */
> > return false;
> > }
> > @@ -2531,9 +2509,9 @@ lflow_output_runtime_data_handler(struct
> engine_node *node,
> > struct hmap *lbs = NULL;
> > init_lflow_ctx(node, rt_data, fo, &l_ctx_in, &l_ctx_out);
> >
> > - struct tracked_binding_datapath *tdp;
> > + struct tracked_datapath *tdp;
> > HMAP_FOR_EACH (tdp, node, tracked_dp_bindings) {
> > - if (tdp->is_new) {
> > + if (tdp->tracked_type == TRACKED_RESOURCE_NEW) {
> > if (!lbs) {
> > lbs =
> load_balancers_by_dp_init(&rt_data->local_datapaths,
> > l_ctx_in.lb_table);
> > @@ -2550,7 +2528,7 @@ lflow_output_runtime_data_handler(struct
> engine_node *node,
> > } else {
> > struct shash_node *shash_node;
> > SHASH_FOR_EACH (shash_node, &tdp->lports) {
> > - struct tracked_binding_lport *lport = shash_node->data;
> > + struct tracked_lport *lport = shash_node->data;
> > if (!lflow_handle_flows_for_lport(lport->pb, &l_ctx_in,
> > &l_ctx_out)) {
> > return false;
> > diff --git a/controller/ovn-controller.h b/controller/ovn-controller.h
> > index a3aa6ebd3..578588305 100644
> > --- a/controller/ovn-controller.h
> > +++ b/controller/ovn-controller.h
> > @@ -40,36 +40,6 @@ struct ct_zone_pending_entry {
> > enum ct_zone_pending_state state;
> > };
> >
> > -/* A logical datapath that has some relevance to this hypervisor. A
> logical
> > - * datapath D is relevant to hypervisor H if:
> > - *
> > - * - Some VIF or l2gateway or l3gateway port in D is located on H.
> > - *
> > - * - D is reachable over a series of hops across patch ports,
> starting from
> > - * a datapath relevant to H.
> > - *
> > - * The 'hmap_node''s hash value is 'datapath->tunnel_key'. */
> > -struct local_datapath {
> > - struct hmap_node hmap_node;
> > - const struct sbrec_datapath_binding *datapath;
> > -
> > - /* The localnet port in this datapath, if any (at most one is
> allowed). */
> > - const struct sbrec_port_binding *localnet_port;
> > -
> > - struct {
> > - const struct sbrec_port_binding *local;
> > - const struct sbrec_port_binding *remote;
> > - } *peer_ports;
> > -
> > - size_t n_peer_ports;
> > - size_t n_allocated_peer_ports;
> > -
> > - struct shash external_ports;
> > -};
> > -
> > -struct local_datapath *get_local_datapath(const struct hmap *,
> > - uint32_t tunnel_key);
> > -
> > const struct ovsrec_bridge *get_bridge(const struct ovsrec_bridge_table
> *,
> > const char *br_name);
> >
> > diff --git a/controller/patch.c b/controller/patch.c
> > index e54b56354..a661025da 100644
> > --- a/controller/patch.c
> > +++ b/controller/patch.c
> > @@ -20,6 +20,7 @@
> > #include "hash.h"
> > #include "lflow.h"
> > #include "lib/vswitch-idl.h"
> > +#include "local_data.h"
> > #include "lport.h"
> > #include "openvswitch/hmap.h"
> > #include "openvswitch/vlog.h"
> > diff --git a/controller/physical.c b/controller/physical.c
> > index 00cf2ca35..188606927 100644
> > --- a/controller/physical.c
> > +++ b/controller/physical.c
> > @@ -21,6 +21,7 @@
> > #include "flow.h"
> > #include "ha-chassis.h"
> > #include "lflow.h"
> > +#include "local_data.h"
> > #include "lport.h"
> > #include "chassis.h"
> > #include "lib/bundle.h"
> > diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> > index d7166b0a9..d417b858d 100644
> > --- a/controller/pinctrl.c
> > +++ b/controller/pinctrl.c
> > @@ -25,6 +25,7 @@
> > #include "encaps.h"
> > #include "flow.h"
> > #include "ha-chassis.h"
> > +#include "local_data.h"
> > #include "lport.h"
> > #include "mac-learn.h"
> > #include "nx-match.h"
> > --
> > 2.31.1
> >
> > _______________________________________________
> > dev mailing list
> > dev at openvswitch.org
> > https://mail.openvswitch.org/mailman/listinfo/ovs-dev
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
More information about the dev
mailing list