From patchwork Fri Feb 10 16:03:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 1740537 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::138; helo=smtp1.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=P41wCqm/; dkim-atps=neutral Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (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 4PCz6p1dD0z23fc for ; Sat, 11 Feb 2023 03:03:30 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 8387982310; Fri, 10 Feb 2023 16:03:28 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 8387982310 Authentication-Results: smtp1.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=P41wCqm/ X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id roZoN_6p-fN5; Fri, 10 Feb 2023 16:03:27 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id 317D782302; Fri, 10 Feb 2023 16:03:26 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 317D782302 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0906FC0032; Fri, 10 Feb 2023 16:03:26 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 8ADF0C002B for ; Fri, 10 Feb 2023 16:03:24 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 64A8B605AC for ; Fri, 10 Feb 2023 16:03:24 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 64A8B605AC Authentication-Results: smtp3.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=P41wCqm/ 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 4CfBABvPiNYv for ; Fri, 10 Feb 2023 16:03:23 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 2C2FB60BFF Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp3.osuosl.org (Postfix) with ESMTPS id 2C2FB60BFF for ; Fri, 10 Feb 2023 16:03:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676045002; 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; bh=/VjqZ5acOZZ2noW0RHA9Ic9AI+dUX8RSndBr7L0Pj6k=; b=P41wCqm/5qjsNpTLR8YI+zOwfULsUxHtYx+squEUBqoxILoxXSH32E6wcZTiyvMAZQfLcE RHztgYOd9royQBe5BT6bOtFJnFVg+LSzPNiOzDJVVoThVtSekkiXq8mstY4js14njLcZtT DYdxLpVTT8GcbWDIXS9Qkrvb7f5d5NA= 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-10-pJja71OuOaSgElC_mUEvWg-1; Fri, 10 Feb 2023 11:03:19 -0500 X-MC-Unique: pJja71OuOaSgElC_mUEvWg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 9732D185A78B; Fri, 10 Feb 2023 16:03:18 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.192.68]) by smtp.corp.redhat.com (Postfix) with ESMTP id 57082400DB1E; Fri, 10 Feb 2023 16:03:17 +0000 (UTC) From: =?utf-8?q?Adri=C3=A1n_Moreno?= To: dev@openvswitch.org Date: Fri, 10 Feb 2023 17:03:13 +0100 Message-Id: <20230210160314.131210-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: i.maximets@ovn.org, simon.horman@corigine.com Subject: [ovs-dev] [PATCH v3 1/2] ofproto-ipfix: use per-domain template timeouts 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: Adrian Moreno IPFIX templates have to be sent for each Observation Domain ID. Currently, a timer is kept at each dpif_ipfix_exporter to send them. This works fine for per-bridge sampling where there is only one Observation Domain ID per exporter. However, this is does not work for per-flow sampling where more than one Observation Domain IDs can be specified by the controller. In this case, ovs-vswitchd will only send template information for one (arbitrary) DomainID. Fix per-flow sampling by using an hmap to keep a timer for each Observation Domain ID. Signed-off-by: Adrian Moreno Reviewed-by: Simon Horman --- - v3: - Removed unit tests which generate errors in Intel CI. Will submit in independent series. - Added Simon Horman's proposal for incresing cache efficiency. - v2: - Fixed a potential race condition in unit test. - v1: - Added unit test. - Drop domain_id from "struct dpif_ipfix_domain" since the hashmap already uses it as index. - Added OVS_REQUES(mutex) to dpif_ipfix_exporter_find_domain. --- ofproto/ofproto-dpif-ipfix.c | 129 ++++++++++++++++++++++++++++------- 1 file changed, 105 insertions(+), 24 deletions(-) diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c index 742eed399..1701d91e8 100644 --- a/ofproto/ofproto-dpif-ipfix.c +++ b/ofproto/ofproto-dpif-ipfix.c @@ -124,11 +124,18 @@ struct dpif_ipfix_port { uint32_t ifindex; }; +struct dpif_ipfix_domain { + struct hmap_node hmap_node; /* In struct dpif_ipfix_exporter's domains. */ + time_t last_template_set_time; +}; + struct dpif_ipfix_exporter { uint32_t exporter_id; /* Exporting Process identifier */ - struct collectors *collectors; uint32_t seq_number; - time_t last_template_set_time; + struct collectors *collectors; + struct hmap domains; /* Contains struct dpif_ipfix_domain indexed by + observation domain id. */ + time_t last_stats_sent_time; struct hmap cache_flow_key_map; /* ipfix_flow_cache_entry. */ struct ovs_list cache_flow_start_timestamp_list; /* ipfix_flow_cache_entry. */ uint32_t cache_active_timeout; /* In seconds. */ @@ -617,6 +624,9 @@ static void get_export_time_now(uint64_t *, uint32_t *); static void dpif_ipfix_cache_expire_now(struct dpif_ipfix_exporter *, bool); +static void dpif_ipfix_exporter_del_domain(struct dpif_ipfix_exporter * , + struct dpif_ipfix_domain * ); + static bool ofproto_ipfix_bridge_exporter_options_equal( const struct ofproto_ipfix_bridge_exporter_options *a, @@ -697,13 +707,14 @@ dpif_ipfix_exporter_init(struct dpif_ipfix_exporter *exporter) exporter->exporter_id = ++exporter_total_count; exporter->collectors = NULL; exporter->seq_number = 1; - exporter->last_template_set_time = 0; + exporter->last_stats_sent_time = 0; hmap_init(&exporter->cache_flow_key_map); ovs_list_init(&exporter->cache_flow_start_timestamp_list); exporter->cache_active_timeout = 0; exporter->cache_max_flows = 0; exporter->virtual_obs_id = NULL; exporter->virtual_obs_len = 0; + hmap_init(&exporter->domains); memset(&exporter->ipfix_global_stats, 0, sizeof(struct dpif_ipfix_global_stats)); @@ -711,6 +722,7 @@ dpif_ipfix_exporter_init(struct dpif_ipfix_exporter *exporter) static void dpif_ipfix_exporter_clear(struct dpif_ipfix_exporter *exporter) + OVS_REQUIRES(mutex) { /* Flush the cache with flow end reason "forced end." */ dpif_ipfix_cache_expire_now(exporter, true); @@ -719,22 +731,29 @@ dpif_ipfix_exporter_clear(struct dpif_ipfix_exporter *exporter) exporter->exporter_id = 0; exporter->collectors = NULL; exporter->seq_number = 1; - exporter->last_template_set_time = 0; + exporter->last_stats_sent_time = 0; exporter->cache_active_timeout = 0; exporter->cache_max_flows = 0; free(exporter->virtual_obs_id); exporter->virtual_obs_id = NULL; exporter->virtual_obs_len = 0; + struct dpif_ipfix_domain *dom; + HMAP_FOR_EACH_SAFE (dom, hmap_node, &exporter->domains) { + dpif_ipfix_exporter_del_domain(exporter, dom); + } + memset(&exporter->ipfix_global_stats, 0, sizeof(struct dpif_ipfix_global_stats)); } static void dpif_ipfix_exporter_destroy(struct dpif_ipfix_exporter *exporter) + OVS_REQUIRES(mutex) { dpif_ipfix_exporter_clear(exporter); hmap_destroy(&exporter->cache_flow_key_map); + hmap_destroy(&exporter->domains); } static bool @@ -742,7 +761,7 @@ dpif_ipfix_exporter_set_options(struct dpif_ipfix_exporter *exporter, const struct sset *targets, const uint32_t cache_active_timeout, const uint32_t cache_max_flows, - const char *virtual_obs_id) + const char *virtual_obs_id) OVS_REQUIRES(mutex) { size_t virtual_obs_len; collectors_destroy(exporter->collectors); @@ -769,6 +788,37 @@ dpif_ipfix_exporter_set_options(struct dpif_ipfix_exporter *exporter, return true; } +static struct dpif_ipfix_domain * +dpif_ipfix_exporter_find_domain(const struct dpif_ipfix_exporter *exporter, + uint32_t domain_id) OVS_REQUIRES(mutex) +{ + struct dpif_ipfix_domain *dom; + HMAP_FOR_EACH_WITH_HASH (dom, hmap_node, hash_int(domain_id, 0), + &exporter->domains) { + return dom; + } + return NULL; +} + +static struct dpif_ipfix_domain * +dpif_ipfix_exporter_insert_domain(struct dpif_ipfix_exporter *exporter, + const uint32_t domain_id) OVS_REQUIRES(mutex) +{ + struct dpif_ipfix_domain *dom = xmalloc(sizeof *dom); + dom->last_template_set_time = 0; + hmap_insert(&exporter->domains, &dom->hmap_node, hash_int(domain_id, 0)); + return dom; +} + +static void +dpif_ipfix_exporter_del_domain(struct dpif_ipfix_exporter *exporter, + struct dpif_ipfix_domain *dom) + OVS_REQUIRES(mutex) +{ + hmap_remove(&exporter->domains, &dom->hmap_node); + free(dom); +} + static struct dpif_ipfix_port * dpif_ipfix_find_port(const struct dpif_ipfix *di, odp_port_t odp_port) OVS_REQUIRES(mutex) @@ -909,6 +959,7 @@ dpif_ipfix_bridge_exporter_init(struct dpif_ipfix_bridge_exporter *exporter) static void dpif_ipfix_bridge_exporter_clear(struct dpif_ipfix_bridge_exporter *exporter) + OVS_REQUIRES(mutex) { dpif_ipfix_exporter_clear(&exporter->exporter); ofproto_ipfix_bridge_exporter_options_destroy(exporter->options); @@ -918,6 +969,7 @@ dpif_ipfix_bridge_exporter_clear(struct dpif_ipfix_bridge_exporter *exporter) static void dpif_ipfix_bridge_exporter_destroy(struct dpif_ipfix_bridge_exporter *exporter) + OVS_REQUIRES(mutex) { dpif_ipfix_bridge_exporter_clear(exporter); dpif_ipfix_exporter_destroy(&exporter->exporter); @@ -927,7 +979,7 @@ static void dpif_ipfix_bridge_exporter_set_options( struct dpif_ipfix_bridge_exporter *exporter, const struct ofproto_ipfix_bridge_exporter_options *options, - bool *options_changed) + bool *options_changed) OVS_REQUIRES(mutex) { if (!options || sset_is_empty(&options->targets)) { /* No point in doing any work if there are no targets. */ @@ -1003,6 +1055,7 @@ dpif_ipfix_flow_exporter_init(struct dpif_ipfix_flow_exporter *exporter) static void dpif_ipfix_flow_exporter_clear(struct dpif_ipfix_flow_exporter *exporter) + OVS_REQUIRES(mutex) { dpif_ipfix_exporter_clear(&exporter->exporter); ofproto_ipfix_flow_exporter_options_destroy(exporter->options); @@ -1011,6 +1064,7 @@ dpif_ipfix_flow_exporter_clear(struct dpif_ipfix_flow_exporter *exporter) static void dpif_ipfix_flow_exporter_destroy(struct dpif_ipfix_flow_exporter *exporter) + OVS_REQUIRES(mutex) { dpif_ipfix_flow_exporter_clear(exporter); dpif_ipfix_exporter_destroy(&exporter->exporter); @@ -1020,7 +1074,7 @@ static bool dpif_ipfix_flow_exporter_set_options( struct dpif_ipfix_flow_exporter *exporter, const struct ofproto_ipfix_flow_exporter_options *options, - bool *options_changed) + bool *options_changed) OVS_REQUIRES(mutex) { if (sset_is_empty(&options->targets)) { /* No point in doing any work if there are no targets. */ @@ -1071,6 +1125,7 @@ dpif_ipfix_flow_exporter_set_options( static void remove_flow_exporter(struct dpif_ipfix *di, struct dpif_ipfix_flow_exporter_map_node *node) + OVS_REQUIRES(mutex) { hmap_remove(&di->flow_exporter_map, &node->node); dpif_ipfix_flow_exporter_destroy(&node->exporter); @@ -2000,6 +2055,7 @@ static void ipfix_cache_update(struct dpif_ipfix_exporter *exporter, struct ipfix_flow_cache_entry *entry, enum ipfix_sampled_packet_type sampled_pkt_type) + OVS_REQUIRES(mutex) { struct ipfix_flow_cache_entry *old_entry; size_t current_flows = 0; @@ -2811,14 +2867,36 @@ dpif_ipfix_flow_sample(struct dpif_ipfix *di, const struct dp_packet *packet, ovs_mutex_unlock(&mutex); } +static bool +dpif_ipfix_should_send_template(struct dpif_ipfix_exporter *exporter, + const uint32_t observation_domain_id, + const uint32_t export_time_sec) + OVS_REQUIRES(mutex) +{ + struct dpif_ipfix_domain *domain; + domain = dpif_ipfix_exporter_find_domain(exporter, + observation_domain_id); + if (!domain) { + /* First time we see this obs_domain_id. */ + domain = dpif_ipfix_exporter_insert_domain(exporter, + observation_domain_id); + } + + if ((domain->last_template_set_time + IPFIX_TEMPLATE_INTERVAL) + <= export_time_sec) { + domain->last_template_set_time = export_time_sec; + return true; + } + return false; +} + static void dpif_ipfix_cache_expire(struct dpif_ipfix_exporter *exporter, bool forced_end, const uint64_t export_time_usec, - const uint32_t export_time_sec) + const uint32_t export_time_sec) OVS_REQUIRES(mutex) { struct ipfix_flow_cache_entry *entry; uint64_t max_flow_start_timestamp_usec; - bool template_msg_sent = false; enum ipfix_flow_end_reason flow_end_reason; if (ovs_list_is_empty(&exporter->cache_flow_start_timestamp_list)) { @@ -2844,25 +2922,28 @@ dpif_ipfix_cache_expire(struct dpif_ipfix_exporter *exporter, break; } - ovs_list_remove(&entry->cache_flow_start_timestamp_list_node); - hmap_remove(&exporter->cache_flow_key_map, - &entry->flow_key_map_node); + /* XXX: Make frequency of the (Options) Template and Exporter Process + * Statistics transmission configurable. + * Cf. IETF RFC 5101 Section 4.3. and 10.3.6. */ + if ((exporter->last_stats_sent_time + IPFIX_TEMPLATE_INTERVAL) + <= export_time_sec) { + exporter->last_stats_sent_time = export_time_sec; + ipfix_send_exporter_data_msg(exporter, export_time_sec); + } - /* XXX: Make frequency of the (Options) Template and Exporter Process - * Statistics transmission configurable. - * Cf. IETF RFC 5101 Section 4.3. and 10.3.6. */ - if (!template_msg_sent - && (exporter->last_template_set_time + IPFIX_TEMPLATE_INTERVAL) - <= export_time_sec) { + if (dpif_ipfix_should_send_template(exporter, + entry->flow_key.obs_domain_id, + export_time_sec)) { + VLOG_DBG("Sending templates for ObservationDomainID %"PRIu32, + entry->flow_key.obs_domain_id); ipfix_send_template_msgs(exporter, export_time_sec, entry->flow_key.obs_domain_id); - exporter->last_template_set_time = export_time_sec; - template_msg_sent = true; - - /* Send Exporter Process Statistics. */ - ipfix_send_exporter_data_msg(exporter, export_time_sec); } + ovs_list_remove(&entry->cache_flow_start_timestamp_list_node); + hmap_remove(&exporter->cache_flow_key_map, + &entry->flow_key_map_node); + /* XXX: Group multiple data records for the same obs domain id * into the same message. */ ipfix_send_data_msg(exporter, export_time_sec, entry, flow_end_reason); @@ -2883,7 +2964,7 @@ get_export_time_now(uint64_t *export_time_usec, uint32_t *export_time_sec) static void dpif_ipfix_cache_expire_now(struct dpif_ipfix_exporter *exporter, - bool forced_end) + bool forced_end) OVS_REQUIRES(mutex) { uint64_t export_time_usec; uint32_t export_time_sec; From patchwork Fri Feb 10 16:03:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 1740538 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=f0pDz4px; 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 4PCz6v1Cq3z23yH for ; Sat, 11 Feb 2023 03:03:34 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 53CEA60598; Fri, 10 Feb 2023 16:03:33 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 53CEA60598 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=f0pDz4px 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 gzic1ETIqjTx; Fri, 10 Feb 2023 16:03:32 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTPS id 26C4260E65; Fri, 10 Feb 2023 16:03:31 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 26C4260E65 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id E56E3C0032; Fri, 10 Feb 2023 16:03:30 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 63283C0077 for ; Fri, 10 Feb 2023 16:03:29 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 6ACEA41165 for ; Fri, 10 Feb 2023 16:03:28 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 6ACEA41165 Authentication-Results: smtp2.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=f0pDz4px X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id XREzxMr0DkHc for ; Fri, 10 Feb 2023 16:03:27 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 3E25041153 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp2.osuosl.org (Postfix) with ESMTPS id 3E25041153 for ; Fri, 10 Feb 2023 16:03:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676045006; 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=EzLg/LrPPY/a5VizMWr1BmdqPozt9l6NYQur+ejPIrE=; b=f0pDz4pxsNDUbDFwd9kRKRmRyScWRHgCsGflqD0yBycGouQGCGT7xb88383hMHXwqrVcAa IitQ1codQBwBDYlbk7hk1FoE0XJjfytgUqsz/KxASjf4OhW/FJdb+Sw+4yp3rVNT6yMXHy TIreh7sSVnxCw34oq7nUObVq7y1x94E= 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-7-iLWCNhuHNTeeE_kYgrDBBA-1; Fri, 10 Feb 2023 11:03:23 -0500 X-MC-Unique: iLWCNhuHNTeeE_kYgrDBBA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 199A8882824; Fri, 10 Feb 2023 16:03:20 +0000 (UTC) Received: from antares.redhat.com (unknown [10.39.192.68]) by smtp.corp.redhat.com (Postfix) with ESMTP id DDF1140CF8F0; Fri, 10 Feb 2023 16:03:18 +0000 (UTC) From: =?utf-8?q?Adri=C3=A1n_Moreno?= To: dev@openvswitch.org Date: Fri, 10 Feb 2023 17:03:14 +0100 Message-Id: <20230210160314.131210-2-amorenoz@redhat.com> In-Reply-To: <20230210160314.131210-1-amorenoz@redhat.com> References: <20230210160314.131210-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: i.maximets@ovn.org, simon.horman@corigine.com Subject: [ovs-dev] [PATCH v3 2/2] ipfix: make template and stats interval configurable 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: Adrian Moreno Add options to the IPFIX table configure the interval to send statistics and template information. Signed-off-by: Adrian Moreno Reviewed-by: Simon Horman --- - v3: - Removed unit tests which generate errors in Intel CI. Will submit in independent series. - v2: - Fixed a potential race condition in unit test. - v1: - Added unit test. --- NEWS | 2 ++ ofproto/ofproto-dpif-ipfix.c | 38 ++++++++++++++++++++++++++---------- ofproto/ofproto.h | 9 +++++++++ vswitchd/bridge.c | 17 ++++++++++++++++ vswitchd/vswitch.ovsschema | 12 +++++++++++- vswitchd/vswitch.xml | 20 +++++++++++++++++++ 6 files changed, 87 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index fe6055a27..4857046b8 100644 --- a/NEWS +++ b/NEWS @@ -50,6 +50,8 @@ v3.1.0 - xx xxx xxxx * Add new experimental PMD load based sleeping feature. PMD threads can request to sleep up to a user configured 'pmd-maxsleep' value under low load conditions. + - IPFIX template and statistics intervals can be configured through two new + options in the IPFIX table: 'template_interval' and 'stats_interval'. v3.0.0 - 15 Aug 2022 diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c index 1701d91e8..bae1eb9a9 100644 --- a/ofproto/ofproto-dpif-ipfix.c +++ b/ofproto/ofproto-dpif-ipfix.c @@ -140,6 +140,8 @@ struct dpif_ipfix_exporter { struct ovs_list cache_flow_start_timestamp_list; /* ipfix_flow_cache_entry. */ uint32_t cache_active_timeout; /* In seconds. */ uint32_t cache_max_flows; + uint32_t stats_interval; + uint32_t template_interval; char *virtual_obs_id; uint8_t virtual_obs_len; @@ -174,11 +176,6 @@ struct dpif_ipfix { #define IPFIX_VERSION 0x000a -/* When using UDP, IPFIX Template Records must be re-sent regularly. - * The standard default interval is 10 minutes (600 seconds). - * Cf. IETF RFC 5101 Section 10.3.6. */ -#define IPFIX_TEMPLATE_INTERVAL 600 - /* Cf. IETF RFC 5101 Section 3.1. */ OVS_PACKED( struct ipfix_header { @@ -637,6 +634,8 @@ ofproto_ipfix_bridge_exporter_options_equal( && a->sampling_rate == b->sampling_rate && a->cache_active_timeout == b->cache_active_timeout && a->cache_max_flows == b->cache_max_flows + && a->stats_interval == b->stats_interval + && a->template_interval == b->template_interval && a->enable_tunnel_sampling == b->enable_tunnel_sampling && a->enable_input_sampling == b->enable_input_sampling && a->enable_output_sampling == b->enable_output_sampling @@ -674,6 +673,8 @@ ofproto_ipfix_flow_exporter_options_equal( return (a->collector_set_id == b->collector_set_id && a->cache_active_timeout == b->cache_active_timeout && a->cache_max_flows == b->cache_max_flows + && a->stats_interval == b->stats_interval + && a->template_interval == b->template_interval && a->enable_tunnel_sampling == b->enable_tunnel_sampling && sset_equals(&a->targets, &b->targets) && nullable_string_is_equal(a->virtual_obs_id, b->virtual_obs_id)); @@ -712,6 +713,9 @@ dpif_ipfix_exporter_init(struct dpif_ipfix_exporter *exporter) ovs_list_init(&exporter->cache_flow_start_timestamp_list); exporter->cache_active_timeout = 0; exporter->cache_max_flows = 0; + exporter->stats_interval = OFPROTO_IPFIX_DEFAULT_TEMPLATE_INTERVAL; + exporter->template_interval = OFPROTO_IPFIX_DEFAULT_TEMPLATE_INTERVAL; + exporter->last_stats_sent_time = 0; exporter->virtual_obs_id = NULL; exporter->virtual_obs_len = 0; hmap_init(&exporter->domains); @@ -734,6 +738,9 @@ dpif_ipfix_exporter_clear(struct dpif_ipfix_exporter *exporter) exporter->last_stats_sent_time = 0; exporter->cache_active_timeout = 0; exporter->cache_max_flows = 0; + exporter->stats_interval = OFPROTO_IPFIX_DEFAULT_TEMPLATE_INTERVAL; + exporter->template_interval = OFPROTO_IPFIX_DEFAULT_TEMPLATE_INTERVAL; + exporter->last_stats_sent_time = 0; free(exporter->virtual_obs_id); exporter->virtual_obs_id = NULL; exporter->virtual_obs_len = 0; @@ -761,6 +768,8 @@ dpif_ipfix_exporter_set_options(struct dpif_ipfix_exporter *exporter, const struct sset *targets, const uint32_t cache_active_timeout, const uint32_t cache_max_flows, + const uint32_t stats_interval, + const uint32_t template_interval, const char *virtual_obs_id) OVS_REQUIRES(mutex) { size_t virtual_obs_len; @@ -775,6 +784,8 @@ dpif_ipfix_exporter_set_options(struct dpif_ipfix_exporter *exporter, } exporter->cache_active_timeout = cache_active_timeout; exporter->cache_max_flows = cache_max_flows; + exporter->stats_interval = stats_interval; + exporter->template_interval = template_interval; virtual_obs_len = virtual_obs_id ? strlen(virtual_obs_id) : 0; if (virtual_obs_len > IPFIX_VIRTUAL_OBS_MAX_LEN) { VLOG_WARN_RL(&rl, "Virtual obsevation ID too long (%d bytes), " @@ -1007,6 +1018,7 @@ dpif_ipfix_bridge_exporter_set_options( if (!dpif_ipfix_exporter_set_options( &exporter->exporter, &options->targets, options->cache_active_timeout, options->cache_max_flows, + options->stats_interval, options->template_interval, options->virtual_obs_id)) { return; } @@ -1022,6 +1034,14 @@ dpif_ipfix_bridge_exporter_set_options( exporter->probability = MAX(1, UINT32_MAX / exporter->options->sampling_rate); + /* Configure static observation_domain_id. */ + struct dpif_ipfix_domain *dom; + HMAP_FOR_EACH_SAFE (dom, hmap_node, &(exporter->exporter.domains)) { + dpif_ipfix_exporter_del_domain(&exporter->exporter, dom); + } + dpif_ipfix_exporter_insert_domain(&exporter->exporter, + options->obs_domain_id); + /* Run over the cache as some entries might have expired after * changing the timeouts. */ dpif_ipfix_cache_expire_now(&exporter->exporter, false); @@ -1102,6 +1122,7 @@ dpif_ipfix_flow_exporter_set_options( if (!dpif_ipfix_exporter_set_options( &exporter->exporter, &options->targets, options->cache_active_timeout, options->cache_max_flows, + options->stats_interval, options->template_interval, options->virtual_obs_id)) { return false; } @@ -2882,7 +2903,7 @@ dpif_ipfix_should_send_template(struct dpif_ipfix_exporter *exporter, observation_domain_id); } - if ((domain->last_template_set_time + IPFIX_TEMPLATE_INTERVAL) + if ((domain->last_template_set_time + exporter->template_interval) <= export_time_sec) { domain->last_template_set_time = export_time_sec; return true; @@ -2922,10 +2943,7 @@ dpif_ipfix_cache_expire(struct dpif_ipfix_exporter *exporter, break; } - /* XXX: Make frequency of the (Options) Template and Exporter Process - * Statistics transmission configurable. - * Cf. IETF RFC 5101 Section 4.3. and 10.3.6. */ - if ((exporter->last_stats_sent_time + IPFIX_TEMPLATE_INTERVAL) + if ((exporter->last_stats_sent_time + exporter->stats_interval) <= export_time_sec) { exporter->last_stats_sent_time = export_time_sec; ipfix_send_exporter_data_msg(exporter, export_time_sec); diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index 4e15167ab..c79f372bc 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -72,6 +72,11 @@ struct ofproto_sflow_options { char *control_ip; }; +/* When using UDP, IPFIX Template Records must be re-sent regularly. + * The standard default interval is 10 minutes (600 seconds). + * Cf. IETF RFC 5101 Section 10.3.6. */ +#define OFPROTO_IPFIX_DEFAULT_TEMPLATE_INTERVAL 600 + struct ofproto_ipfix_bridge_exporter_options { struct sset targets; uint32_t sampling_rate; @@ -79,6 +84,8 @@ struct ofproto_ipfix_bridge_exporter_options { uint32_t obs_point_id; /* Bridge-wide Observation Point ID. */ uint32_t cache_active_timeout; uint32_t cache_max_flows; + uint32_t template_interval; + uint32_t stats_interval; bool enable_tunnel_sampling; bool enable_input_sampling; bool enable_output_sampling; @@ -90,6 +97,8 @@ struct ofproto_ipfix_flow_exporter_options { struct sset targets; uint32_t cache_active_timeout; uint32_t cache_max_flows; + uint32_t template_interval; + uint32_t stats_interval; bool enable_tunnel_sampling; char *virtual_obs_id; }; diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index abf2afe57..307a51527 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -1542,6 +1542,17 @@ bridge_configure_ipfix(struct bridge *br) if (be_cfg->cache_max_flows) { be_opts.cache_max_flows = *be_cfg->cache_max_flows; } + if (be_cfg->stats_interval) { + be_opts.stats_interval = *be_cfg->stats_interval; + } else { + be_opts.stats_interval = OFPROTO_IPFIX_DEFAULT_TEMPLATE_INTERVAL; + } + if (be_cfg->template_interval) { + be_opts.template_interval = *be_cfg->template_interval; + } else { + be_opts.template_interval = + OFPROTO_IPFIX_DEFAULT_TEMPLATE_INTERVAL; + } be_opts.enable_tunnel_sampling = smap_get_bool(&be_cfg->other_config, "enable-tunnel-sampling", true); @@ -1570,6 +1581,12 @@ bridge_configure_ipfix(struct bridge *br) ? *fe_cfg->ipfix->cache_active_timeout : 0; opts->cache_max_flows = fe_cfg->ipfix->cache_max_flows ? *fe_cfg->ipfix->cache_max_flows : 0; + opts->stats_interval = fe_cfg->ipfix->stats_interval + ? *fe_cfg->ipfix->stats_interval + : OFPROTO_IPFIX_DEFAULT_TEMPLATE_INTERVAL; + opts->template_interval = fe_cfg->ipfix->template_interval + ? *fe_cfg->ipfix->template_interval + : OFPROTO_IPFIX_DEFAULT_TEMPLATE_INTERVAL; opts->enable_tunnel_sampling = smap_get_bool( &fe_cfg->ipfix->other_config, "enable-tunnel-sampling", true); diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema index 1a49cdffe..8ab609dfb 100644 --- a/vswitchd/vswitch.ovsschema +++ b/vswitchd/vswitch.ovsschema @@ -1,6 +1,6 @@ {"name": "Open_vSwitch", "version": "8.3.1", - "cksum": "3012963480 26720", + "cksum": "142028610 27127", "tables": { "Open_vSwitch": { "columns": { @@ -531,6 +531,16 @@ "minInteger": 0, "maxInteger": 4294967295}, "min": 0, "max": 1}}, + "stats_interval": { + "type": {"key": {"type": "integer", + "minInteger": 1, + "maxInteger": 3600}, + "min": 0, "max": 1}}, + "template_interval": { + "type": {"key": {"type": "integer", + "minInteger": 1, + "maxInteger": 3600}, + "min": 0, "max": 1}}, "other_config": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}, diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 64f23302d..9c7bdb218 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -6592,6 +6592,26 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \ disabled. + +

+ Interval (in seconds) for sending IPFIX exporting process statistics + according to IETF RFC 5101 Section 4.3. +

+

+ Default value is 600 +

+
+ + +

+ Interval (in seconds) for sending IPFIX Template information for each + Observation Domain ID. +

+

+ Default value is 600 +

+
+