Skip to content

Commit

Permalink
Track interface MTU in if-status-mgr
Browse files Browse the repository at this point in the history
This will be used in a later patch to calculate the effective interface
MTU after considering tunneling overhead.

NOTE: ideally, OVN would support Logical_Port MTU, in which case we
wouldn't have to track OVSDB for interfaces.

Signed-off-by: Ihar Hrachyshka <ihrachys@redhat.com>
Acked-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Mark Michelson <mmichels@redhat.com>
  • Loading branch information
booxter authored and putnopvut committed May 30, 2023
1 parent 06d8db6 commit cdd8dea
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 6 deletions.
4 changes: 2 additions & 2 deletions controller/binding.c
Original file line number Diff line number Diff line change
Expand Up @@ -1307,7 +1307,7 @@ claim_lport(const struct sbrec_port_binding *pb,
}
set_pb_chassis_in_sbrec(pb, chassis_rec, true);
} else {
if_status_mgr_claim_iface(if_mgr, pb, chassis_rec,
if_status_mgr_claim_iface(if_mgr, pb, chassis_rec, iface_rec,
sb_readonly);
}
register_claim_timestamp(pb->logical_port, now);
Expand All @@ -1322,7 +1322,7 @@ claim_lport(const struct sbrec_port_binding *pb,
!smap_get_bool(&iface_rec->external_ids,
OVN_INSTALLED_EXT_ID, false)) {
if_status_mgr_claim_iface(if_mgr, pb, chassis_rec,
sb_readonly);
iface_rec, sb_readonly);
}
}
}
Expand Down
40 changes: 36 additions & 4 deletions controller/if-status.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
#include "binding.h"
#include "if-status.h"
#include "ofctrl-seqno.h"
#include "ovsport.h"
#include "simap.h"

#include "lib/hmapx.h"
#include "lib/util.h"
#include "timeval.h"
#include "openvswitch/vlog.h"
#include "lib/vswitch-idl.h"
#include "lib/ovn-sb-idl.h"

VLOG_DEFINE_THIS_MODULE(if_status);
Expand Down Expand Up @@ -181,6 +183,7 @@ struct ovs_iface {
* be fully programmed in OVS. Only used in state
* OIF_INSTALL_FLOWS.
*/
uint16_t mtu; /* Extracted from OVS interface.mtu field. */
};

static uint64_t ifaces_usage;
Expand All @@ -205,9 +208,10 @@ struct if_status_mgr {
uint32_t iface_seqno;
};

static struct ovs_iface *ovs_iface_create(struct if_status_mgr *,
const char *iface_id,
enum if_state );
static struct ovs_iface *
ovs_iface_create(struct if_status_mgr *, const char *iface_id,
const struct ovsrec_interface *iface_rec,
enum if_state);
static void add_to_ovn_uninstall_hash(struct if_status_mgr *, const char *,
const struct uuid *);
static void ovs_iface_destroy(struct if_status_mgr *, struct ovs_iface *);
Expand Down Expand Up @@ -272,13 +276,14 @@ void
if_status_mgr_claim_iface(struct if_status_mgr *mgr,
const struct sbrec_port_binding *pb,
const struct sbrec_chassis *chassis_rec,
const struct ovsrec_interface *iface_rec,
bool sb_readonly)
{
const char *iface_id = pb->logical_port;
struct ovs_iface *iface = shash_find_data(&mgr->ifaces, iface_id);

if (!iface) {
iface = ovs_iface_create(mgr, iface_id, OIF_CLAIMED);
iface = ovs_iface_create(mgr, iface_id, iface_rec, OIF_CLAIMED);
}

memcpy(&iface->pb_uuid, &pb->header_.uuid, sizeof(iface->pb_uuid));
Expand Down Expand Up @@ -639,8 +644,34 @@ ovn_uninstall_hash_account_mem(const char *name, bool erase)
}
}

uint16_t
if_status_mgr_iface_get_mtu(const struct if_status_mgr *mgr,
const char *iface_id)
{
const struct ovs_iface *iface = shash_find_data(&mgr->ifaces, iface_id);
return iface ? iface->mtu : 0;
}

