From patchwork Tue Oct 18 12:02:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Moreno X-Patchwork-Id: 1691485 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::137; helo=smtp4.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=WmSc0xfJ; dkim-atps=neutral Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (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 4MsCCt63gPz1ygT for ; Tue, 18 Oct 2022 23:02:34 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 8CFAA41944; Tue, 18 Oct 2022 12:02:32 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 8CFAA41944 Authentication-Results: smtp4.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=WmSc0xfJ 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 pUBDfOdx6_qT; Tue, 18 Oct 2022 12:02:30 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id 9244B41937; Tue, 18 Oct 2022 12:02:29 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 9244B41937 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id CDA7AC0077; Tue, 18 Oct 2022 12:02:27 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id AC7F5C002D for ; Tue, 18 Oct 2022 12:02:22 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 879F3606F9 for ; Tue, 18 Oct 2022 12:02:22 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 879F3606F9 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=WmSc0xfJ 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 56-Jft_HF9i8 for ; Tue, 18 Oct 2022 12:02:21 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 5BE9961007 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 5BE9961007 for ; Tue, 18 Oct 2022 12:02:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1666094540; 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=e+QbFPfN53sFujv5hKFYifO4VexIudCnFnUNVN5FQSs=; b=WmSc0xfJwiazIqzOud10lDIDGdLjBfnCZAEI5HPgrHXAvNI70dKBt9CoFfTaq6z6Y2pQ79 SfBFYZbNhr3UDaZA9hl5CCEN+U/RFH01espRi6evjeBFTHALeG3eglKwBhl+Pot81il5ih 29WOnPh6lDTiqZLeOZlb+pydlDew64Q= 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-426-pCzJ6QAEO8miKnUPCJxh7w-1; Tue, 18 Oct 2022 08:02:19 -0400 X-MC-Unique: pCzJ6QAEO8miKnUPCJxh7w-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 07D95811E81 for ; Tue, 18 Oct 2022 12:02:19 +0000 (UTC) Received: from amorenoz.users.ipa.redhat.com (unknown [10.39.193.255]) by smtp.corp.redhat.com (Postfix) with ESMTP id 13A7740C2065; Tue, 18 Oct 2022 12:02:17 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Tue, 18 Oct 2022 14:02:13 +0200 Message-Id: <20221018120214.1106988-2-amorenoz@redhat.com> In-Reply-To: <20221018120214.1106988-1-amorenoz@redhat.com> References: <20221018120214.1106988-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 Subject: [ovs-dev] [PATCH 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" 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 --- ofproto/ofproto-dpif-ipfix.c | 130 ++++++++++++++++++++++++++++------- 1 file changed, 107 insertions(+), 23 deletions(-) diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c index 742eed399..98a3f9b71 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.*/ + uint32_t obs_domain_id; + 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 hmap domains; /* Contains struct dpif_ipfix_domain. */ + 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,40 @@ 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) +{ + struct dpif_ipfix_domain *dom; + HMAP_FOR_EACH_IN_BUCKET (dom, hmap_node, hash_int(domain_id, 0), + &exporter->domains) { + if (dom->obs_domain_id == domain_id) { + 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->obs_domain_id = domain_id; + 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 +962,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 +972,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 +982,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 +1058,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 +1067,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 +1077,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 +1128,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 +2058,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 +2870,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 +2925,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 +2967,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 Tue Oct 18 12:02:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Moreno X-Patchwork-Id: 1691486 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=HC+IB+3T; 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 4MsCCx5Hq8z1ygT for ; Tue, 18 Oct 2022 23:02:37 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 05DA0833FB; Tue, 18 Oct 2022 12:02:35 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 05DA0833FB 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=HC+IB+3T 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 UrgrUL6rLstN; Tue, 18 Oct 2022 12:02:33 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 7065283337; Tue, 18 Oct 2022 12:02:31 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 7065283337 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id CB7E9C0082; Tue, 18 Oct 2022 12:02:28 +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 DCFECC002D for ; Tue, 18 Oct 2022 12:02:23 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id AE3E7606F9 for ; Tue, 18 Oct 2022 12:02:23 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org AE3E7606F9 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=HC+IB+3T 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 yAiZr3znXCxA for ; Tue, 18 Oct 2022 12:02:22 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 8CD596101B 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 8CD596101B for ; Tue, 18 Oct 2022 12:02:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1666094541; 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=4wtrUCObFNrX8qxOYmhbCBNPGtXF6mmO0qs+3KA4G1U=; b=HC+IB+3TanPBhcywlTIVPDWiwIK2b48uDJzT9v++MJrl5XlF1fgKdvxYXhaqLj0Ng2lOqp XRI88fiJJd8JL8udTTwkaTl9Bnj+uBA+vRHnXp8e2N9SUgwSeWfaojtF5IGfT/CMqxdMG4 DFWSS56i8As0+NeKS6wWRZ1YXL7Yr+Y= 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-414-wCQtfU4VNoOEgVkOKEqiIw-1; Tue, 18 Oct 2022 08:02:20 -0400 X-MC-Unique: wCQtfU4VNoOEgVkOKEqiIw-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 F3EBE85A583 for ; Tue, 18 Oct 2022 12:02:19 +0000 (UTC) Received: from amorenoz.users.ipa.redhat.com (unknown [10.39.193.255]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4B87940C206B; Tue, 18 Oct 2022 12:02:19 +0000 (UTC) From: Adrian Moreno To: dev@openvswitch.org Date: Tue, 18 Oct 2022 14:02:14 +0200 Message-Id: <20221018120214.1106988-3-amorenoz@redhat.com> In-Reply-To: <20221018120214.1106988-1-amorenoz@redhat.com> References: <20221018120214.1106988-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 Subject: [ovs-dev] [PATCH 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" Add options to the IPFIX table configure the interval to send statistics and template information. Signed-off-by: Adrian Moreno Acked-by: Mike Pattrick --- NEWS | 2 ++ ofproto/ofproto-dpif-ipfix.c | 38 ++++++++++++++++++++++++++---------- ofproto/ofproto.h | 9 +++++++++ vswitchd/bridge.c | 12 ++++++++++++ vswitchd/vswitch.ovsschema | 12 +++++++++++- vswitchd/vswitch.xml | 20 +++++++++++++++++++ 6 files changed, 82 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index ff77ee404..119f8312f 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,8 @@ Post-v3.0.0 bug and CVE fixes addressed since its release. If a user wishes to benefit from these fixes it is recommended to use DPDK 21.11.2. + - 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 98a3f9b71..ae12f1e5f 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), " @@ -1010,6 +1021,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; } @@ -1025,6 +1037,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); @@ -1105,6 +1125,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; } @@ -2885,7 +2906,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; @@ -2925,10 +2946,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 25ce45e3d..5c940ca2a 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -1542,6 +1542,12 @@ bridge_configure_ipfix(struct bridge *br) if (be_cfg->cache_max_flows) { be_opts.cache_max_flows = *be_cfg->cache_max_flows; } + be_opts.stats_interval = be_cfg->stats_interval + ? *be_cfg->stats_interval + : OFPROTO_IPFIX_DEFAULT_TEMPLATE_INTERVAL; + be_opts.template_interval = be_cfg->template_interval + ? *be_cfg->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 +1576,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 4873cfde7..6a0ab7bbc 100644 --- a/vswitchd/vswitch.ovsschema +++ b/vswitchd/vswitch.ovsschema @@ -1,6 +1,6 @@ {"name": "Open_vSwitch", "version": "8.3.0", - "cksum": "3781850481 26690", + "cksum": "4031209732 27097", "tables": { "Open_vSwitch": { "columns": { @@ -530,6 +530,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 36388e3c4..ac9fab03f 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -6569,6 +6569,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 +

+
+