From patchwork Mon Jun 26 15:54:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Richardson X-Patchwork-Id: 780771 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wxDFr6Rb1z9s9Y for ; Tue, 27 Jun 2017 01:57:04 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 235A7B76; Mon, 26 Jun 2017 15:54:54 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id E6A99B5A for ; Mon, 26 Jun 2017 15:54:50 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 8FCA03D7 for ; Mon, 26 Jun 2017 15:54:47 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0FB0A4E357 for ; Mon, 26 Jun 2017 15:54:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 0FB0A4E357 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=lrichard@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 0FB0A4E357 Received: from thinkcentre.localdomain.com (ovpn-121-28.rdu2.redhat.com [10.10.121.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id B12FA1755D for ; Mon, 26 Jun 2017 15:54:46 +0000 (UTC) From: Lance Richardson To: dev@openvswitch.org Date: Mon, 26 Jun 2017 11:54:43 -0400 Message-Id: <20170626155444.29180-3-lrichard@redhat.com> In-Reply-To: <20170626155444.29180-1-lrichard@redhat.com> References: <20170626155444.29180-1-lrichard@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Mon, 26 Jun 2017 15:54:47 +0000 (UTC) X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [RFC 2/3] ovn-controller: use idl indexes for logical port table X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Use IDL index for logical port table lookups, avoiding the overhead of creating/destroying an index hmap for each iteration of the ovn-controller main loop. Signed-off-by: Lance Richardson --- ovn/controller/binding.c | 27 ++++--- ovn/controller/binding.h | 3 +- ovn/controller/lflow.c | 31 ++++---- ovn/controller/lflow.h | 2 - ovn/controller/lport.c | 154 +++++++++++++++++++++------------------- ovn/controller/lport.h | 18 +---- ovn/controller/ovn-controller.c | 31 ++++++-- ovn/controller/physical.c | 14 ++-- ovn/controller/physical.h | 2 +- ovn/controller/pinctrl.c | 72 +++++++++---------- ovn/controller/pinctrl.h | 2 +- 11 files changed, 178 insertions(+), 178 deletions(-) diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c index bb76608..f76e692 100644 --- a/ovn/controller/binding.c +++ b/ovn/controller/binding.c @@ -106,8 +106,8 @@ get_local_iface_ids(const struct ovsrec_bridge *br_int, } static void -add_local_datapath__(const struct ldatapath_index *ldatapaths, - const struct lport_index *lports, +add_local_datapath__(struct controller_ctx *ctx, + const struct ldatapath_index *ldatapaths, const struct sbrec_datapath_binding *datapath, bool has_local_l3gateway, int depth, struct hmap *local_datapaths) @@ -143,9 +143,9 @@ add_local_datapath__(const struct ldatapath_index *ldatapaths, const char *peer_name = smap_get(&pb->options, "peer"); if (peer_name) { const struct sbrec_port_binding *peer = lport_lookup_by_name( - lports, peer_name); + ctx->ovnsb_idl, peer_name); if (peer && peer->datapath) { - add_local_datapath__(ldatapaths, lports, peer->datapath, + add_local_datapath__(ctx, ldatapaths, peer->datapath, false, depth + 1, local_datapaths); } } @@ -154,12 +154,12 @@ add_local_datapath__(const struct ldatapath_index *ldatapaths, } static void -add_local_datapath(const struct ldatapath_index *ldatapaths, - const struct lport_index *lports, +add_local_datapath(struct controller_ctx *ctx, + const struct ldatapath_index *ldatapaths, const struct sbrec_datapath_binding *datapath, bool has_local_l3gateway, struct hmap *local_datapaths) { - add_local_datapath__(ldatapaths, lports, datapath, has_local_l3gateway, 0, + add_local_datapath__(ctx, ldatapaths, datapath, has_local_l3gateway, 0, local_datapaths); } @@ -356,7 +356,6 @@ setup_qos(const char *egress_iface, struct hmap *queue_map) static void consider_local_datapath(struct controller_ctx *ctx, const struct ldatapath_index *ldatapaths, - const struct lport_index *lports, const struct sbrec_chassis *chassis_rec, const struct sbrec_port_binding *binding_rec, struct hmap *qos_map, @@ -375,7 +374,7 @@ consider_local_datapath(struct controller_ctx *ctx, /* Add child logical port to the set of all local ports. */ sset_add(local_lports, binding_rec->logical_port); } - add_local_datapath(ldatapaths, lports, binding_rec->datapath, + add_local_datapath(ctx, ldatapaths, binding_rec->datapath, false, local_datapaths); if (iface_rec && qos_map && ctx->ovs_idl_txn) { get_qos_params(binding_rec, qos_map); @@ -390,7 +389,7 @@ consider_local_datapath(struct controller_ctx *ctx, our_chassis = chassis_id && !strcmp(chassis_id, chassis_rec->name); if (our_chassis) { sset_add(local_lports, binding_rec->logical_port); - add_local_datapath(ldatapaths, lports, binding_rec->datapath, + add_local_datapath(ctx, ldatapaths, binding_rec->datapath, false, local_datapaths); } } else if (!strcmp(binding_rec->type, "chassisredirect")) { @@ -398,7 +397,7 @@ consider_local_datapath(struct controller_ctx *ctx, "redirect-chassis"); our_chassis = chassis_id && !strcmp(chassis_id, chassis_rec->name); if (our_chassis) { - add_local_datapath(ldatapaths, lports, binding_rec->datapath, + add_local_datapath(ctx, ldatapaths, binding_rec->datapath, false, local_datapaths); } } else if (!strcmp(binding_rec->type, "l3gateway")) { @@ -406,7 +405,7 @@ consider_local_datapath(struct controller_ctx *ctx, "l3gateway-chassis"); our_chassis = chassis_id && !strcmp(chassis_id, chassis_rec->name); if (our_chassis) { - add_local_datapath(ldatapaths, lports, binding_rec->datapath, + add_local_datapath(ctx, ldatapaths, binding_rec->datapath, true, local_datapaths); } } else if (!strcmp(binding_rec->type, "localnet")) { @@ -446,7 +445,7 @@ void binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, const struct sbrec_chassis *chassis_rec, const struct ldatapath_index *ldatapaths, - const struct lport_index *lports, struct hmap *local_datapaths, + struct hmap *local_datapaths, struct sset *local_lports) { if (!chassis_rec) { @@ -468,7 +467,7 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, * chassis and update the binding accordingly. This includes both * directly connected logical ports and children of those ports. */ SBREC_PORT_BINDING_FOR_EACH(binding_rec, ctx->ovnsb_idl) { - consider_local_datapath(ctx, ldatapaths, lports, + consider_local_datapath(ctx, ldatapaths, chassis_rec, binding_rec, sset_is_empty(&egress_ifaces) ? NULL : &qos_map, local_datapaths, &lport_to_iface, diff --git a/ovn/controller/binding.h b/ovn/controller/binding.h index 3bfa7d1..26ca5ab 100644 --- a/ovn/controller/binding.h +++ b/ovn/controller/binding.h @@ -22,7 +22,6 @@ struct controller_ctx; struct hmap; struct ldatapath_index; -struct lport_index; struct ovsdb_idl; struct ovsrec_bridge; struct sbrec_chassis; @@ -31,7 +30,7 @@ struct sset; void binding_register_ovs_idl(struct ovsdb_idl *); void binding_run(struct controller_ctx *, const struct ovsrec_bridge *br_int, const struct sbrec_chassis *, const struct ldatapath_index *, - const struct lport_index *, struct hmap *local_datapaths, + struct hmap *local_datapaths, struct sset *all_lports); bool binding_cleanup(struct controller_ctx *, const struct sbrec_chassis *); diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index 56a7c02..27338ce 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -46,17 +46,15 @@ lflow_init(void) struct lookup_port_aux { struct ovsdb_idl *ovnsb_idl; - const struct lport_index *lports; const struct sbrec_datapath_binding *dp; }; struct condition_aux { - const struct lport_index *lports; + struct ovsdb_idl *ovnsb_idl; const struct sbrec_chassis *chassis; }; static void consider_logical_flow(struct controller_ctx *ctx, - const struct lport_index *lports, const struct sbrec_logical_flow *lflow, const struct hmap *local_datapaths, struct group_table *group_table, @@ -73,7 +71,7 @@ lookup_port_cb(const void *aux_, const char *port_name, unsigned int *portp) const struct lookup_port_aux *aux = aux_; const struct sbrec_port_binding *pb - = lport_lookup_by_name(aux->lports, port_name); + = lport_lookup_by_name(aux->ovnsb_idl, port_name); if (pb && pb->datapath == aux->dp) { *portp = pb->tunnel_key; return true; @@ -95,7 +93,7 @@ is_chassis_resident_cb(const void *c_aux_, const char *port_name) const struct condition_aux *c_aux = c_aux_; const struct sbrec_port_binding *pb - = lport_lookup_by_name(c_aux->lports, port_name); + = lport_lookup_by_name(c_aux->ovnsb_idl, port_name); return pb && pb->chassis && pb->chassis == c_aux->chassis; } @@ -117,7 +115,7 @@ is_gateway_router(const struct sbrec_datapath_binding *ldp, /* Adds the logical flows from the Logical_Flow table to flow tables. */ static void -add_logical_flows(struct controller_ctx *ctx, const struct lport_index *lports, +add_logical_flows(struct controller_ctx *ctx, const struct hmap *local_datapaths, struct group_table *group_table, const struct sbrec_chassis *chassis, @@ -143,7 +141,7 @@ add_logical_flows(struct controller_ctx *ctx, const struct lport_index *lports, } SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) { - consider_logical_flow(ctx, lports, lflow, local_datapaths, + consider_logical_flow(ctx, lflow, local_datapaths, group_table, chassis, &dhcp_opts, &dhcpv6_opts, &conj_id_ofs, addr_sets, flow_table); @@ -155,7 +153,6 @@ add_logical_flows(struct controller_ctx *ctx, const struct lport_index *lports, static void consider_logical_flow(struct controller_ctx *ctx, - const struct lport_index *lports, const struct sbrec_logical_flow *lflow, const struct hmap *local_datapaths, struct group_table *group_table, @@ -218,7 +215,6 @@ consider_logical_flow(struct controller_ctx *ctx, uint64_t ofpacts_stub[1024 / 8]; struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub); struct lookup_port_aux aux = { - .lports = lports, .ovnsb_idl = ctx->ovnsb_idl, .dp = lflow->logical_datapath }; @@ -261,7 +257,7 @@ consider_logical_flow(struct controller_ctx *ctx, return; } - struct condition_aux cond_aux = { lports, chassis }; + struct condition_aux cond_aux = { ctx->ovnsb_idl, chassis }; expr = expr_simplify(expr, is_chassis_resident_cb, &cond_aux); expr = expr_normalize(expr); uint32_t n_conjs = expr_to_matches(expr, lookup_port_cb, &aux, @@ -318,12 +314,12 @@ put_load(const uint8_t *data, size_t len, } static void -consider_neighbor_flow(const struct lport_index *lports, +consider_neighbor_flow(struct controller_ctx *ctx, const struct sbrec_mac_binding *b, struct hmap *flow_table) { const struct sbrec_port_binding *pb - = lport_lookup_by_name(lports, b->logical_port); + = lport_lookup_by_name(ctx->ovnsb_idl, b->logical_port); if (!pb) { return; } @@ -367,16 +363,14 @@ consider_neighbor_flow(const struct lport_index *lports, } /* Adds an OpenFlow flow to flow tables for each MAC binding in the OVN - * southbound database, using 'lports' to resolve logical port names to - * numbers. */ + * southbound database. */ static void add_neighbor_flows(struct controller_ctx *ctx, - const struct lport_index *lports, struct hmap *flow_table) { const struct sbrec_mac_binding *b; SBREC_MAC_BINDING_FOR_EACH (b, ctx->ovnsb_idl) { - consider_neighbor_flow(lports, b, flow_table); + consider_neighbor_flow(ctx, b, flow_table); } } @@ -385,15 +379,14 @@ add_neighbor_flows(struct controller_ctx *ctx, void lflow_run(struct controller_ctx *ctx, const struct sbrec_chassis *chassis, - const struct lport_index *lports, const struct hmap *local_datapaths, struct group_table *group_table, const struct shash *addr_sets, struct hmap *flow_table) { - add_logical_flows(ctx, lports, local_datapaths, group_table, + add_logical_flows(ctx, local_datapaths, group_table, chassis, addr_sets, flow_table); - add_neighbor_flows(ctx, lports, flow_table); + add_neighbor_flows(ctx, flow_table); } void diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index 60d86cd..a2ea042 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -38,7 +38,6 @@ struct controller_ctx; struct group_table; struct hmap; -struct lport_index; struct sbrec_chassis; struct simap; struct uuid; @@ -63,7 +62,6 @@ struct uuid; void lflow_init(void); void lflow_run(struct controller_ctx *, const struct sbrec_chassis *chassis, - const struct lport_index *, const struct hmap *local_datapaths, struct group_table *group_table, const struct shash *addr_sets, diff --git a/ovn/controller/lport.c b/ovn/controller/lport.c index 07173a9..aed6389 100644 --- a/ovn/controller/lport.c +++ b/ovn/controller/lport.c @@ -22,6 +22,9 @@ VLOG_DEFINE_THIS_MODULE(lport); +static struct ovsdb_idl_index_cursor lport_by_name_cursor; +static struct ovsdb_idl_index_cursor lport_by_key_cursor; +static struct ovsdb_idl_index_cursor dpath_by_key_cursor; static struct ovsdb_idl_index_cursor mc_grp_by_dp_name_cursor; static struct ldatapath *ldatapath_lookup_by_key__( @@ -86,97 +89,88 @@ const struct ldatapath *ldatapath_lookup_by_key( return ldatapath_lookup_by_key__(ldatapaths, dp_key); } -/* A logical port. */ -struct lport { - struct hmap_node name_node; /* Index by name. */ - struct hmap_node key_node; /* Index by (dp_key, port_key). */ - const struct sbrec_port_binding *pb; -}; -void -lport_index_init(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl) +/* Finds and returns the port binding record with the given 'name', + * or NULL if no such port binding exists. */ +const struct sbrec_port_binding * +lport_lookup_by_name(struct ovsdb_idl *idl, const char *name) { - hmap_init(&lports->by_name); - hmap_init(&lports->by_key); + struct sbrec_port_binding *value; + const struct sbrec_port_binding *pb, *retval = NULL; - const struct sbrec_port_binding *pb; - SBREC_PORT_BINDING_FOR_EACH (pb, ovnsb_idl) { - if (!pb->datapath) { - continue; - } + /* Build key for an indexed lookup. */ + value = sbrec_port_binding_index_init_row(idl, &sbrec_table_port_binding); + sbrec_port_binding_index_set_logical_port(value, xstrdup(name)); + + /* Find an entry with matching logical port name. Since this column is + * declared to be an index in the OVN_Southbound schema, the first match + * (if any) will be the only match. */ + SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, &lport_by_name_cursor, value) { + retval = pb; + break; + } - if (lport_lookup_by_name(lports, pb->logical_port)) { - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); - VLOG_WARN_RL(&rl, "duplicate logical port name '%s'", - pb->logical_port); - continue; - } - if (lport_lookup_by_key(lports, pb->datapath->tunnel_key, - pb->tunnel_key)) { - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); - VLOG_WARN_RL(&rl, "duplicate logical port %"PRId64" in logical " - "datapath %"PRId64, - pb->tunnel_key, pb->datapath->tunnel_key); - continue; - } + sbrec_port_binding_index_destroy_row(value); - struct lport *p = xmalloc(sizeof *p); - hmap_insert(&lports->by_name, &p->name_node, - hash_string(pb->logical_port, 0)); - hmap_insert(&lports->by_key, &p->key_node, - hash_int(pb->tunnel_key, pb->datapath->tunnel_key)); - p->pb = pb; - } + return retval; } -void -lport_index_destroy(struct lport_index *lports) +/* Finds and returns the datapath binding record with tunnel_key equal to the + * given 'dp_key', or NULL if no such datapath binding exists. */ +static const struct sbrec_datapath_binding * +datapath_lookup_by_key(struct ovsdb_idl *idl, uint64_t dp_key) { - if (!lports) { - return; - } + struct sbrec_datapath_binding *dbval; + const struct sbrec_datapath_binding *db, *retval = NULL; - /* Destroy all of the "struct lport"s. - * - * We don't have to remove the node from both indexes. */ - struct lport *port, *next; - HMAP_FOR_EACH_SAFE (port, next, name_node, &lports->by_name) { - hmap_remove(&lports->by_name, &port->name_node); - free(port); + /* Build key for an indexed lookup. */ + dbval = sbrec_datapath_binding_index_init_row(idl, + &sbrec_table_datapath_binding); + sbrec_datapath_binding_index_set_tunnel_key(dbval, dp_key); + + /* Find an entry with matching tunnel_key. Since this column is declared + * to be an index in the OVN_Southbound schema, the first match (if any) + * will be the only match. */ + SBREC_DATAPATH_BINDING_FOR_EACH_EQUAL (db, &dpath_by_key_cursor, dbval) { + retval = db; + break; } + sbrec_datapath_binding_index_destroy_row(dbval); - hmap_destroy(&lports->by_name); - hmap_destroy(&lports->by_key); + return retval; } -/* Finds and returns the lport with the given 'name', or NULL if no such lport - * exists. */ +/* Finds and returns the port binding record with tunnel_key equal to the + * given 'port_key' and datapath binding matching 'dp_key', or NULL if no + * such port binding exists. */ const struct sbrec_port_binding * -lport_lookup_by_name(const struct lport_index *lports, const char *name) +lport_lookup_by_key(struct ovsdb_idl *idl, uint64_t dp_key, uint64_t port_key) { - const struct lport *lport; - HMAP_FOR_EACH_WITH_HASH (lport, name_node, hash_string(name, 0), - &lports->by_name) { - if (!strcmp(lport->pb->logical_port, name)) { - return lport->pb; - } + struct sbrec_port_binding *pbval; + const struct sbrec_port_binding *pb, *retval = NULL; + const struct sbrec_datapath_binding *db; + + /* Lookup datapath corresponding to dp_key. */ + db = datapath_lookup_by_key(idl, dp_key); + if (!db) { + return NULL; } - return NULL; -} -const struct sbrec_port_binding * -lport_lookup_by_key(const struct lport_index *lports, - uint32_t dp_key, uint16_t port_key) -{ - const struct lport *lport; - HMAP_FOR_EACH_WITH_HASH (lport, key_node, hash_int(port_key, dp_key), - &lports->by_key) { - if (port_key == lport->pb->tunnel_key - && dp_key == lport->pb->datapath->tunnel_key) { - return lport->pb; - } + /* Build key for an indexed lookup. */ + pbval = sbrec_port_binding_index_init_row(idl, &sbrec_table_port_binding); + sbrec_port_binding_index_set_datapath(pbval, db); + sbrec_port_binding_index_set_tunnel_key(pbval, port_key); + + /* Find an entry with matching tunnel_key and datapath UUID. Since this + * column pair is declared to be an index in the OVN_Southbound schema, + * the first match (if any) will be the only match. */ + SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, &lport_by_key_cursor, pbval) { + retval = pb; + break; } - return NULL; + sbrec_port_binding_index_destroy_row(pbval); + + return retval; } /* Finds and returns the logical multicast group with the given 'name' and @@ -217,4 +211,18 @@ lport_init(struct ovsdb_idl *idl) ovsdb_idl_initialize_cursor(idl, &sbrec_table_multicast_group, "multicast-group-by-dp-name", &mc_grp_by_dp_name_cursor); + + /* Create cursor to search port binding table by logical port name. */ + ovsdb_idl_initialize_cursor(idl, &sbrec_table_port_binding, + "lport-by-name", + &lport_by_name_cursor); + + /* Create cursor to search port binding table by logical port tunnel key + * and datapath uuid. */ + ovsdb_idl_initialize_cursor(idl, &sbrec_table_port_binding, "lport-by-key", + &lport_by_key_cursor); + + /* Create cursor to search datapath binding table by tunnel key. */ + ovsdb_idl_initialize_cursor(idl, &sbrec_table_datapath_binding, + "dpath-by-key", &dpath_by_key_cursor); } diff --git a/ovn/controller/lport.h b/ovn/controller/lport.h index 4ee19a5..60532c8 100644 --- a/ovn/controller/lport.h +++ b/ovn/controller/lport.h @@ -51,25 +51,11 @@ void ldatapath_index_destroy(struct ldatapath_index *); const struct ldatapath *ldatapath_lookup_by_key( const struct ldatapath_index *, uint32_t dp_key); -/* Logical port index - * ================== - * - * This data structure holds multiple indexes over logical ports, to allow for - * efficient searching for logical ports by name or number. - */ - -struct lport_index { - struct hmap by_name; - struct hmap by_key; -}; - -void lport_index_init(struct lport_index *, struct ovsdb_idl *); -void lport_index_destroy(struct lport_index *); const struct sbrec_port_binding *lport_lookup_by_name( - const struct lport_index *, const char *name); + struct ovsdb_idl *, const char *name); const struct sbrec_port_binding *lport_lookup_by_key( - const struct lport_index *, uint32_t dp_key, uint16_t port_key); + struct ovsdb_idl *, uint64_t dp_key, uint64_t port_key); const struct sbrec_multicast_group *mcgroup_lookup_by_dp_name( diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index e30e83b..4455083 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -537,6 +537,26 @@ create_ovnsb_indexes(struct ovsdb_idl *ovnsb_idl) OVSDB_INDEX_ASC, NULL); ovsdb_idl_index_add_column(index, &sbrec_multicast_group_col_datapath, OVSDB_INDEX_ASC, NULL); + + /* Index logical port table by name. */ + index = ovsdb_idl_create_index(ovnsb_idl, &sbrec_table_port_binding, + "lport-by-name"); + ovsdb_idl_index_add_column(index, &sbrec_port_binding_col_logical_port, + OVSDB_INDEX_ASC, NULL); + + /* Index logical port table by tunnel key and datapath. */ + index = ovsdb_idl_create_index(ovnsb_idl, &sbrec_table_port_binding, + "lport-by-key"); + ovsdb_idl_index_add_column(index, &sbrec_port_binding_col_tunnel_key, + OVSDB_INDEX_ASC, NULL); + ovsdb_idl_index_add_column(index, &sbrec_port_binding_col_datapath, + OVSDB_INDEX_ASC, NULL); + + /* Index datapath binding table by tunnel key. */ + index = ovsdb_idl_create_index(ovnsb_idl, &sbrec_table_datapath_binding, + "dpath-by-key"); + ovsdb_idl_index_add_column(index, &sbrec_datapath_binding_col_tunnel_key, + OVSDB_INDEX_ASC, NULL); } int @@ -643,15 +663,13 @@ main(int argc, char *argv[]) const char *chassis_id = get_chassis_id(ctx.ovs_idl); struct ldatapath_index ldatapaths; - struct lport_index lports; ldatapath_index_init(&ldatapaths, ctx.ovnsb_idl); - lport_index_init(&lports, ctx.ovnsb_idl); const struct sbrec_chassis *chassis = NULL; if (chassis_id) { chassis = chassis_run(&ctx, chassis_id, br_int); encaps_run(&ctx, br_int, chassis_id); - binding_run(&ctx, br_int, chassis, &ldatapaths, &lports, + binding_run(&ctx, br_int, chassis, &ldatapaths, &local_datapaths, &local_lports); } @@ -664,7 +682,7 @@ main(int argc, char *argv[]) enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int, &pending_ct_zones); - pinctrl_run(&ctx, &lports, br_int, chassis, &local_datapaths); + pinctrl_run(&ctx, br_int, chassis, &local_datapaths); update_ct_zones(&local_lports, &local_datapaths, &ct_zones, ct_zone_bitmap, &pending_ct_zones); if (ctx.ovs_idl_txn) { @@ -672,11 +690,11 @@ main(int argc, char *argv[]) commit_ct_zones(br_int, &pending_ct_zones); struct hmap flow_table = HMAP_INITIALIZER(&flow_table); - lflow_run(&ctx, chassis, &lports, &local_datapaths, + lflow_run(&ctx, chassis, &local_datapaths, &group_table, &addr_sets, &flow_table); physical_run(&ctx, mff_ovn_geneve, - br_int, chassis, &ct_zones, &lports, + br_int, chassis, &ct_zones, &flow_table, &local_datapaths, &local_lports); ofctrl_put(&flow_table, &pending_ct_zones, @@ -721,7 +739,6 @@ main(int argc, char *argv[]) free(pending_pkt.flow_s); } - lport_index_destroy(&lports); ldatapath_index_destroy(&ldatapaths); sset_destroy(&local_lports); diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index f2d9676..8aa3603 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -286,9 +286,9 @@ load_logical_ingress_metadata(const struct sbrec_port_binding *binding, } static void -consider_port_binding(enum mf_field_id mff_ovn_geneve, +consider_port_binding(struct controller_ctx *ctx, + enum mf_field_id mff_ovn_geneve, const struct simap *ct_zones, - const struct lport_index *lports, struct hmap *local_datapaths, const struct sbrec_port_binding *binding, const struct sbrec_chassis *chassis, @@ -311,7 +311,7 @@ consider_port_binding(enum mf_field_id mff_ovn_geneve, } const struct sbrec_port_binding *peer = lport_lookup_by_name( - lports, peer_name); + ctx->ovnsb_idl, peer_name); if (!peer || strcmp(peer->type, binding->type)) { return; } @@ -373,7 +373,7 @@ consider_port_binding(enum mf_field_id mff_ovn_geneve, const char *distributed_port = smap_get_def(&binding->options, "distributed-port", ""); const struct sbrec_port_binding *distributed_binding - = lport_lookup_by_name(lports, distributed_port); + = lport_lookup_by_name(ctx->ovnsb_idl, distributed_port); if (!distributed_binding) { /* Packet will be dropped. */ @@ -768,7 +768,7 @@ void physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, const struct ovsrec_bridge *br_int, const struct sbrec_chassis *chassis, - const struct simap *ct_zones, struct lport_index *lports, + const struct simap *ct_zones, struct hmap *flow_table, struct hmap *local_datapaths, const struct sset *local_lports) { @@ -890,7 +890,7 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, * 64 for logical-to-physical translation. */ const struct sbrec_port_binding *binding; SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) { - consider_port_binding(mff_ovn_geneve, ct_zones, lports, + consider_port_binding(ctx, mff_ovn_geneve, ct_zones, local_datapaths, binding, chassis, &ofpacts, flow_table); } @@ -1014,7 +1014,7 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, * rule with higher priority for every localport in this * datapath. */ const struct sbrec_port_binding *pb = lport_lookup_by_name( - lports, localport); + ctx->ovnsb_idl, localport); if (pb && !strcmp(pb->type, "localport")) { match_set_reg(&match, MFF_LOG_INPORT - MFF_REG0, pb->tunnel_key); match_set_metadata(&match, htonll(pb->datapath->tunnel_key)); diff --git a/ovn/controller/physical.h b/ovn/controller/physical.h index 66aa80e..d70f45b 100644 --- a/ovn/controller/physical.h +++ b/ovn/controller/physical.h @@ -45,7 +45,7 @@ void physical_register_ovs_idl(struct ovsdb_idl *); void physical_run(struct controller_ctx *, enum mf_field_id mff_ovn_geneve, const struct ovsrec_bridge *br_int, const struct sbrec_chassis *chassis, - const struct simap *ct_zones, struct lport_index *, + const struct simap *ct_zones, struct hmap *flow_table, struct hmap *local_datapaths, const struct sset *local_lports); diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c index 660233a..e1fb188 100644 --- a/ovn/controller/pinctrl.c +++ b/ovn/controller/pinctrl.c @@ -61,17 +61,16 @@ static void pinctrl_handle_put_mac_binding(const struct flow *md, bool is_arp); static void init_put_mac_bindings(void); static void destroy_put_mac_bindings(void); -static void run_put_mac_bindings(struct controller_ctx *, - const struct lport_index *lports); +static void run_put_mac_bindings(struct controller_ctx *); static void wait_put_mac_bindings(struct controller_ctx *); static void flush_put_mac_bindings(void); static void init_send_garps(void); static void destroy_send_garps(void); static void send_garp_wait(void); -static void send_garp_run(const struct ovsrec_bridge *, +static void send_garp_run(struct controller_ctx *ctx, + const struct ovsrec_bridge *, const struct sbrec_chassis *, - const struct lport_index *lports, struct hmap *local_datapaths); static void pinctrl_handle_nd_na(const struct flow *ip_flow, const struct match *md, @@ -1013,7 +1012,7 @@ pinctrl_recv(const struct ofp_header *oh, enum ofptype type, } void -pinctrl_run(struct controller_ctx *ctx, const struct lport_index *lports, +pinctrl_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, const struct sbrec_chassis *chassis, struct hmap *local_datapaths) @@ -1050,8 +1049,8 @@ pinctrl_run(struct controller_ctx *ctx, const struct lport_index *lports, } } - run_put_mac_bindings(ctx, lports); - send_garp_run(br_int, chassis, lports, local_datapaths); + run_put_mac_bindings(ctx); + send_garp_run(ctx, br_int, chassis, local_datapaths); } void @@ -1164,7 +1163,6 @@ pinctrl_handle_put_mac_binding(const struct flow *md, static void run_put_mac_binding(struct controller_ctx *ctx, - const struct lport_index *lports, const struct put_mac_binding *pmb) { if (time_msec() > pmb->timestamp + 1000) { @@ -1173,7 +1171,7 @@ run_put_mac_binding(struct controller_ctx *ctx, /* Convert logical datapath and logical port key into lport. */ const struct sbrec_port_binding *pb - = lport_lookup_by_key(lports, pmb->dp_key, pmb->port_key); + = lport_lookup_by_key(ctx->ovnsb_idl, pmb->dp_key, pmb->port_key); if (!pb) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); @@ -1211,8 +1209,7 @@ run_put_mac_binding(struct controller_ctx *ctx, } static void -run_put_mac_bindings(struct controller_ctx *ctx, - const struct lport_index *lports) +run_put_mac_bindings(struct controller_ctx *ctx) { if (!ctx->ovnsb_idl_txn) { return; @@ -1220,7 +1217,7 @@ run_put_mac_bindings(struct controller_ctx *ctx, const struct put_mac_binding *pmb; HMAP_FOR_EACH (pmb, hmap_node, &put_mac_bindings) { - run_put_mac_binding(ctx, lports, pmb); + run_put_mac_binding(ctx, pmb); } flush_put_mac_bindings(); } @@ -1413,9 +1410,9 @@ send_garp(struct garp_data *garp, long long int current_time) /* Get localnet vifs, local l3gw ports and ofport for localnet patch ports. */ static void -get_localnet_vifs_l3gwports(const struct ovsrec_bridge *br_int, +get_localnet_vifs_l3gwports(struct controller_ctx *ctx, + const struct ovsrec_bridge *br_int, const struct sbrec_chassis *chassis, - const struct lport_index *lports, struct hmap *local_datapaths, struct sset *localnet_vifs, struct simap *localnet_ofports, @@ -1454,7 +1451,7 @@ get_localnet_vifs_l3gwports(const struct ovsrec_bridge *br_int, continue; } const struct sbrec_port_binding *pb - = lport_lookup_by_name(lports, iface_id); + = lport_lookup_by_name(ctx->ovnsb_idl, iface_id); if (!pb) { continue; } @@ -1488,12 +1485,12 @@ get_localnet_vifs_l3gwports(const struct ovsrec_bridge *br_int, } static bool -pinctrl_is_chassis_resident(const struct lport_index *lports, +pinctrl_is_chassis_resident(struct controller_ctx *ctx, const struct sbrec_chassis *chassis, const char *port_name) { const struct sbrec_port_binding *pb - = lport_lookup_by_name(lports, port_name); + = lport_lookup_by_name(ctx->ovnsb_idl, port_name); return pb && pb->chassis && pb->chassis == chassis; } @@ -1564,10 +1561,10 @@ extract_addresses_with_port(const char *addresses, } static void -consider_nat_address(const char *nat_address, +consider_nat_address(struct controller_ctx *ctx, + const char *nat_address, const struct sbrec_port_binding *pb, struct sset *nat_address_keys, - const struct lport_index *lports, const struct sbrec_chassis *chassis, struct shash *nat_addresses) { @@ -1575,7 +1572,7 @@ consider_nat_address(const char *nat_address, char *lport = NULL; if (!extract_addresses_with_port(nat_address, laddrs, &lport) || (!lport && !strcmp(pb->type, "patch")) - || (lport && !pinctrl_is_chassis_resident(lports, chassis, lport))) { + || (lport && !pinctrl_is_chassis_resident(ctx, chassis, lport))) { destroy_lport_addresses(laddrs); free(laddrs); free(lport); @@ -1594,24 +1591,25 @@ consider_nat_address(const char *nat_address, } static void -get_nat_addresses_and_keys(struct sset *nat_address_keys, +get_nat_addresses_and_keys(struct controller_ctx *ctx, + struct sset *nat_address_keys, struct sset *local_l3gw_ports, - const struct lport_index *lports, const struct sbrec_chassis *chassis, struct shash *nat_addresses) { const char *gw_port; SSET_FOR_EACH(gw_port, local_l3gw_ports) { - const struct sbrec_port_binding *pb = lport_lookup_by_name(lports, - gw_port); + const struct sbrec_port_binding *pb; + + pb = lport_lookup_by_name(ctx->ovnsb_idl, gw_port); if (!pb) { continue; } if (pb->n_nat_addresses) { for (int i = 0; i < pb->n_nat_addresses; i++) { - consider_nat_address(pb->nat_addresses[i], pb, - nat_address_keys, lports, chassis, + consider_nat_address(ctx, pb->nat_addresses[i], pb, + nat_address_keys, chassis, nat_addresses); } } else { @@ -1620,8 +1618,8 @@ get_nat_addresses_and_keys(struct sset *nat_address_keys, const char *nat_addresses_options = smap_get(&pb->options, "nat-addresses"); if (nat_addresses_options) { - consider_nat_address(nat_addresses_options, pb, - nat_address_keys, lports, chassis, + consider_nat_address(ctx, nat_addresses_options, pb, + nat_address_keys, chassis, nat_addresses); } } @@ -1635,9 +1633,9 @@ send_garp_wait(void) } static void -send_garp_run(const struct ovsrec_bridge *br_int, +send_garp_run(struct controller_ctx *ctx, + const struct ovsrec_bridge *br_int, const struct sbrec_chassis *chassis, - const struct lport_index *lports, struct hmap *local_datapaths) { struct sset localnet_vifs = SSET_INITIALIZER(&localnet_vifs); @@ -1648,10 +1646,10 @@ send_garp_run(const struct ovsrec_bridge *br_int, shash_init(&nat_addresses); - get_localnet_vifs_l3gwports(br_int, chassis, lports, local_datapaths, + get_localnet_vifs_l3gwports(ctx, br_int, chassis, local_datapaths, &localnet_vifs, &localnet_ofports, &local_l3gw_ports); - get_nat_addresses_and_keys(&nat_ip_keys, &local_l3gw_ports, lports, + get_nat_addresses_and_keys(ctx, &nat_ip_keys, &local_l3gw_ports, chassis, &nat_addresses); /* For deleted ports and deleted nat ips, remove from send_garp_data. */ struct shash_node *iter, *next; @@ -1665,8 +1663,9 @@ send_garp_run(const struct ovsrec_bridge *br_int, /* Update send_garp_data. */ const char *iface_id; SSET_FOR_EACH (iface_id, &localnet_vifs) { - const struct sbrec_port_binding *pb = lport_lookup_by_name(lports, - iface_id); + const struct sbrec_port_binding *pb; + + pb = lport_lookup_by_name(ctx->ovnsb_idl, iface_id); if (pb) { send_garp_update(pb, &localnet_ofports, local_datapaths, &nat_addresses); @@ -1676,8 +1675,9 @@ send_garp_run(const struct ovsrec_bridge *br_int, /* Update send_garp_data for nat-addresses. */ const char *gw_port; SSET_FOR_EACH (gw_port, &local_l3gw_ports) { - const struct sbrec_port_binding *pb = lport_lookup_by_name(lports, - gw_port); + const struct sbrec_port_binding *pb; + + pb = lport_lookup_by_name(ctx->ovnsb_idl, gw_port); if (pb) { send_garp_update(pb, &localnet_ofports, local_datapaths, &nat_addresses); diff --git a/ovn/controller/pinctrl.h b/ovn/controller/pinctrl.h index 230580b..0b7afab 100644 --- a/ovn/controller/pinctrl.h +++ b/ovn/controller/pinctrl.h @@ -28,7 +28,7 @@ struct ovsrec_bridge; struct sbrec_chassis; void pinctrl_init(void); -void pinctrl_run(struct controller_ctx *, const struct lport_index *, +void pinctrl_run(struct controller_ctx *, const struct ovsrec_bridge *, const struct sbrec_chassis *, struct hmap *local_datapaths); void pinctrl_wait(struct controller_ctx *);