bool
if_status_mgr_iface_update(const struct if_status_mgr *mgr,
const struct ovsrec_interface *iface_rec)
{
const char *iface_id = smap_get(&iface_rec->external_ids, "iface-id");
if (!iface_id) {
return false;
}
uint16_t mtu = get_iface_mtu(iface_rec);
struct ovs_iface *iface = shash_find_data(&mgr->ifaces, iface_id);
if (iface && iface->mtu != mtu) {
iface->mtu = mtu;
return true;
}
return false;
}

static struct ovs_iface *
ovs_iface_create(struct if_status_mgr *mgr, const char *iface_id,
const struct ovsrec_interface *iface_rec,
enum if_state state)
{
struct ovs_iface *iface = xzalloc(sizeof *iface);
Expand All @@ -650,6 +681,7 @@ ovs_iface_create(struct if_status_mgr *mgr, const char *iface_id,
shash_add_nocopy(&mgr->ifaces, iface->id, iface);
ovs_iface_set_state(mgr, iface, state);
ovs_iface_account_mem(iface_id, false);
if_status_mgr_iface_update(mgr, iface_rec);
return iface;
}

Expand Down
5 changes: 5 additions & 0 deletions controller/if-status.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ void if_status_mgr_destroy(struct if_status_mgr *);
void if_status_mgr_claim_iface(struct if_status_mgr *,
const struct sbrec_port_binding *pb,
const struct sbrec_chassis *chassis_rec,
const struct ovsrec_interface *iface_rec,
bool sb_readonly);
void if_status_mgr_release_iface(struct if_status_mgr *, const char *iface_id);
void if_status_mgr_delete_iface(struct if_status_mgr *, const char *iface_id);
Expand All @@ -56,5 +57,9 @@ bool if_status_handle_claims(struct if_status_mgr *mgr,
void if_status_mgr_remove_ovn_installed(struct if_status_mgr *mgr,
const char *name,
const struct uuid *uuid);
uint16_t if_status_mgr_iface_get_mtu(const struct if_status_mgr *mgr,
const char *iface_id);
bool if_status_mgr_iface_update(const struct if_status_mgr *mgr,
const struct ovsrec_interface *iface_rec);

# endif /* controller/if-status.h */
122 changes: 122 additions & 0 deletions controller/ovn-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include "lib/ovn-dirs.h"
#include "lib/ovn-sb-idl.h"
#include "lib/ovn-util.h"
#include "ovsport.h"
#include "patch.h"
#include "vif-plug.h"
#include "vif-plug-provider.h"
Expand Down Expand Up @@ -1063,6 +1064,7 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl)
ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_name);
ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd);
ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_bfd_status);
ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_mtu);
ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_type);
ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_options);
ovsdb_idl_track_add_column(ovs_idl, &ovsrec_interface_col_ofport);
Expand Down Expand Up @@ -1162,6 +1164,56 @@ en_ofctrl_is_connected_run(struct engine_node *node, void *data)
engine_set_node_state(node, EN_UNCHANGED);
}

struct ed_type_if_status_mgr {
const struct if_status_mgr *manager;
const struct ovsrec_interface_table *iface_table;
};

static void *
en_if_status_mgr_init(struct engine_node *node OVS_UNUSED,
struct engine_arg *arg OVS_UNUSED)
{
struct ed_type_if_status_mgr *data = xzalloc(sizeof *data);
return data;
}

static void
en_if_status_mgr_cleanup(void *data OVS_UNUSED)
{
}

static void
en_if_status_mgr_run(struct engine_node *node, void *data_)
{
enum engine_node_state state = EN_UNCHANGED;
struct ed_type_if_status_mgr *data = data_;
struct controller_engine_ctx *ctrl_ctx = engine_get_context()->client_ctx;
data->manager = ctrl_ctx->if_mgr;
data->iface_table = EN_OVSDB_GET(engine_get_input("OVS_interface", node));

const struct ovsrec_interface *iface;
OVSREC_INTERFACE_TABLE_FOR_EACH (iface, data->iface_table) {
if (if_status_mgr_iface_update(data->manager, iface)) {
state = EN_UPDATED;
}
}
engine_set_node_state(node, state);
}

