Skip to content

Commit

Permalink
controller: MAC learning: Add OF rules for the FDB entries.
Browse files Browse the repository at this point in the history
This patch adds the OF rules in table 71 and 72 to support
'get_fdb' and 'lookup_fdb' actions.

Acked-by: Mark Michelson <mmichels@redhat.com>
Signed-off-by: Numan Siddique <numans@ovn.org>
  • Loading branch information
numansiddique committed Feb 20, 2021
1 parent f819ce8 commit 94bab31
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 1 deletion.
103 changes: 103 additions & 0 deletions controller/lflow.c
Expand Up @@ -964,6 +964,18 @@ put_load(const uint8_t *data, size_t len,
bitwise_one(ofpact_set_field_mask(sf), sf->field->n_bytes, ofs, n_bits);
}

static void
put_load64(uint64_t value, enum mf_field_id dst, int ofs, int n_bits,
struct ofpbuf *ofpacts)
{
struct ofpact_set_field *sf = ofpact_put_set_field(ofpacts,
mf_from_id(dst), NULL,
NULL);
ovs_be64 n_value = htonll(value);
bitwise_copy(&n_value, 8, 0, sf->value, sf->field->n_bytes, ofs, n_bits);
bitwise_one(ofpact_set_field_mask(sf), sf->field->n_bytes, ofs, n_bits);
}

static void
consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct hmap *local_datapaths,
Expand Down Expand Up @@ -1461,6 +1473,61 @@ lflow_handle_changed_neighbors(
}
}

static void
consider_fdb_flows(const struct sbrec_fdb *fdb,
const struct hmap *local_datapaths,
struct ovn_desired_flow_table *flow_table)
{
if (!get_local_datapath(local_datapaths, fdb->dp_key)) {
return;
}

struct eth_addr mac;
if (!eth_addr_from_string(fdb->mac, &mac)) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
VLOG_WARN_RL(&rl, "bad 'mac' %s", fdb->mac);
return;
}

struct match match = MATCH_CATCHALL_INITIALIZER;
match_set_metadata(&match, htonll(fdb->dp_key));
match_set_dl_dst(&match, mac);

uint64_t stub[1024 / 8];
struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub);
put_load64(fdb->port_key, MFF_LOG_OUTPORT, 0, 32, &ofpacts);
ofctrl_add_flow(flow_table, OFTABLE_GET_FDB, 100,
fdb->header_.uuid.parts[0], &match, &ofpacts,
&fdb->header_.uuid);
ofpbuf_clear(&ofpacts);

uint8_t value = 1;
put_load(&value, sizeof value, MFF_LOG_FLAGS,
MLF_LOOKUP_FDB_BIT, 1, &ofpacts);

struct match lookup_match = MATCH_CATCHALL_INITIALIZER;
match_set_metadata(&lookup_match, htonll(fdb->dp_key));
match_set_dl_src(&lookup_match, mac);
match_set_reg(&lookup_match, MFF_LOG_INPORT - MFF_REG0, fdb->port_key);
ofctrl_add_flow(flow_table, OFTABLE_LOOKUP_FDB, 100,
fdb->header_.uuid.parts[0], &lookup_match, &ofpacts,
&fdb->header_.uuid);
ofpbuf_uninit(&ofpacts);
}

/* Adds an OpenFlow flow to flow tables for each MAC binding in the OVN
* southbound database. */
static void
add_fdb_flows(const struct sbrec_fdb_table *fdb_table,
const struct hmap *local_datapaths,
struct ovn_desired_flow_table *flow_table)
{
const struct sbrec_fdb *fdb;
SBREC_FDB_TABLE_FOR_EACH (fdb, fdb_table) {
consider_fdb_flows(fdb, local_datapaths, flow_table);
}
}


/* Translates logical flows in the Logical_Flow table in the OVN_SB database
* into OpenFlow flows. See ovn-architecture(7) for more information. */
Expand All @@ -1475,6 +1542,8 @@ lflow_run(struct lflow_ctx_in *l_ctx_in, struct lflow_ctx_out *l_ctx_out)
l_ctx_out->flow_table);
add_lb_hairpin_flows(l_ctx_in->lb_table, l_ctx_in->local_datapaths,
l_ctx_out->flow_table);
add_fdb_flows(l_ctx_in->fdb_table, l_ctx_in->local_datapaths,
l_ctx_out->flow_table);
}

