From patchwork Fri Feb 5 07:00:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Numan Siddique X-Patchwork-Id: 1436460 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DX5sV6h48z9sWg for ; Fri, 5 Feb 2021 18:00:30 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 240D12E109; Fri, 5 Feb 2021 07:00:28 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id XBDJdMtOSC5d; Fri, 5 Feb 2021 07:00:17 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 5AC2F20397; Fri, 5 Feb 2021 07:00:17 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3BD07C08A1; Fri, 5 Feb 2021 07:00:17 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 336B3C08A1 for ; Fri, 5 Feb 2021 07:00:15 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 1F04A86F90 for ; Fri, 5 Feb 2021 07:00:15 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id D8Ga0yW7rV34 for ; Fri, 5 Feb 2021 07:00:13 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by whitealder.osuosl.org (Postfix) with ESMTPS id AFC9886EB0 for ; Fri, 5 Feb 2021 07:00:12 +0000 (UTC) X-Originating-IP: 115.99.223.251 Received: from nusiddiq.home.org.com (unknown [115.99.223.251]) (Authenticated sender: numans@ovn.org) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id EF131E000E; Fri, 5 Feb 2021 07:00:07 +0000 (UTC) From: numans@ovn.org To: dev@openvswitch.org Date: Fri, 5 Feb 2021 12:30:04 +0530 Message-Id: <20210205070004.40218-1-numans@ovn.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210205065622.39226-1-numans@ovn.org> References: <20210205065622.39226-1-numans@ovn.org> MIME-Version: 1.0 Subject: [ovs-dev] [PATCH ovn 4/6] controller: MAC learning: Add OF rules for the FDB entries. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Numan Siddique This patch adds the OF rules in table 71 and 72 to support 'get_fdb' and 'lookup_fdb' actions. Signed-off-by: Numan Siddique --- controller/lflow.c | 103 ++++++++++++++++++++++++++++++++++++ controller/lflow.h | 2 + controller/ovn-controller.c | 27 +++++++++- 3 files changed, 131 insertions(+), 1 deletion(-) diff --git a/controller/lflow.c b/controller/lflow.c index baf6932d51..6c74fe9c85 100644 --- a/controller/lflow.c +++ b/controller/lflow.c @@ -1080,6 +1080,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, @@ -1419,6 +1431,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. */ @@ -1446,6 +1513,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); } void @@ -1597,3 +1666,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; +} diff --git a/controller/lflow.h b/controller/lflow.h index d790d518d8..9f8bed4938 100644 --- a/controller/lflow.h +++ b/controller/lflow.h @@ -138,6 +138,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; @@ -169,6 +170,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); void lflow_cache_init(struct hmap *); diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index 42858d60fa..32f3f69324 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -923,7 +923,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, @@ -1854,6 +1855,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)); @@ -1891,6 +1896,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; @@ -2331,6 +2337,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; @@ -2592,6 +2615,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);