On Wed, Jan 21, 2026 at 12:57 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. > > Coverage counters provide a standardized way to track events and can > be queried using the coverage/read-counter and coverage/show commands. > > The following DNS-related coverage counters are added: > - dns_query_total: Total number of DNS queries received > - dns_query_type_a: Number of A (IPv4) record queries > - dns_query_type_aaaa: Number of AAAA (IPv6) record queries > - dns_query_type_ptr: Number of PTR (reverse lookup) queries > - dns_query_type_any: Number of ANY record queries > - dns_query_type_other: Number of other query types > - dns_cache_hit: Number of cache hits > - dns_cache_miss: Number of cache misses > - dns_response_sent: Number of DNS responses sent > > Coverage counters can be viewed using: > ovn-appctl -t ovn-controller coverage/show > ovn-appctl -t ovn-controller coverage/read-counter <counter_name> > > Signed-off-by: Ketan Supanekar <[email protected]> > --- > Hi Ketan, thank you for the v5. We should add a NEWS entry. I also have one small comment down below. > controller/pinctrl.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > > diff --git a/controller/pinctrl.c b/controller/pinctrl.c > index 6f7ae4037..81f677942 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,20 @@ pinctrl_handle_dns_lookup( > } > > uint16_t query_type = ntohs(get_unaligned_be16((void *) in_dns_data)); > + > + /* Track query type statistics */ > + if (query_type == DNS_QUERY_TYPE_A) { > + COVERAGE_INC(dns_query_type_a); > + } else if (query_type == DNS_QUERY_TYPE_AAAA) { > + COVERAGE_INC(dns_query_type_aaaa); > + } else if (query_type == DNS_QUERY_TYPE_PTR) { > + COVERAGE_INC(dns_query_type_ptr); > + } else if (query_type == DNS_QUERY_TYPE_ANY) { > + COVERAGE_INC(dns_query_type_any); > + } else { > + COVERAGE_INC(dns_query_type_other); > + } > It would be better to use a switch here. > + > /* 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 +3505,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 +3551,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 +3636,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; > -- > 2.52.0 > > _______________________________________________ > dev mailing list > [email protected] > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > Regards, Ales _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
