@@ -18,6 +18,7 @@
/* OVS includes. */
#include "lib/bitmap.h"
#include "openvswitch/poll-loop.h"
+#include "lib/hmapx.h"
#include "lib/sset.h"
#include "lib/util.h"
#include "lib/netdev.h"
@@ -1352,6 +1353,7 @@ is_postponed_port(const char *port_name)
*/
static bool
claim_lport(const struct sbrec_port_binding *pb,
+ struct local_datapath *ld,
const struct sbrec_port_binding *parent_pb,
const struct sbrec_chassis *chassis_rec,
const struct ovsrec_interface *iface_rec,
@@ -1363,6 +1365,10 @@ claim_lport(const struct sbrec_port_binding *pb,
enum can_bind can_bind = lport_can_bind_on_this_chassis(chassis_rec, pb);
bool update_tracked = false;
+ if (ld) {
+ sset_add(&ld->claimed_lports, pb->logical_port);
+ }
+
if (can_bind == CAN_BIND_AS_MAIN) {
if (pb->chassis != chassis_rec) {
long long int now = time_msec();
@@ -1419,6 +1425,7 @@ claim_lport(const struct sbrec_port_binding *pb,
return update_port_additional_encap_if_needed(
pb, chassis_rec, iface_rec, sb_readonly);
}
+
return true;
}
@@ -1490,6 +1497,7 @@ release_lport_additional_chassis(const struct sbrec_port_binding *pb,
static bool
release_lport(const struct sbrec_port_binding *pb,
+ struct local_datapath *ld,
const struct sbrec_chassis *chassis_rec, bool sb_readonly,
struct hmap *tracked_datapaths, struct if_status_mgr *if_mgr)
{
@@ -1506,6 +1514,10 @@ release_lport(const struct sbrec_port_binding *pb,
}
update_lport_tracking(pb, tracked_datapaths, false);
if_status_mgr_release_iface(if_mgr, pb->logical_port);
+
+ if (ld) {
+ sset_find_and_delete(&ld->claimed_lports, pb->logical_port);
+ }
return true;
}
@@ -1549,7 +1561,11 @@ release_binding_lport(const struct sbrec_chassis *chassis_rec,
remove_related_lport(b_lport->pb, b_ctx_out);
}
if (is_binding_lport_this_chassis(b_lport, chassis_rec)) {
- if (!release_lport(b_lport->pb, chassis_rec, sb_readonly,
+ struct local_datapath *ld =
+ get_local_datapath(b_ctx_out->local_datapaths,
+ b_lport->pb->datapath->tunnel_key);
+
+ if (!release_lport(b_lport->pb, ld, chassis_rec, sb_readonly,
b_ctx_out->tracked_dp_bindings,
b_ctx_out->if_mgr)) {
return false;
@@ -1575,7 +1591,15 @@ consider_vif_lport_(const struct sbrec_port_binding *pb,
const struct sbrec_port_binding *parent_pb =
binding_lport_get_parent_pb(b_lport);
- if (!claim_lport(pb, parent_pb, b_ctx_in->chassis_rec,
+ struct local_datapath *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,
+ pb->datapath, b_ctx_in->chassis_rec,
+ b_ctx_out->local_datapaths,
+ b_ctx_out->tracked_dp_bindings);
+
+ if (!claim_lport(pb, ld, parent_pb, b_ctx_in->chassis_rec,
b_lport->lbinding->iface,
!b_ctx_in->ovnsb_idl_txn,
!parent_pb, b_ctx_out->tracked_dp_bindings,
@@ -1584,12 +1608,6 @@ consider_vif_lport_(const struct sbrec_port_binding *pb,
return false;
}
- 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_in->chassis_rec,
- 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);
if (binding_lport_update_port_sec(b_lport, pb) &&
@@ -1627,7 +1645,10 @@ consider_vif_lport_(const struct sbrec_port_binding *pb,
if (!lbinding_set || !can_bind) {
remove_related_lport(pb, b_ctx_out);
- return release_lport(pb, b_ctx_in->chassis_rec,
+ struct local_datapath *ld =
+ get_local_datapath(b_ctx_out->local_datapaths,
+ pb->datapath->tunnel_key);
+ return release_lport(pb, ld, b_ctx_in->chassis_rec,
!b_ctx_in->ovnsb_idl_txn,
b_ctx_out->tracked_dp_bindings,
b_ctx_out->if_mgr);
@@ -1675,10 +1696,9 @@ consider_vif_lport(const struct sbrec_port_binding *pb,
b_lport = NULL;
}
} else {
- struct shash *binding_lports =
- &b_ctx_out->lbinding_data->lports;
- b_lport = local_binding_add_lport(binding_lports, lbinding, pb,
- LP_VIF);
+ struct shash *binding_lports = &b_ctx_out->lbinding_data->lports;
+ b_lport = local_binding_add_lport(binding_lports,
+ lbinding, pb, LP_VIF);
}
}
@@ -1722,8 +1742,8 @@ consider_container_lport(const struct sbrec_port_binding *pb,
}
struct binding_lport *container_b_lport =
- local_binding_add_lport(binding_lports, parent_lbinding, pb,
- LP_CONTAINER);
+ local_binding_add_lport(binding_lports, parent_lbinding,
+ pb, LP_CONTAINER);
struct binding_lport *parent_b_lport =
binding_lport_find(binding_lports, pb->parent_port);
@@ -1756,7 +1776,10 @@ consider_container_lport(const struct sbrec_port_binding *pb,
* if it was bound earlier. */
if (is_binding_lport_this_chassis(container_b_lport,
b_ctx_in->chassis_rec)) {
- return release_lport(pb, b_ctx_in->chassis_rec,
+ struct local_datapath *ld =
+ get_local_datapath(b_ctx_out->local_datapaths,
+ pb->datapath->tunnel_key);
+ return release_lport(pb, ld, b_ctx_in->chassis_rec,
!b_ctx_in->ovnsb_idl_txn,
b_ctx_out->tracked_dp_bindings,
b_ctx_out->if_mgr);
@@ -1850,8 +1873,8 @@ consider_localport(const struct sbrec_port_binding *pb,
return true;
}
- local_binding_add_lport(&b_ctx_out->lbinding_data->lports, lbinding, pb,
- LP_LOCALPORT);
+ local_binding_add_lport(&b_ctx_out->lbinding_data->lports,
+ lbinding, pb, LP_LOCALPORT);
/* If the port binding is claimed, then release it as localport is claimed
* by any ovn-controller. */
@@ -1893,12 +1916,12 @@ consider_nonvif_lport_(const struct sbrec_port_binding *pb,
if (our_chassis) {
update_local_lports(pb->logical_port, b_ctx_out);
if (!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,
- pb->datapath, b_ctx_in->chassis_rec,
- b_ctx_out->local_datapaths,
- b_ctx_out->tracked_dp_bindings);
+ 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,
+ pb->datapath, b_ctx_in->chassis_rec,
+ b_ctx_out->local_datapaths,
+ b_ctx_out->tracked_dp_bindings);
} else {
/* Add the peer datapath to the local datapaths if it's
* not present yet.
@@ -1917,7 +1940,7 @@ consider_nonvif_lport_(const struct sbrec_port_binding *pb,
}
update_related_lport(pb, b_ctx_out);
- return claim_lport(pb, NULL, b_ctx_in->chassis_rec, NULL,
+ return claim_lport(pb, ld, NULL, b_ctx_in->chassis_rec, NULL,
!b_ctx_in->ovnsb_idl_txn, false,
b_ctx_out->tracked_dp_bindings,
b_ctx_out->if_mgr,
@@ -1931,10 +1954,10 @@ consider_nonvif_lport_(const struct sbrec_port_binding *pb,
|| is_additional_chassis(pb, b_ctx_in->chassis_rec)
|| if_status_is_port_claimed(b_ctx_out->if_mgr,
pb->logical_port)) {
- if (!release_lport(pb, b_ctx_in->chassis_rec,
- !b_ctx_in->ovnsb_idl_txn,
- b_ctx_out->tracked_dp_bindings,
- b_ctx_out->if_mgr)) {
+ if (!release_lport(pb, ld, b_ctx_in->chassis_rec,
+ !b_ctx_in->ovnsb_idl_txn,
+ b_ctx_out->tracked_dp_bindings,
+ b_ctx_out->if_mgr)) {
return false;
}
@@ -2830,9 +2853,9 @@ handle_deleted_vif_lport(const struct sbrec_port_binding *pb,
struct binding_ctx_in *b_ctx_in,
struct binding_ctx_out *b_ctx_out)
{
+ struct shash *binding_lports = &b_ctx_out->lbinding_data->lports;
struct local_binding *lbinding = NULL;
- struct shash *binding_lports = &b_ctx_out->lbinding_data->lports;
struct binding_lport *b_lport = binding_lport_find(binding_lports, pb->logical_port);
if (b_lport) {
lbinding = b_lport->lbinding;
@@ -2957,13 +2980,13 @@ consider_patch_port_for_local_datapaths(const struct sbrec_port_binding *pb,
if (peer_ld && need_add_peer_to_local(
b_ctx_in->sbrec_port_binding_by_name, peer,
b_ctx_in->chassis_rec)) {
- 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_in->chassis_rec,
- b_ctx_out->local_datapaths,
- b_ctx_out->tracked_dp_bindings);
+ 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,
+ pb->datapath, b_ctx_in->chassis_rec,
+ b_ctx_out->local_datapaths,
+ b_ctx_out->tracked_dp_bindings);
}
} else {
/* Add the peer datapath to the local datapaths if it's
@@ -2984,7 +3007,7 @@ consider_patch_port_for_local_datapaths(const struct sbrec_port_binding *pb,
/* If this chassis is requested - try to claim. */
if (pb->requested_chassis == b_ctx_in->chassis_rec) {
- return claim_lport(pb, NULL, b_ctx_in->chassis_rec, NULL,
+ return claim_lport(pb, ld, NULL, b_ctx_in->chassis_rec, NULL,
!b_ctx_in->ovnsb_idl_txn, false,
b_ctx_out->tracked_dp_bindings,
b_ctx_out->if_mgr,
@@ -2998,7 +3021,7 @@ consider_patch_port_for_local_datapaths(const struct sbrec_port_binding *pb,
|| if_status_is_port_claimed(b_ctx_out->if_mgr, pb->logical_port)) {
remove_local_lports(pb->logical_port, b_ctx_out);
- if (!release_lport(pb, b_ctx_in->chassis_rec,
+ if (!release_lport(pb, ld, b_ctx_in->chassis_rec,
!b_ctx_in->ovnsb_idl_txn,
b_ctx_out->tracked_dp_bindings,
b_ctx_out->if_mgr)) {
@@ -3557,7 +3580,8 @@ binding_lport_create(const struct sbrec_port_binding *pb,
}
static void
-binding_lport_add(struct shash *binding_lports, struct binding_lport *b_lport)
+binding_lport_add(struct shash *binding_lports,
+ struct binding_lport *b_lport)
{
shash_add(binding_lports, b_lport->pb->logical_port, b_lport);
}
@@ -88,6 +88,7 @@ local_datapath_alloc(const struct sbrec_datapath_binding *dp)
ld->is_transit_switch = datapath_is_transit_switch(dp);
shash_init(&ld->external_ports);
shash_init(&ld->multichassis_ports);
+ sset_init(&ld->claimed_lports);
/* memory accounting - common part. */
local_datapath_usage += sizeof *ld;
@@ -127,6 +128,7 @@ local_datapath_destroy(struct local_datapath *ld)
free(ld->peer_ports);
shash_destroy(&ld->external_ports);
shash_destroy(&ld->multichassis_ports);
+ sset_destroy(&ld->claimed_lports);
free(ld);
}
@@ -180,7 +182,7 @@ need_add_peer_to_local(
return false;
}
-void
+struct local_datapath *
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,
@@ -189,11 +191,11 @@ add_local_datapath(struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
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, 0,
- dp, chassis, local_datapaths,
- tracked_datapaths);
+ return add_local_datapath__(sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name, 0,
+ dp, chassis, local_datapaths,
+ tracked_datapaths);
}
void
@@ -63,6 +63,8 @@ struct local_datapath {
struct shash external_ports;
struct shash multichassis_ports;
+
+ struct sset claimed_lports;
};
struct local_datapath *local_datapath_alloc(
@@ -78,7 +80,7 @@ need_add_peer_to_local(
struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_port_binding *,
const struct sbrec_chassis *);
-void add_local_datapath(
+struct local_datapath * 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,