Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,372 changes: 1,014 additions & 358 deletions controller/binding.c

Large diffs are not rendered by default.

66 changes: 44 additions & 22 deletions controller/binding.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
#define OVN_BINDING_H 1

#include <stdbool.h>
#include "openvswitch/hmap.h"
#include "openvswitch/uuid.h"
#include "openvswitch/list.h"

struct hmap;
struct ovsdb_idl;
Expand All @@ -31,31 +34,50 @@ struct ovsrec_open_vswitch_table;
struct sbrec_chassis;
struct sbrec_port_binding_table;
struct sset;
struct sbrec_port_binding;

struct binding_ctx_in {
struct ovsdb_idl_txn *ovnsb_idl_txn;
struct ovsdb_idl_txn *ovs_idl_txn;
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 ovsrec_port_table *port_table;
const struct ovsrec_qos_table *qos_table;
const struct sbrec_port_binding_table *port_binding_table;
const struct ovsrec_bridge *br_int;
const struct sbrec_chassis *chassis_rec;
const struct sset *active_tunnels;
const struct ovsrec_bridge_table *bridge_table;
const struct ovsrec_open_vswitch_table *ovs_table;
const struct ovsrec_interface_table *iface_table;
};

struct binding_ctx_out {
struct hmap *local_datapaths;
struct shash *local_bindings;
struct sset *local_lports;
struct sset *local_lport_ids;
struct sset *egress_ifaces;
struct smap *local_iface_ids;
struct hmap *tracked_dp_bindings;
bool *local_lports_changed;
};

void binding_register_ovs_idl(struct ovsdb_idl *);
void binding_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
struct ovsdb_idl_txn *ovs_idl_txn,
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 ovsrec_port_table *,
const struct ovsrec_qos_table *,
const struct sbrec_port_binding_table *,
const struct ovsrec_bridge *br_int,
const struct sbrec_chassis *,
const struct sset *active_tunnels,
const struct ovsrec_bridge_table *bridge_table,
const struct ovsrec_open_vswitch_table *ovs_table,
struct hmap *local_datapaths,
struct sset *local_lports, struct sset *local_lport_ids);
void binding_run(struct binding_ctx_in *, struct binding_ctx_out *);
bool binding_cleanup(struct ovsdb_idl_txn *ovnsb_idl_txn,
const struct sbrec_port_binding_table *,
const struct sbrec_chassis *);
bool binding_evaluate_port_binding_changes(
const struct sbrec_port_binding_table *,
const struct ovsrec_bridge *br_int,
const struct sbrec_chassis *,
struct sset *active_tunnels,
struct sset *local_lports);