static bool
if_status_mgr_ovs_interface_handler(struct engine_node *node, void *data)
{
struct ed_type_if_status_mgr *data_ = data;

const struct ovsrec_interface *iface;
OVSREC_INTERFACE_TABLE_FOR_EACH_TRACKED (iface, data_->iface_table) {
if (if_status_mgr_iface_update(data_->manager, iface)) {
engine_set_node_state(node, EN_UPDATED);
}
}
return true;
}

/* This engine node is to wrap the OVS_interface input and maintain a copy of
* the old version of data for the column external_ids.
*
Expand Down Expand Up @@ -4061,6 +4113,9 @@ static void init_physical_ctx(struct engine_node *node,
const struct ed_type_mff_ovn_geneve *ed_mff_ovn_geneve =
engine_get_input_data("mff_ovn_geneve", node);

const struct ovsrec_interface_table *ovs_interface_table =
EN_OVSDB_GET(engine_get_input("if_status_mgr", node));

const struct ovsrec_open_vswitch_table *ovs_table =
EN_OVSDB_GET(engine_get_input("OVS_open_vswitch", node));
const struct ovsrec_bridge_table *bridge_table =
Expand All @@ -4085,6 +4140,7 @@ static void init_physical_ctx(struct engine_node *node,
p_ctx->sbrec_port_binding_by_name = sbrec_port_binding_by_name;
p_ctx->sbrec_port_binding_by_datapath = sbrec_port_binding_by_datapath;
p_ctx->port_binding_table = port_binding_table;
p_ctx->ovs_interface_table = ovs_interface_table;
p_ctx->mc_group_table = multicast_group_table;
p_ctx->br_int = br_int;
p_ctx->chassis_table = chassis_table;
Expand All @@ -4098,6 +4154,9 @@ static void init_physical_ctx(struct engine_node *node,
p_ctx->patch_ofports = &non_vif_data->patch_ofports;
p_ctx->chassis_tunnels = &non_vif_data->chassis_tunnels;

struct controller_engine_ctx *ctrl_ctx = engine_get_context()->client_ctx;
p_ctx->if_mgr = ctrl_ctx->if_mgr;

pflow_output_get_debug(node, &p_ctx->debug);
}

Expand Down Expand Up @@ -4141,6 +4200,63 @@ en_pflow_output_run(struct engine_node *node, void *data)
engine_set_node_state(node, EN_UPDATED);
}

static bool
pflow_output_if_status_mgr_handler(struct engine_node *node,
void *data)
{
struct ed_type_pflow_output *pfo = data;
struct ed_type_runtime_data *rt_data =
engine_get_input_data("runtime_data", node);
struct ed_type_non_vif_data *non_vif_data =
engine_get_input_data("non_vif_data", node);
struct ed_type_if_status_mgr *if_mgr_data =
engine_get_input_data("if_status_mgr", node);

struct physical_ctx p_ctx;
init_physical_ctx(node, rt_data, non_vif_data, &p_ctx);

const struct ovsrec_interface *iface;
OVSREC_INTERFACE_TABLE_FOR_EACH_TRACKED (iface, if_mgr_data->iface_table) {
const char *iface_id = smap_get(&iface->external_ids, "iface-id");
if (!iface_id) {
continue;
}

const struct sbrec_port_binding *pb = lport_lookup_by_name(
p_ctx.sbrec_port_binding_by_name, iface_id);
if (!pb) {
continue;
}
if (pb->n_additional_chassis) {
/* Update flows for all ports in datapath. */
struct sbrec_port_binding *target =
sbrec_port_binding_index_init_row(
p_ctx.sbrec_port_binding_by_datapath);
sbrec_port_binding_index_set_datapath(target, pb->datapath);

