Thank you Ales. -Ketan
On Thu, Jan 22, 2026 at 2:03 AM Ales Musil <[email protected]> wrote: > > > On Thu, Jan 22, 2026 at 12:04 AM Ketan Supanekar via dev < > [email protected]> wrote: > >> Add DNS query statistics tracking using OVS coverage counters in >> ovn-controller for observability into DNS query processing. >> >> Tracked metrics include: >> - Total queries processed >> - Query types (A, AAAA, PTR, ANY, Other) >> - Cache performance (hits/misses) >> - Responses sent >> - Error conditions (truncated, parse failures, etc.) >> >> Statistics can be queried using: >> ovn-appctl -t ovn-controller coverage/read-counter <counter_name> >> ovn-appctl -t ovn-controller coverage/show >> >> The implementation uses coverage counter verification into existing DNS >> tests >> in tests/ovn.at. >> >> Signed-off-by: Ketan Supanekar <[email protected]> >> --- >> > > Hello Ketan, > > thank you for v6. > > >> NEWS | 5 +++++ >> controller/pinctrl.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ >> tests/ovn.at | 28 ++++++++++++++++++++++++++ >> 3 files changed, 81 insertions(+) >> >> diff --git a/NEWS b/NEWS >> index 9883fb81d..dc9d28f2c 100644 >> --- a/NEWS >> +++ b/NEWS >> @@ -1,5 +1,10 @@ >> Post v25.09.0 >> ------------- >> + - Added DNS query statistics tracking in ovn-controller using OVS >> coverage >> + counters. Statistics can be queried using "ovn-appctl -t >> ovn-controller >> + coverage/read-counter <counter_name>" or "coverage/show". Tracked >> metrics >> + include total queries, query types (A, AAAA, PTR, ANY, Other), cache >> + performance (hits/misses), responses sent, and error conditions. >> - Added support for TLS Server Name Indication (SNI) with the new >> --ssl-server-name option in OVN utilities and daemons. This allows >> specifying the server name for SNI, which is useful when connecting >> diff --git a/controller/pinctrl.c b/controller/pinctrl.c >> index 6f7ae4037..ab8a0a37c 100644 >> --- a/controller/pinctrl.c >> +++ b/controller/pinctrl.c >> @@ -391,6 +391,22 @@ COVERAGE_DEFINE(pinctrl_drop_put_vport_binding); >> COVERAGE_DEFINE(pinctrl_notify_main_thread); >> COVERAGE_DEFINE(pinctrl_total_pin_pkts); >> >> +/* DNS query statistics - thread-safe coverage counters */ >> +COVERAGE_DEFINE(dns_query_total); >> +COVERAGE_DEFINE(dns_query_type_a); >> +COVERAGE_DEFINE(dns_query_type_aaaa); >> +COVERAGE_DEFINE(dns_query_type_ptr); >> +COVERAGE_DEFINE(dns_query_type_any); >> +COVERAGE_DEFINE(dns_query_type_other); >> +COVERAGE_DEFINE(dns_cache_hit); >> +COVERAGE_DEFINE(dns_cache_miss); >> +COVERAGE_DEFINE(dns_error_truncated); >> +COVERAGE_DEFINE(dns_skipped_not_request); >> +COVERAGE_DEFINE(dns_error_no_query); >> +COVERAGE_DEFINE(dns_error_parse_failure); >> +COVERAGE_DEFINE(dns_unsupported_ovn_owned); >> +COVERAGE_DEFINE(dns_response_sent); >> + >> struct empty_lb_backends_event { >> struct hmap_node hmap_node; >> long long int timestamp; >> @@ -3366,6 +3382,9 @@ pinctrl_handle_dns_lookup( >> uint32_t success = 0; >> bool send_refuse = false; >> >> + /* Track total DNS queries received */ >> + COVERAGE_INC(dns_query_total); >> + >> /* Parse result field. */ >> const struct mf_field *f; >> enum ofperr ofperr = nx_pull_header(userdata, NULL, &f, NULL); >> @@ -3392,6 +3411,7 @@ pinctrl_handle_dns_lookup( >> /* Check that the packet stores at least the minimal headers. */ >> if (dp_packet_l4_size(pkt_in) < (UDP_HEADER_LEN + DNS_HEADER_LEN)) { >> VLOG_WARN_RL(&rl, "truncated dns packet"); >> + COVERAGE_INC(dns_error_truncated); >> goto exit; >> } >> >> @@ -3399,17 +3419,20 @@ pinctrl_handle_dns_lookup( >> struct dns_header const *in_dns_header = >> dp_packet_get_udp_payload(pkt_in); >> if (!in_dns_header) { >> VLOG_WARN_RL(&rl, "truncated dns packet"); >> + COVERAGE_INC(dns_error_truncated); >> goto exit; >> } >> >> /* Check if it is DNS request or not */ >> if (in_dns_header->lo_flag & 0x80) { >> /* It's a DNS response packet which we are not interested in */ >> + COVERAGE_INC(dns_skipped_not_request); >> goto exit; >> } >> >> /* Check if at least one query request is present */ >> if (!in_dns_header->qdcount) { >> + COVERAGE_INC(dns_error_no_query); >> goto exit; >> } >> >> @@ -3431,6 +3454,7 @@ pinctrl_handle_dns_lookup( >> uint8_t label_len = in_dns_data[idx++]; >> if (in_dns_data + idx + label_len > end) { >> ds_destroy(&query_name); >> + COVERAGE_INC(dns_error_parse_failure); >> goto exit; >> } >> ds_put_buffer(&query_name, (const char *) in_dns_data + idx, >> label_len); >> @@ -3449,6 +3473,26 @@ pinctrl_handle_dns_lookup( >> } >> >> uint16_t query_type = ntohs(get_unaligned_be16((void *) >> in_dns_data)); >> + >> + /* Track query type statistics */ >> + switch (query_type) { >> + case DNS_QUERY_TYPE_A: >> + COVERAGE_INC(dns_query_type_a); >> + break; >> + case DNS_QUERY_TYPE_AAAA: >> + COVERAGE_INC(dns_query_type_aaaa); >> + break; >> + case DNS_QUERY_TYPE_PTR: >> + COVERAGE_INC(dns_query_type_ptr); >> + break; >> + case DNS_QUERY_TYPE_ANY: >> + COVERAGE_INC(dns_query_type_any); >> + break; >> + default: >> + COVERAGE_INC(dns_query_type_other); >> + break; >> + } >> + >> /* Supported query types - A, AAAA, ANY and PTR */ >> if (!(query_type == DNS_QUERY_TYPE_A || query_type == >> DNS_QUERY_TYPE_AAAA >> || query_type == DNS_QUERY_TYPE_ANY >> @@ -3467,8 +3511,10 @@ pinctrl_handle_dns_lookup( >> &ovn_owned); >> ds_destroy(&query_name); >> if (!answer_data) { >> + COVERAGE_INC(dns_cache_miss); >> goto exit; >> } >> + COVERAGE_INC(dns_cache_hit); >> >> >> uint16_t ancount = 0; >> @@ -3511,6 +3557,7 @@ pinctrl_handle_dns_lookup( >> if (ovn_owned && (query_type == DNS_QUERY_TYPE_AAAA || >> query_type == DNS_QUERY_TYPE_A) && !ancount) { >> send_refuse = true; >> + COVERAGE_INC(dns_unsupported_ovn_owned); >> } >> >> destroy_lport_addresses(&ip_addrs); >> @@ -3595,6 +3642,7 @@ pinctrl_handle_dns_lookup( >> pin->packet_len = dp_packet_size(&pkt_out); >> >> success = 1; >> + COVERAGE_INC(dns_response_sent); >> exit: >> if (!ofperr) { >> union mf_subvalue sv; >> diff --git a/tests/ovn.at b/tests/ovn.at >> index 445a74ce5..d657bd2e1 100644 >> --- a/tests/ovn.at >> +++ b/tests/ovn.at >> @@ -12136,6 +12136,34 @@ reset_pcap_file hv1-vif1 hv1/vif1 >> reset_pcap_file hv1-vif2 hv1/vif2 >> rm -f 1.expected >> rm -f 2.expected >> + >> +AS_BOX([Verify DNS coverage counters]) >> +# The test has sent multiple DNS queries of various types, verify >> counters >> +# Total queries should be > 0 >> +AT_CHECK([as hv1 ovn-appctl -t ovn-controller coverage/read-counter >> dns_query_total | awk '{if ($1 > 0) print "ok"}'], [0], [ok >> +]) >> +# A record queries (multiple A queries sent) >> +AT_CHECK([as hv1 ovn-appctl -t ovn-controller coverage/read-counter >> dns_query_type_a | awk '{if ($1 > 0) print "ok"}'], [0], [ok >> +]) >> +# AAAA record queries (IPv6 queries sent) >> +AT_CHECK([as hv1 ovn-appctl -t ovn-controller coverage/read-counter >> dns_query_type_aaaa | awk '{if ($1 > 0) print "ok"}'], [0], [ok >> +]) >> +# PTR record queries (reverse DNS lookups sent) >> +AT_CHECK([as hv1 ovn-appctl -t ovn-controller coverage/read-counter >> dns_query_type_ptr | awk '{if ($1 > 0) print "ok"}'], [0], [ok >> +]) >> +# ANY record queries (vm1_ipv4_v6 queries sent) >> +AT_CHECK([as hv1 ovn-appctl -t ovn-controller coverage/read-counter >> dns_query_type_any | awk '{if ($1 > 0) print "ok"}'], [0], [ok >> +]) >> +# Cache hits (repeated queries) >> +AT_CHECK([as hv1 ovn-appctl -t ovn-controller coverage/read-counter >> dns_cache_hit | awk '{if ($1 > 0) print "ok"}'], [0], [ok >> +]) >> +# Cache misses (queries for non-existent records) >> +AT_CHECK([as hv1 ovn-appctl -t ovn-controller coverage/read-counter >> dns_cache_miss | awk '{if ($1 > 0) print "ok"}'], [0], [ok >> +]) >> +# Responses sent >> +AT_CHECK([as hv1 ovn-appctl -t ovn-controller coverage/read-counter >> dns_response_sent | awk '{if ($1 > 0) print "ok"}'], [0], [ok >> +]) >> + >> > > The test was a bit flaky, so I have adjusted it to use OVS_WAIT_FOR_OUTPUT > instead. > > OVN_CLEANUP([hv1]) >> >> AT_CLEANUP >> -- >> 2.52.0 >> >> _______________________________________________ >> dev mailing list >> [email protected] >> https://mail.openvswitch.org/mailman/listinfo/ovs-dev >> >> > With that change I went ahead and merged this into main, I have also added > you into the AUTHORS file. > > Regards, > Ales > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