/* Should be called at every ovn-controller iteration before IDL tracked
Expand Down Expand Up @@ -1643,3 +1712,37 @@ lflow_handle_changed_lbs(struct lflow_ctx_in *l_ctx_in,

return true;
}

bool
lflow_handle_changed_fdbs(struct lflow_ctx_in *l_ctx_in,
struct lflow_ctx_out *l_ctx_out)
{
const struct sbrec_fdb *fdb;

SBREC_FDB_TABLE_FOR_EACH_TRACKED (fdb, l_ctx_in->fdb_table) {
if (sbrec_fdb_is_deleted(fdb)) {
VLOG_DBG("Remove fdb flows for deleted fdb "UUID_FMT,
UUID_ARGS(&fdb->header_.uuid));
ofctrl_remove_flows(l_ctx_out->flow_table, &fdb->header_.uuid);
}
}

SBREC_FDB_TABLE_FOR_EACH_TRACKED (fdb, l_ctx_in->fdb_table) {
if (sbrec_fdb_is_deleted(fdb)) {
continue;
}

if (!sbrec_fdb_is_new(fdb)) {
VLOG_DBG("Remove fdb flows for updated fdb "UUID_FMT,
UUID_ARGS(&fdb->header_.uuid));
ofctrl_remove_flows(l_ctx_out->flow_table, &fdb->header_.uuid);
}

VLOG_DBG("Add fdb flows for fdb "UUID_FMT,
UUID_ARGS(&fdb->header_.uuid));
consider_fdb_flows(fdb, l_ctx_in->local_datapaths,
l_ctx_out->flow_table);
}

return true;
}
2 changes: 2 additions & 0 deletions controller/lflow.h
Expand Up @@ -139,6 +139,7 @@ struct lflow_ctx_in {
const struct sbrec_logical_flow_table *logical_flow_table;
const struct sbrec_logical_dp_group_table *logical_dp_group_table;
const struct sbrec_multicast_group_table *mc_group_table;
const struct sbrec_fdb_table *fdb_table;
const struct sbrec_chassis *chassis;
const struct sbrec_load_balancer_table *lb_table;
const struct hmap *local_datapaths;
Expand Down Expand Up @@ -172,6 +173,7 @@ void lflow_handle_changed_neighbors(
const struct hmap *local_datapaths,
struct ovn_desired_flow_table *);
bool lflow_handle_changed_lbs(struct lflow_ctx_in *, struct lflow_ctx_out *);
bool lflow_handle_changed_fdbs(struct lflow_ctx_in *, struct lflow_ctx_out *);
void lflow_destroy(void);

bool lflow_add_flows_for_datapath(const struct sbrec_datapath_binding *,
Expand Down
27 changes: 26 additions & 1 deletion controller/ovn-controller.c
Expand Up @@ -953,7 +953,8 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl)
SB_NODE(dhcp_options, "dhcp_options") \
SB_NODE(dhcpv6_options, "dhcpv6_options") \
SB_NODE(dns, "dns") \
SB_NODE(load_balancer, "load_balancer")
SB_NODE(load_balancer, "load_balancer") \
SB_NODE(fdb, "fdb")

enum sb_engine_node {
#define SB_NODE(NAME, NAME_STR) SB_##NAME,
Expand Down Expand Up @@ -1879,6 +1880,10 @@ static void init_lflow_ctx(struct engine_node *node,
(struct sbrec_load_balancer_table *)EN_OVSDB_GET(
engine_get_input("SB_load_balancer", node));

struct sbrec_fdb_table *fdb_table =
(struct sbrec_fdb_table *)EN_OVSDB_GET(
engine_get_input("SB_fdb", node));

struct ovsrec_open_vswitch_table *ovs_table =
(struct ovsrec_open_vswitch_table *)EN_OVSDB_GET(
engine_get_input("OVS_open_vswitch", node));
Expand Down Expand Up @@ -1916,6 +1921,7 @@ static void init_lflow_ctx(struct engine_node *node,
l_ctx_in->logical_flow_table = logical_flow_table;
l_ctx_in->logical_dp_group_table = logical_dp_group_table;
l_ctx_in->mc_group_table = multicast_group_table;
l_ctx_in->fdb_table = fdb_table,
l_ctx_in->chassis = chassis;
l_ctx_in->lb_table = lb_table;
l_ctx_in->local_datapaths = &rt_data->local_datapaths;
Expand Down Expand Up @@ -2346,6 +2352,23 @@ flow_output_sb_load_balancer_handler(struct engine_node *node, void *data)
return handled;
}

static bool
flow_output_sb_fdb_handler(struct engine_node *node, void *data)
{
struct ed_type_runtime_data *rt_data =
engine_get_input_data("runtime_data", node);

struct ed_type_flow_output *fo = data;
struct lflow_ctx_in l_ctx_in;
struct lflow_ctx_out l_ctx_out;
init_lflow_ctx(node, rt_data, fo, &l_ctx_in, &l_ctx_out);

bool handled = lflow_handle_changed_fdbs(&l_ctx_in, &l_ctx_out);

engine_set_node_state(node, EN_UPDATED);
return handled;
}

struct ovn_controller_exit_args {
bool *exiting;
bool *restart;
Expand Down Expand Up @@ -2607,6 +2630,8 @@ main(int argc, char *argv[])
engine_add_input(&en_flow_output, &en_sb_dns, NULL);
engine_add_input(&en_flow_output, &en_sb_load_balancer,
flow_output_sb_load_balancer_handler);
engine_add_input(&en_flow_output, &en_sb_fdb,
flow_output_sb_fdb_handler);

engine_add_input(&en_ct_zones, &en_ovs_open_vswitch, NULL);
engine_add_input(&en_ct_zones, &en_ovs_bridge, NULL);
Expand Down

0 comments on commit 94bab31

Please sign in to comment.