From patchwork Sat Nov 14 07:56:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1400235 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.137; helo=fraxinus.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CY73M72Cbz9sRK for ; Sat, 14 Nov 2020 18:57:19 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 66D1A876E9; Sat, 14 Nov 2020 07:57:18 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id C4F8krjBGh6I; Sat, 14 Nov 2020 07:57:13 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id EE6FC876DB; Sat, 14 Nov 2020 07:57:11 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id D3312C163C; Sat, 14 Nov 2020 07:57:11 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3B7F4C163C for ; Sat, 14 Nov 2020 07:57:10 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 2A406879B5 for ; Sat, 14 Nov 2020 07:57:10 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2NaexxuI21Cn for ; Sat, 14 Nov 2020 07:57:09 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by hemlock.osuosl.org (Postfix) with ESMTPS id A917A87984 for ; Sat, 14 Nov 2020 07:57:08 +0000 (UTC) X-Originating-IP: 78.45.89.65 Received: from im-t490s.redhat.com (ip-78-45-89-65.net.upcbroadband.cz [78.45.89.65]) (Authenticated sender: i.maximets@ovn.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id BAF36FF806; Sat, 14 Nov 2020 07:57:06 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Sat, 14 Nov 2020 08:56:51 +0100 Message-Id: <20201114075653.9142-5-i.maximets@ovn.org> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20201114075653.9142-1-i.maximets@ovn.org> References: <20201114075653.9142-1-i.maximets@ovn.org> MIME-Version: 1.0 Cc: Ilya Maximets Subject: [ovs-dev] [PATCH ovn 4/6] controller: Add support for Logical Datapath Groups. 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" Signed-off-by: Ilya Maximets --- controller/lflow.c | 105 +++++++++++++++++++++++------------- controller/lflow.h | 1 - controller/ovn-controller.c | 23 ++------ 3 files changed, 73 insertions(+), 56 deletions(-) diff --git a/controller/lflow.c b/controller/lflow.c index f631679c3..385fd4876 100644 --- a/controller/lflow.c +++ b/controller/lflow.c @@ -666,6 +666,7 @@ update_conj_id_ofs(uint32_t *conj_id_ofs, uint32_t n_conjs) static void add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, + const struct sbrec_datapath_binding *dp, struct hmap *matches, size_t conj_id_ofs, uint8_t ptable, uint8_t output_ptable, struct ofpbuf *ovnacts, @@ -676,7 +677,7 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, .sbrec_multicast_group_by_name_datapath = l_ctx_in->sbrec_multicast_group_by_name_datapath, .sbrec_port_binding_by_name = l_ctx_in->sbrec_port_binding_by_name, - .dp = lflow->logical_datapath + .dp = dp, }; /* Encode OVN logical actions into OpenFlow. */ @@ -686,7 +687,7 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, .lookup_port = lookup_port_cb, .tunnel_ofport = tunnel_ofport_cb, .aux = &aux, - .is_switch = datapath_is_switch(lflow->logical_datapath), + .is_switch = datapath_is_switch(dp), .group_table = l_ctx_out->group_table, .meter_table = l_ctx_out->meter_table, .lflow_uuid = lflow->header_.uuid, @@ -702,17 +703,16 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, struct expr_match *m; HMAP_FOR_EACH (m, hmap_node, matches) { - match_set_metadata(&m->match, - htonll(lflow->logical_datapath->tunnel_key)); + match_set_metadata(&m->match, htonll(dp->tunnel_key)); if (m->match.wc.masks.conj_id) { m->match.flow.conj_id += conj_id_ofs; } - if (datapath_is_switch(lflow->logical_datapath)) { + if (datapath_is_switch(dp)) { unsigned int reg_index = (ingress ? MFF_LOG_INPORT : MFF_LOG_OUTPORT) - MFF_REG0; int64_t port_id = m->match.flow.regs[reg_index]; if (port_id) { - int64_t dp_id = lflow->logical_datapath->tunnel_key; + int64_t dp_id = dp->tunnel_key; char buf[16]; get_unique_lport_key(dp_id, port_id, buf, sizeof(buf)); lflow_resource_add(l_ctx_out->lfrr, REF_TYPE_PORTBINDING, buf, @@ -761,6 +761,7 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, */ static struct expr * convert_match_to_expr(const struct sbrec_logical_flow *lflow, + const struct sbrec_datapath_binding *dp, struct expr *prereqs, const struct shash *addr_sets, const struct shash *port_groups, @@ -773,8 +774,7 @@ convert_match_to_expr(const struct sbrec_logical_flow *lflow, struct expr *e = expr_parse_string(lflow->match, &symtab, addr_sets, port_groups, &addr_sets_ref, - &port_groups_ref, - lflow->logical_datapath->tunnel_key, + &port_groups_ref, dp->tunnel_key, &error); const char *addr_set_name; SSET_FOR_EACH (addr_set_name, &addr_sets_ref) { @@ -812,23 +812,18 @@ convert_match_to_expr(const struct sbrec_logical_flow *lflow, } static bool -consider_logical_flow(const struct sbrec_logical_flow *lflow, - struct hmap *dhcp_opts, struct hmap *dhcpv6_opts, - struct hmap *nd_ra_opts, - struct controller_event_options *controller_event_opts, - struct lflow_ctx_in *l_ctx_in, - struct lflow_ctx_out *l_ctx_out) +consider_logical_flow__(const struct sbrec_logical_flow *lflow, + const struct sbrec_datapath_binding *dp, + struct hmap *dhcp_opts, struct hmap *dhcpv6_opts, + struct hmap *nd_ra_opts, + struct controller_event_options *controller_event_opts, + struct lflow_ctx_in *l_ctx_in, + struct lflow_ctx_out *l_ctx_out) { /* Determine translation of logical table IDs to physical table IDs. */ bool ingress = !strcmp(lflow->pipeline, "ingress"); - const struct sbrec_datapath_binding *ldp = lflow->logical_datapath; - if (!ldp) { - VLOG_DBG("lflow "UUID_FMT" has no datapath binding, skip", - UUID_ARGS(&lflow->header_.uuid)); - return true; - } - if (!get_local_datapath(l_ctx_in->local_datapaths, ldp->tunnel_key)) { + if (!get_local_datapath(l_ctx_in->local_datapaths, dp->tunnel_key)) { VLOG_DBG("lflow "UUID_FMT" is not for local datapath, skip", UUID_ARGS(&lflow->header_.uuid)); return true; @@ -877,7 +872,7 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, .sbrec_multicast_group_by_name_datapath = l_ctx_in->sbrec_multicast_group_by_name_datapath, .sbrec_port_binding_by_name = l_ctx_in->sbrec_port_binding_by_name, - .dp = lflow->logical_datapath + .dp = dp, }; struct condition_aux cond_aux = { .sbrec_port_binding_by_name = l_ctx_in->sbrec_port_binding_by_name, @@ -890,7 +885,7 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, struct expr *expr = NULL; if (!l_ctx_out->lflow_cache_map) { /* Caching is disabled. */ - expr = convert_match_to_expr(lflow, prereqs, l_ctx_in->addr_sets, + expr = convert_match_to_expr(lflow, dp, prereqs, l_ctx_in->addr_sets, l_ctx_in->port_groups, l_ctx_out->lfrr, NULL); if (!expr) { @@ -916,7 +911,7 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, return true; } - add_matches_to_flow_table(lflow, &matches, *l_ctx_out->conj_id_ofs, + add_matches_to_flow_table(lflow, dp, &matches, *l_ctx_out->conj_id_ofs, ptable, output_ptable, &ovnacts, ingress, l_ctx_in, l_ctx_out); @@ -933,7 +928,7 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, if (lc && lc->type == LCACHE_T_MATCHES) { /* 'matches' is cached. No need to do expr parsing. * Add matches to flow table and return. */ - add_matches_to_flow_table(lflow, lc->expr_matches, lc->conj_id_ofs, + add_matches_to_flow_table(lflow, dp, lc->expr_matches, lc->conj_id_ofs, ptable, output_ptable, &ovnacts, ingress, l_ctx_in, l_ctx_out); ovnacts_free(ovnacts.data, ovnacts.size); @@ -953,7 +948,7 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, bool pg_addr_set_ref = false; if (!expr) { - expr = convert_match_to_expr(lflow, prereqs, l_ctx_in->addr_sets, + expr = convert_match_to_expr(lflow, dp, prereqs, l_ctx_in->addr_sets, l_ctx_in->port_groups, l_ctx_out->lfrr, &pg_addr_set_ref); if (!expr) { @@ -1011,7 +1006,7 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, } /* Encode OVN logical actions into OpenFlow. */ - add_matches_to_flow_table(lflow, matches, lc->conj_id_ofs, + add_matches_to_flow_table(lflow, dp, matches, lc->conj_id_ofs, ptable, output_ptable, &ovnacts, ingress, l_ctx_in, l_ctx_out); ovnacts_free(ovnacts.data, ovnacts.size); @@ -1033,6 +1028,35 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow, return true; } +static bool +consider_logical_flow(const struct sbrec_logical_flow *lflow, + struct hmap *dhcp_opts, struct hmap *dhcpv6_opts, + struct hmap *nd_ra_opts, + struct controller_event_options *controller_event_opts, + struct lflow_ctx_in *l_ctx_in, + struct lflow_ctx_out *l_ctx_out) +{ + struct sbrec_logical_datapath_group *dp_group + = lflow->logical_datapath_group; + bool ret = true; + + if (!dp_group) { + VLOG_DBG("lflow "UUID_FMT" has no datapath binding, skip", + UUID_ARGS(&lflow->header_.uuid)); + return true; + } + + for (size_t i = 0; i < dp_group->n_datapaths; i++) { + if (!consider_logical_flow__(lflow, dp_group->datapaths[i], + dhcp_opts, dhcpv6_opts, nd_ra_opts, + controller_event_opts, + l_ctx_in, l_ctx_out)) { + ret = false; + } + } + return ret; +} + static void put_load(const uint8_t *data, size_t len, enum mf_field_id dst, int ofs, int n_bits, @@ -1235,22 +1259,29 @@ lflow_add_flows_for_datapath(const struct sbrec_datapath_binding *dp, 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)) { + SBREC_LOGICAL_FLOW_TABLE_FOR_EACH (lflow, l_ctx_in->logical_flow_table) { + struct sbrec_logical_datapath_group *dp_group + = lflow->logical_datapath_group; + bool found = false; + + if (dp_group) { + for (size_t i = 0; i < dp_group->n_datapaths; i++) { + if (dp_group->datapaths[i] == dp) { + found = true; + break; + } + } + } + if (found && !consider_logical_flow__(lflow, dp, &dhcp_opts, + &dhcpv6_opts, &nd_ra_opts, + &controller_event_opts, + l_ctx_in, l_ctx_out)) { handled = false; l_ctx_out->conj_id_overflow = true; break; } } - sbrec_logical_flow_index_destroy_row(lf_row); dhcp_opts_destroy(&dhcp_opts); dhcp_opts_destroy(&dhcpv6_opts); diff --git a/controller/lflow.h b/controller/lflow.h index 1251fb0f4..9baee7716 100644 --- a/controller/lflow.h +++ b/controller/lflow.h @@ -123,7 +123,6 @@ 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; diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index a06cae3cc..aa20091b8 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -153,7 +153,7 @@ update_sb_monitors(struct ovsdb_idl *ovnsb_idl, * a VIF on a particular logical switch, we immediately know to monitor all * the connected logical routers and logical switches. */ struct ovsdb_idl_condition pb = OVSDB_IDL_CONDITION_INIT(&pb); - struct ovsdb_idl_condition lf = OVSDB_IDL_CONDITION_INIT(&lf); + struct ovsdb_idl_condition ldpg = OVSDB_IDL_CONDITION_INIT(&ldpg); struct ovsdb_idl_condition mb = OVSDB_IDL_CONDITION_INIT(&mb); struct ovsdb_idl_condition mg = OVSDB_IDL_CONDITION_INIT(&mg); struct ovsdb_idl_condition dns = OVSDB_IDL_CONDITION_INIT(&dns); @@ -164,7 +164,7 @@ update_sb_monitors(struct ovsdb_idl *ovnsb_idl, if (monitor_all) { ovsdb_idl_condition_add_clause_true(&pb); - ovsdb_idl_condition_add_clause_true(&lf); + ovsdb_idl_condition_add_clause_true(&ldpg); ovsdb_idl_condition_add_clause_true(&mb); ovsdb_idl_condition_add_clause_true(&mg); ovsdb_idl_condition_add_clause_true(&dns); @@ -226,8 +226,8 @@ update_sb_monitors(struct ovsdb_idl *ovnsb_idl, struct uuid *uuid = CONST_CAST(struct uuid *, &ld->datapath->header_.uuid); sbrec_port_binding_add_clause_datapath(&pb, OVSDB_F_EQ, uuid); - sbrec_logical_flow_add_clause_logical_datapath(&lf, OVSDB_F_EQ, - uuid); + sbrec_logical_datapath_group_add_clause_datapaths( + &ldpg, OVSDB_F_INCLUDES, &uuid, 1); sbrec_mac_binding_add_clause_datapath(&mb, OVSDB_F_EQ, uuid); sbrec_multicast_group_add_clause_datapath(&mg, OVSDB_F_EQ, uuid); sbrec_dns_add_clause_datapaths(&dns, OVSDB_F_INCLUDES, &uuid, 1); @@ -238,7 +238,7 @@ update_sb_monitors(struct ovsdb_idl *ovnsb_idl, out: sbrec_port_binding_set_condition(ovnsb_idl, &pb); - sbrec_logical_flow_set_condition(ovnsb_idl, &lf); + sbrec_logical_datapath_group_set_condition(ovnsb_idl, &ldpg); sbrec_mac_binding_set_condition(ovnsb_idl, &mb); sbrec_multicast_group_set_condition(ovnsb_idl, &mg); sbrec_dns_set_condition(ovnsb_idl, &dns); @@ -247,7 +247,6 @@ out: sbrec_igmp_group_set_condition(ovnsb_idl, &igmp); sbrec_chassis_private_set_condition(ovnsb_idl, &chprv); ovsdb_idl_condition_destroy(&pb); - ovsdb_idl_condition_destroy(&lf); ovsdb_idl_condition_destroy(&mb); ovsdb_idl_condition_destroy(&mg); ovsdb_idl_condition_destroy(&dns); @@ -1652,11 +1651,6 @@ static void init_lflow_ctx(struct engine_node *node, engine_get_input("SB_port_binding", node), "name"); - struct ovsdb_idl_index *sbrec_logical_flow_by_dp = - engine_ovsdb_node_get_index( - engine_get_input("SB_logical_flow", node), - "logical_datapath"); - struct ovsdb_idl_index *sbrec_mc_group_by_name_dp = engine_ovsdb_node_get_index( engine_get_input("SB_multicast_group", node), @@ -1704,8 +1698,6 @@ static void init_lflow_ctx(struct engine_node *node, l_ctx_in->sbrec_multicast_group_by_name_datapath = sbrec_mc_group_by_name_dp; - l_ctx_in->sbrec_logical_flow_by_logical_datapath = - sbrec_logical_flow_by_dp; l_ctx_in->sbrec_port_binding_by_name = sbrec_port_binding_by_name; l_ctx_in->dhcp_options_table = dhcp_table; l_ctx_in->dhcpv6_options_table = dhcpv6_table; @@ -2188,9 +2180,6 @@ main(int argc, char *argv[]) = chassis_private_index_create(ovnsb_idl_loop.idl); struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath = mcast_group_index_create(ovnsb_idl_loop.idl); - struct ovsdb_idl_index *sbrec_logical_flow_by_logical_datapath - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, - &sbrec_logical_flow_col_logical_datapath); struct ovsdb_idl_index *sbrec_port_binding_by_name = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, &sbrec_port_binding_col_logical_port); @@ -2362,8 +2351,6 @@ main(int argc, char *argv[]) engine_ovsdb_node_add_index(&en_sb_chassis, "name", sbrec_chassis_by_name); engine_ovsdb_node_add_index(&en_sb_multicast_group, "name_datapath", sbrec_multicast_group_by_name_datapath); - engine_ovsdb_node_add_index(&en_sb_logical_flow, "logical_datapath", - sbrec_logical_flow_by_logical_datapath); engine_ovsdb_node_add_index(&en_sb_port_binding, "name", sbrec_port_binding_by_name); engine_ovsdb_node_add_index(&en_sb_port_binding, "key",