void local_bindings_destroy(struct shash *local_bindings);
void binding_add_vport_to_local_bindings(
struct shash *local_bindings, const struct sbrec_port_binding *parent,
const struct sbrec_port_binding *vport);
bool binding_handle_ovs_interface_changes(struct binding_ctx_in *,
struct binding_ctx_out *,
bool *changed);
bool binding_handle_port_binding_changes(struct binding_ctx_in *,
struct binding_ctx_out *,
bool *changed);
void binding_tracked_dp_destroy(struct hmap *tracked_datapaths);
#endif /* controller/binding.h */
82 changes: 81 additions & 1 deletion controller/lflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ lflow_resource_destroy_lflow(struct lflow_resource_ref *lfrr,
/* Adds the logical flows from the Logical_Flow table to flow tables. */
static void
add_logical_flows(struct lflow_ctx_in *l_ctx_in,
struct lflow_ctx_out *l_ctx_out)
struct lflow_ctx_out *l_ctx_out)
{
const struct sbrec_logical_flow *lflow;

Expand Down Expand Up @@ -649,6 +649,8 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow,
int64_t dp_id = lflow->logical_datapath->tunnel_key;
char buf[16];
snprintf(buf, sizeof(buf), "%"PRId64"_%"PRId64, dp_id, port_id);
lflow_resource_add(l_ctx_out->lfrr, REF_TYPE_PORTBINDING, buf,
&lflow->header_.uuid);
if (!sset_contains(l_ctx_in->local_lport_ids, buf)) {
VLOG_DBG("lflow "UUID_FMT
" port %s in match is not local, skip",
Expand Down Expand Up @@ -847,3 +849,81 @@ lflow_destroy(void)
expr_symtab_destroy(&symtab);
shash_destroy(&symtab);
}

bool
lflow_evaluate_pb_changes(const struct sbrec_port_binding_table *pb_table)
{
const struct sbrec_port_binding *binding;
SBREC_PORT_BINDING_TABLE_FOR_EACH_TRACKED (binding, pb_table) {
if (!strcmp(binding->type, "remote")) {
return false;
}
}

return true;
}

bool
lflow_add_flows_for_datapath(const struct sbrec_datapath_binding *dp,
struct lflow_ctx_in *l_ctx_in,
struct lflow_ctx_out *l_ctx_out)
{
bool handled = true;
struct hmap dhcp_opts = HMAP_INITIALIZER(&dhcp_opts);
struct hmap dhcpv6_opts = HMAP_INITIALIZER(&dhcpv6_opts);
const struct sbrec_dhcp_options *dhcp_opt_row;
SBREC_DHCP_OPTIONS_TABLE_FOR_EACH (dhcp_opt_row,
l_ctx_in->dhcp_options_table) {
dhcp_opt_add(&dhcp_opts, dhcp_opt_row->name, dhcp_opt_row->code,
dhcp_opt_row->type);
}


const struct sbrec_dhcpv6_options *dhcpv6_opt_row;
SBREC_DHCPV6_OPTIONS_TABLE_FOR_EACH (dhcpv6_opt_row,
l_ctx_in->dhcpv6_options_table) {
dhcp_opt_add(&dhcpv6_opts, dhcpv6_opt_row->name, dhcpv6_opt_row->code,
dhcpv6_opt_row->type);
}

struct hmap nd_ra_opts = HMAP_INITIALIZER(&nd_ra_opts);
nd_ra_opts_init(&nd_ra_opts);

struct controller_event_options controller_event_opts;
controller_event_opts_init(&controller_event_opts);

struct sbrec_logical_flow *lf_row = sbrec_logical_flow_index_init_row(
l_ctx_in->sbrec_logical_flow_by_logical_datapath);
sbrec_logical_flow_index_set_logical_datapath(lf_row, dp);

const struct sbrec_logical_flow *lflow;
SBREC_LOGICAL_FLOW_FOR_EACH_EQUAL(
lflow, lf_row, l_ctx_in->sbrec_logical_flow_by_logical_datapath) {
if (!consider_logical_flow(lflow, &dhcp_opts, &dhcpv6_opts,
&nd_ra_opts, &controller_event_opts,
l_ctx_in, l_ctx_out)) {
handled = false;
break;
}
}

dhcp_opts_destroy(&dhcp_opts);
dhcp_opts_destroy(&dhcpv6_opts);
nd_ra_opts_destroy(&nd_ra_opts);
controller_event_opts_destroy(&controller_event_opts);
return handled;
}

bool
lflow_handle_flows_for_lport(const struct sbrec_port_binding *pb,
struct lflow_ctx_in *l_ctx_in,
struct lflow_ctx_out *l_ctx_out)
{
int64_t dp_id = pb->datapath->tunnel_key;
char pb_ref_name[16];
snprintf(pb_ref_name, sizeof(pb_ref_name), "%"PRId64"_%"PRId64,
dp_id, pb->tunnel_key);
bool changed = true;
return lflow_handle_changed_ref(REF_TYPE_PORTBINDING, pb_ref_name,
l_ctx_in, l_ctx_out, &changed);
}
14 changes: 13 additions & 1 deletion controller/lflow.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ struct sbrec_dhcp_options_table;
struct sbrec_dhcpv6_options_table;
struct sbrec_logical_flow_table;
struct sbrec_mac_binding_table;
struct sbrec_port_binding_table;
struct sbrec_datapath_binding;
struct sbrec_port_binding;
struct simap;
struct sset;
struct uuid;
Expand All @@ -72,7 +75,8 @@ struct uuid;

enum ref_type {
REF_TYPE_ADDRSET,
REF_TYPE_PORTGROUP
REF_TYPE_PORTGROUP,
REF_TYPE_PORTBINDING
};

/* Maintains the relationship for a pair of named resource and
Expand Down Expand Up @@ -117,6 +121,7 @@ void lflow_resource_clear(struct lflow_resource_ref *);

struct lflow_ctx_in {
struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath;
struct ovsdb_idl_index *sbrec_logical_flow_by_logical_datapath;
struct ovsdb_idl_index *sbrec_port_binding_by_name;
const struct sbrec_dhcp_options_table *dhcp_options_table;
const struct sbrec_dhcpv6_options_table *dhcpv6_options_table;
Expand Down Expand Up @@ -153,8 +158,15 @@ void lflow_handle_changed_neighbors(
const struct hmap *local_datapaths,
struct ovn_desired_flow_table *);

bool lflow_evaluate_pb_changes(const struct sbrec_port_binding_table *);
void lflow_destroy(void);

void lflow_expr_destroy(struct hmap *lflow_expr_cache);

bool lflow_add_flows_for_datapath(const struct sbrec_datapath_binding *,
struct lflow_ctx_in *,
struct lflow_ctx_out *);
bool lflow_handle_flows_for_lport(const struct sbrec_port_binding *,
struct lflow_ctx_in *,
struct lflow_ctx_out *);
#endif /* controller/lflow.h */
23 changes: 16 additions & 7 deletions controller/ofctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,14 +667,23 @@ ofctrl_check_and_add_flow(struct ovn_desired_flow_table *flow_table,

ovn_flow_log(f, "ofctrl_add_flow");

if (ovn_flow_lookup(&flow_table->match_flow_table, f, true)) {
if (log_duplicate_flow) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
if (!VLOG_DROP_DBG(&rl)) {
char *s = ovn_flow_to_string(f);
VLOG_DBG("dropping duplicate flow: %s", s);
free(s);
struct ovn_flow *existing_f =
ovn_flow_lookup(&flow_table->match_flow_table, f, true);
if (existing_f) {
if (ofpacts_equal(f->ofpacts, f->ofpacts_len,
existing_f->ofpacts, existing_f->ofpacts_len)) {
if (log_duplicate_flow) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
if (!VLOG_DROP_DBG(&rl)) {
char *s = ovn_flow_to_string(f);
VLOG_DBG("dropping duplicate flow: %s", s);
free(s);
}
}
} else {
free(existing_f->ofpacts);
existing_f->ofpacts = xmemdup(f->ofpacts, f->ofpacts_len);
existing_f->ofpacts_len = f->ofpacts_len;
}
ovn_flow_destroy(f);
return;
Expand Down
Loading