const struct sbrec_port_binding *binding;
SBREC_PORT_BINDING_FOR_EACH_EQUAL (
binding, target, p_ctx.sbrec_port_binding_by_datapath) {
bool removed = sbrec_port_binding_is_deleted(binding);
if (!physical_handle_flows_for_lport(binding, removed, &p_ctx,
&pfo->flow_table)) {
return false;
}
}
sbrec_port_binding_index_destroy_row(target);
} else {
/* If any multichassis ports, update flows for the port. */
bool removed = sbrec_port_binding_is_deleted(pb);
if (!physical_handle_flows_for_lport(pb, removed, &p_ctx,
&pfo->flow_table)) {
return false;
}
}
engine_set_node_state(node, EN_UPDATED);
}
return true;
}

static bool
pflow_output_sb_port_binding_handler(struct engine_node *node,
void *data)
Expand Down Expand Up @@ -4628,6 +4744,7 @@ main(int argc, char *argv[])
ENGINE_NODE_WITH_CLEAR_TRACK_DATA(port_groups, "port_groups");
ENGINE_NODE(northd_options, "northd_options");
ENGINE_NODE(dhcp_options, "dhcp_options");
ENGINE_NODE(if_status_mgr, "if_status_mgr");
ENGINE_NODE_WITH_CLEAR_TRACK_DATA(lb_data, "lb_data");

#define SB_NODE(NAME, NAME_STR) ENGINE_NODE_SB(NAME, NAME_STR);
Expand Down Expand Up @@ -4666,6 +4783,9 @@ main(int argc, char *argv[])
engine_add_input(&en_non_vif_data, &en_ovs_interface,
non_vif_data_ovs_iface_handler);

engine_add_input(&en_if_status_mgr, &en_ovs_interface,
if_status_mgr_ovs_interface_handler);

/* Note: The order of inputs is important, all OVS interface changes must
* be handled before any ct_zone changes.
*/
Expand All @@ -4676,6 +4796,8 @@ main(int argc, char *argv[])
engine_add_input(&en_pflow_output, &en_sb_chassis,
pflow_lflow_output_sb_chassis_handler);

engine_add_input(&en_pflow_output, &en_if_status_mgr,
pflow_output_if_status_mgr_handler);
engine_add_input(&en_pflow_output, &en_sb_port_binding,
pflow_output_sb_port_binding_handler);
engine_add_input(&en_pflow_output, &en_sb_multicast_group,
Expand Down
9 changes: 9 additions & 0 deletions controller/ovsport.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,12 @@ maintain_interface_smap_column(
}
}
}

uint16_t
get_iface_mtu(const struct ovsrec_interface *iface)
{
if (!iface || !iface->n_mtu || iface->mtu[0] <= 0) {
return 0;
}
return (uint16_t) iface->mtu[0];
}
2 changes: 2 additions & 0 deletions controller/ovsport.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,6 @@ const struct ovsrec_port * ovsport_lookup_by_interface(
const struct ovsrec_port * ovsport_lookup_by_qos(
struct ovsdb_idl_index *, const struct ovsrec_qos *);

uint16_t get_iface_mtu(const struct ovsrec_interface *);

#endif /* lib/ovsport.h */
2 changes: 2 additions & 0 deletions controller/physical.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@ struct physical_ctx {
struct ovsdb_idl_index *sbrec_port_binding_by_name;
struct ovsdb_idl_index *sbrec_port_binding_by_datapath;
const struct sbrec_port_binding_table *port_binding_table;
const struct ovsrec_interface_table *ovs_interface_table;
const struct sbrec_multicast_group_table *mc_group_table;
const struct ovsrec_bridge *br_int;
const struct sbrec_chassis_table *chassis_table;
const struct sbrec_chassis *chassis;
const struct sset *active_tunnels;
const struct if_status_mgr *if_mgr;
struct hmap *local_datapaths;
struct sset *local_lports;
const struct simap *ct_zones;
Expand Down

0 comments on commit cdd8dea

Please sign in to comment.