From patchwork Thu Aug 10 12:44:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dumitru Ceara X-Patchwork-Id: 1819841 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ilgpvwSM; dkim-atps=neutral Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RM6843s8Qz1yf2 for ; Thu, 10 Aug 2023 22:44:52 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 8092C60B7C; Thu, 10 Aug 2023 12:44:50 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 8092C60B7C Authentication-Results: smtp3.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ilgpvwSM X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id l4DWpCT-yqmD; Thu, 10 Aug 2023 12:44:49 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTPS id 2F71260AB7; Thu, 10 Aug 2023 12:44:48 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 2F71260AB7 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id F0231C0072; Thu, 10 Aug 2023 12:44:47 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 30ADCC0032 for ; Thu, 10 Aug 2023 12:44:46 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id F1BE141B88 for ; Thu, 10 Aug 2023 12:44:45 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org F1BE141B88 Authentication-Results: smtp4.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ilgpvwSM X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id RPvkPISFB3bp for ; Thu, 10 Aug 2023 12:44:44 +0000 (UTC) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp4.osuosl.org (Postfix) with ESMTPS id 6533641B84 for ; Thu, 10 Aug 2023 12:44:44 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 6533641B84 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691671483; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=M9LxfIQJDXQaHxkz8j1/ATb/GZxgdACpuNZ127EHFs8=; b=ilgpvwSMrYSU2+WZVWvZz2/dAz3GXaNS/KCvecJSBUVS+7AJPKrx7F/A5VSScJGEkUNfeL 5SPVMRLlX8iqxdifezZNOnjZN4sX5ug7h0x5Iygg/1CMrtiqRtbg7dPZH8x5DbK9hCHULS SIATqWbTrK+N8w3nxHxt+STArqyEPDM= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-551-o862VAKLMl6wbdYjwa5xvg-1; Thu, 10 Aug 2023 08:44:39 -0400 X-MC-Unique: o862VAKLMl6wbdYjwa5xvg-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 801A48DC666; Thu, 10 Aug 2023 12:44:39 +0000 (UTC) Received: from dceara.remote.csb (unknown [10.39.194.96]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5FD15492C13; Thu, 10 Aug 2023 12:44:38 +0000 (UTC) From: Dumitru Ceara To: ovs-dev@openvswitch.org Date: Thu, 10 Aug 2023 14:44:35 +0200 Message-Id: <169167147158.2447623.6554641432367089545.stgit@dceara.remote.csb> In-Reply-To: <169167146062.2447623.4263905982665736274.stgit@dceara.remote.csb> References: <169167146062.2447623.4263905982665736274.stgit@dceara.remote.csb> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.10 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH ovn 1/5] ovn-util: Factor out struct sorted_addresses into sorted_array. 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" It's actually a generic wrapper and will be useful for upcoming commits. This commit doesn't perform any functional changes but cleans up a bit the implementation unifying the sorted_array cleanup. Before the change the caller had to track whether it should free the internal 'arr' field or not. It's now taken care of inside the sorted_array_destroy() API which the user always has to call. Signed-off-by: Dumitru Ceara Acked-by: Han Zhou Acked-by: Ales Musil --- lib/ovn-util.h | 78 +++++++++++++++++++++++++++ northd/en-sync-sb.c | 150 +++++++++++++++++---------------------------------- 2 files changed, 127 insertions(+), 101 deletions(-) diff --git a/lib/ovn-util.h b/lib/ovn-util.h index 5ebdd8adb0..2de7725132 100644 --- a/lib/ovn-util.h +++ b/lib/ovn-util.h @@ -18,6 +18,8 @@ #include "ovsdb-idl.h" #include "lib/packets.h" +#include "lib/sset.h" +#include "lib/svec.h" #include "include/ovn/version.h" #define ovn_set_program_name(name) \ @@ -409,4 +411,80 @@ void flow_collector_ids_clear(struct flow_collector_ids *); * The returned pointer has to be freed by caller. */ char *encode_fqdn_string(const char *fqdn, size_t *len); +/* A wrapper that holds sorted arrays of strings. */ +struct sorted_array { + const char **arr; + bool owns_array; + size_t n; +}; + +static inline struct sorted_array +sorted_array_create(const char **sorted_data, size_t n, bool take_ownership) +{ + return (struct sorted_array) { + .arr = sorted_data, + .owns_array = take_ownership, + .n = n, + }; +} + +static inline void +sorted_array_destroy(struct sorted_array *a) +{ + if (a->owns_array) { + free(a->arr); + } +} + +static inline struct sorted_array +sorted_array_from_svec(struct svec *v) +{ + svec_sort(v); + return sorted_array_create((const char **) v->names, v->n, false); +} + +static inline struct sorted_array +sorted_array_from_sset(struct sset *s) +{ + return sorted_array_create(sset_sort(s), sset_count(s), true); +} + +/* DB set columns are already sorted, just wrap them into a sorted array. */ +#define sorted_array_from_dbrec(dbrec, column) \ + sorted_array_create((const char **) (dbrec)->column, \ + (dbrec)->n_##column, false) + +static inline void +sorted_array_apply_diff(const struct sorted_array *a1, + const struct sorted_array *a2, + void (*apply_callback)(const void *arg, + const char *item, + bool add), + const void *arg) +{ + size_t idx1, idx2; + + for (idx1 = idx2 = 0; idx1 < a1->n && idx2 < a2->n;) { + int cmp = strcmp(a1->arr[idx1], a2->arr[idx2]); + if (cmp < 0) { + apply_callback(arg, a1->arr[idx1], true); + idx1++; + } else if (cmp > 0) { + apply_callback(arg, a2->arr[idx2], false); + idx2++; + } else { + idx1++; + idx2++; + } + } + + for (; idx1 < a1->n; idx1++) { + apply_callback(arg, a1->arr[idx1], true); + } + + for (; idx2 < a2->n; idx2++) { + apply_callback(arg, a2->arr[idx2], false); + } +} + #endif /* OVN_UTIL_H */ diff --git a/northd/en-sync-sb.c b/northd/en-sync-sb.c index d7fea981f2..f97771b3b4 100644 --- a/northd/en-sync-sb.c +++ b/northd/en-sync-sb.c @@ -33,15 +33,8 @@ VLOG_DEFINE_THIS_MODULE(en_sync_to_sb); -/* This is just a type wrapper to enforce that it has to be sorted. */ -struct sorted_addresses { - const char **arr; - size_t n; -}; - - static void sync_addr_set(struct ovsdb_idl_txn *ovnsb_txn, const char *name, - struct sorted_addresses *addresses, + struct sorted_array *addresses, struct shash *sb_address_sets); static void sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, const struct nbrec_address_set_table *, @@ -50,17 +43,11 @@ static void sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, const struct ovn_datapaths *lr_datapaths); static const struct sbrec_address_set *sb_address_set_lookup_by_name( struct ovsdb_idl_index *, const char *name); -static void update_sb_addr_set(struct sorted_addresses *, +static void update_sb_addr_set(struct sorted_array *, const struct sbrec_address_set *); static void build_port_group_address_set(const struct nbrec_port_group *, struct svec *ipv4_addrs, struct svec *ipv6_addrs); -static struct sorted_addresses -sorted_addresses_from_nbrec(const struct nbrec_address_set *nb_as); -static struct sorted_addresses -sorted_addresses_from_svec(struct svec *addresses); -static struct sorted_addresses -sorted_addresses_from_sset(struct sset *addresses); void * en_sync_to_sb_init(struct engine_node *node OVS_UNUSED, @@ -145,9 +132,10 @@ sync_to_sb_addr_set_nb_address_set_handler(struct engine_node *node, if (!sb_addr_set) { return false; } - struct sorted_addresses addrs = - sorted_addresses_from_nbrec(nb_addr_set); + struct sorted_array addrs = + sorted_array_from_dbrec(nb_addr_set, addresses); update_sb_addr_set(&addrs, sb_addr_set); + sorted_array_destroy(&addrs); } return true; @@ -194,18 +182,20 @@ sync_to_sb_addr_set_nb_port_group_handler(struct engine_node *node, struct svec ipv6_addrs = SVEC_EMPTY_INITIALIZER; build_port_group_address_set(nb_pg, &ipv4_addrs, &ipv6_addrs); - struct sorted_addresses ipv4_addrs_sorted = - sorted_addresses_from_svec(&ipv4_addrs); - struct sorted_addresses ipv6_addrs_sorted = - sorted_addresses_from_svec(&ipv6_addrs); + struct sorted_array ipv4_addrs_sorted = + sorted_array_from_svec(&ipv4_addrs); + struct sorted_array ipv6_addrs_sorted = + sorted_array_from_svec(&ipv6_addrs); update_sb_addr_set(&ipv4_addrs_sorted, sb_addr_set_v4); update_sb_addr_set(&ipv6_addrs_sorted, sb_addr_set_v6); - free(ipv4_addrs_name); - free(ipv6_addrs_name); + sorted_array_destroy(&ipv4_addrs_sorted); + sorted_array_destroy(&ipv6_addrs_sorted); svec_destroy(&ipv4_addrs); svec_destroy(&ipv6_addrs); + free(ipv4_addrs_name); + free(ipv6_addrs_name); } return true; @@ -214,7 +204,7 @@ sync_to_sb_addr_set_nb_port_group_handler(struct engine_node *node, /* static functions. */ static void sync_addr_set(struct ovsdb_idl_txn *ovnsb_txn, const char *name, - struct sorted_addresses *addresses, + struct sorted_array *addresses, struct shash *sb_address_sets) { const struct sbrec_address_set *sb_address_set; @@ -261,11 +251,9 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, /* Service monitor MAC. */ const char *svc_monitor_macp = northd_get_svc_monitor_mac(); - struct sorted_addresses svc = { - .arr = &svc_monitor_macp, - .n = 1, - }; + struct sorted_array svc = sorted_array_create(&svc_monitor_macp, 1, false); sync_addr_set(ovnsb_txn, "svc_monitor_mac", &svc, &sb_address_sets); + sorted_array_destroy(&svc); /* sync port group generated address sets first */ const struct nbrec_port_group *nb_port_group; @@ -277,19 +265,21 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, char *ipv4_addrs_name = xasprintf("%s_ip4", nb_port_group->name); char *ipv6_addrs_name = xasprintf("%s_ip6", nb_port_group->name); - struct sorted_addresses ipv4_addrs_sorted = - sorted_addresses_from_svec(&ipv4_addrs); - struct sorted_addresses ipv6_addrs_sorted = - sorted_addresses_from_svec(&ipv6_addrs); + struct sorted_array ipv4_addrs_sorted = + sorted_array_from_svec(&ipv4_addrs); + struct sorted_array ipv6_addrs_sorted = + sorted_array_from_svec(&ipv6_addrs); sync_addr_set(ovnsb_txn, ipv4_addrs_name, &ipv4_addrs_sorted, &sb_address_sets); sync_addr_set(ovnsb_txn, ipv6_addrs_name, &ipv6_addrs_sorted, &sb_address_sets); - free(ipv4_addrs_name); - free(ipv6_addrs_name); + sorted_array_destroy(&ipv4_addrs_sorted); + sorted_array_destroy(&ipv6_addrs_sorted); svec_destroy(&ipv4_addrs); svec_destroy(&ipv6_addrs); + free(ipv4_addrs_name); + free(ipv6_addrs_name); } /* Sync router load balancer VIP generated address sets. */ @@ -301,24 +291,24 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, char *ipv4_addrs_name = lr_lb_address_set_name(od->tunnel_key, AF_INET); - struct sorted_addresses ipv4_addrs_sorted = - sorted_addresses_from_sset(&od->lb_ips->ips_v4_reachable); + struct sorted_array ipv4_addrs_sorted = + sorted_array_from_sset(&od->lb_ips->ips_v4_reachable); sync_addr_set(ovnsb_txn, ipv4_addrs_name, &ipv4_addrs_sorted, &sb_address_sets); - free(ipv4_addrs_sorted.arr); + sorted_array_destroy(&ipv4_addrs_sorted); free(ipv4_addrs_name); } if (sset_count(&od->lb_ips->ips_v6_reachable)) { char *ipv6_addrs_name = lr_lb_address_set_name(od->tunnel_key, AF_INET6); - struct sorted_addresses ipv6_addrs_sorted = - sorted_addresses_from_sset(&od->lb_ips->ips_v6_reachable); + struct sorted_array ipv6_addrs_sorted = + sorted_array_from_sset(&od->lb_ips->ips_v6_reachable); sync_addr_set(ovnsb_txn, ipv6_addrs_name, &ipv6_addrs_sorted, &sb_address_sets); - free(ipv6_addrs_sorted.arr); + sorted_array_destroy(&ipv6_addrs_sorted); free(ipv6_addrs_name); } } @@ -328,10 +318,11 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, const struct nbrec_address_set *nb_address_set; NBREC_ADDRESS_SET_TABLE_FOR_EACH (nb_address_set, nb_address_set_table) { - struct sorted_addresses addrs = - sorted_addresses_from_nbrec(nb_address_set); + struct sorted_array addrs = + sorted_array_from_dbrec(nb_address_set, addresses); sync_addr_set(ovnsb_txn, nb_address_set->name, &addrs, &sb_address_sets); + sorted_array_destroy(&addrs); } struct shash_node *node; @@ -343,39 +334,25 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, } static void -update_sb_addr_set(struct sorted_addresses *nb_addresses, - const struct sbrec_address_set *sb_as) +sb_addr_set_apply_diff(const void *arg, const char *item, bool add) { - size_t nb_index, sb_index; - - const char **nb_arr = nb_addresses->arr; - char **sb_arr = sb_as->addresses; - size_t nb_n = nb_addresses->n; - size_t sb_n = sb_as->n_addresses; - - for (nb_index = sb_index = 0; nb_index < nb_n && sb_index < sb_n;) { - int cmp = strcmp(nb_arr[nb_index], sb_arr[sb_index]); - if (cmp < 0) { - sbrec_address_set_update_addresses_addvalue(sb_as, - nb_arr[nb_index]); - nb_index++; - } else if (cmp > 0) { - sbrec_address_set_update_addresses_delvalue(sb_as, - sb_arr[sb_index]); - sb_index++; - } else { - nb_index++; - sb_index++; - } - } - - for (; nb_index < nb_n; nb_index++) { - sbrec_address_set_update_addresses_addvalue(sb_as, nb_arr[nb_index]); + const struct sbrec_address_set *as = arg; + if (add) { + sbrec_address_set_update_addresses_addvalue(as, item); + } else { + sbrec_address_set_update_addresses_delvalue(as, item); } +} - for (; sb_index < sb_n; sb_index++) { - sbrec_address_set_update_addresses_delvalue(sb_as, sb_arr[sb_index]); - } +static void +update_sb_addr_set(struct sorted_array *nb_addresses, + const struct sbrec_address_set *sb_as) +{ + struct sorted_array sb_addresses = + sorted_array_from_dbrec(sb_as, addresses); + sorted_array_apply_diff(nb_addresses, &sb_addresses, + sb_addr_set_apply_diff, sb_as); + sorted_array_destroy(&sb_addresses); } static void @@ -414,32 +391,3 @@ sb_address_set_lookup_by_name(struct ovsdb_idl_index *sbrec_addr_set_by_name, return retval; } - -static struct sorted_addresses -sorted_addresses_from_nbrec(const struct nbrec_address_set *nb_as) -{ - /* The DB is already sorted. */ - return (struct sorted_addresses) { - .arr = (const char **) nb_as->addresses, - .n = nb_as->n_addresses, - }; -} - -static struct sorted_addresses -sorted_addresses_from_svec(struct svec *addresses) -{ - svec_sort(addresses); - return (struct sorted_addresses) { - .arr = (const char **) addresses->names, - .n = addresses->n, - }; -} - -static struct sorted_addresses -sorted_addresses_from_sset(struct sset *addresses) -{ - return (struct sorted_addresses) { - .arr = sset_sort(addresses), - .n = sset_count(addresses), - }; -}