On Tue, Sep 15, 2026 at 11:06 AM Dumitru Ceara via dev <
[email protected]> wrote:

> OVN's native DNS responder answered every A/AAAA/ANY/PTR query with a
> hardcoded resource-record TTL of 3600 seconds.  In dynamic environments
> caching a DNS response for 1h is probably not desirable, in any case
> it's better if the TTL is operator configurable.
>
> Add a per-row "options:ttl" key on the NB DNS table.  ovn-northd
> validates the value in sync_dns_entries() and, like the existing
> "ovn-owned" option, propagates it to the SB DNS table.  ovn-controller
> reads the option back and uses it when building DNS replies for
> that record.
>
> The default remains 3600 seconds.
>
> Reported-at: https://redhat.atlassian.net/browse/FDP-2956
> Assisted-by: Qwen3.8-27B-FP8, opencode
> Signed-off-by: Dumitru Ceara <[email protected]>
> ---

 NEWS                 |   2 +
>  controller/ovn-dns.c |   7 ++-
>  controller/ovn-dns.h |   2 +-
>  controller/pinctrl.c |  27 +++++----
>  lib/ovn-l7.h         |   1 +
>  northd/northd.c      |  22 +++++++
>  ovn-nb.xml           |  14 +++++
>  ovn-sb.xml           |   9 +++
>  tests/ovn-northd.at  |  60 +++++++++++++++++++
>  tests/ovn.at         | 138 +++++++++++++++++++++++++++++++++++++++++++
>  10 files changed, 268 insertions(+), 14 deletions(-)
>
> diff --git a/NEWS b/NEWS
> index aadf6416d2..f1c56dd147 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -1,5 +1,7 @@
>  Post v26.09.0
>  --------------
> +   - Added a new "options:ttl" key on the NB DNS table to make the TTL of
> +     DNS replies from OVN's native DNS resolver configurable per row.
>     - Removed implementations of the commit_ecmp_nh, chk_ecmp_nh, and
>       chk_ecmp_nh_mac actions from the code.
>     - Mark tunnel ports as transient (other_config:transient=true) when the
> diff --git a/controller/ovn-dns.c b/controller/ovn-dns.c
> index bfeef5a747..416f399d78 100644
> --- a/controller/ovn-dns.c
> +++ b/controller/ovn-dns.c
> @@ -22,6 +22,7 @@
>  #include "openvswitch/vlog.h"
>
>  /* OVN includes. */
> +#include "lib/ovn-l7.h"
>  #include "lib/ovn-sb-idl.h"
>  #include "ovn-dns.h"
>
> @@ -112,12 +113,14 @@ ovn_dns_update_cache(const struct sbrec_dns_table
> *dns_table)
>  }
>
>  const char *
> -ovn_dns_lookup(const char *query_name, uint64_t dp_key, bool *ovn_owned)
> +ovn_dns_lookup(const char *query_name, uint64_t dp_key, bool *ovn_owned,
> +               uint32_t *ttl)
>  {
>      const char *answer_data = NULL;
>      struct dns_data *dns_data;
>
>      *ovn_owned = false;
> +    *ttl = DNS_DEFAULT_RR_TTL;
>
>      CMAP_FOR_EACH (dns_data, cmap_node, &dns_cache_) {
>          for (size_t i = 0; i < dns_data->n_dps; i++) {
> @@ -131,6 +134,8 @@ ovn_dns_lookup(const char *query_name, uint64_t
> dp_key, bool *ovn_owned)
>                  if (answer_data) {
>                      *ovn_owned = smap_get_bool(&dns_data->options,
> "ovn-owned",
>                                                 false);
> +                    *ttl = smap_get_uint(&dns_data->options, "ttl",
> +                                         DNS_DEFAULT_RR_TTL);
>                      break;
>                  }
>              }
> diff --git a/controller/ovn-dns.h b/controller/ovn-dns.h
> index 8eca6ad0eb..6c86ccc858 100644
> --- a/controller/ovn-dns.h
> +++ b/controller/ovn-dns.h
> @@ -24,6 +24,6 @@ void ovn_dns_cache_destroy(void);
>  void ovn_dns_sync_cache(const struct sbrec_dns_table *);
>  void ovn_dns_update_cache(const struct sbrec_dns_table *);
>  const char *ovn_dns_lookup(const char *query_name, uint64_t dp_key,
> -                           bool *ovn_owned);
> +                           bool *ovn_owned, uint32_t *ttl);
>
>  #endif /* OVN_DNS_H */
> diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> index 333dcedb6e..e100912510 100644
> --- a/controller/pinctrl.c
> +++ b/controller/pinctrl.c
> @@ -3394,22 +3394,22 @@ put_be32(struct ofpbuf *buf, ovs_be32 x)
>  static void
>  dns_build_base_answer(
>      struct ofpbuf *dns_answer, const uint8_t *in_queryname,
> -    uint16_t query_length, int query_type)
> +    uint16_t query_length, int query_type, uint32_t ttl)
>  {
>      ofpbuf_put(dns_answer, in_queryname, query_length);
>      put_be16(dns_answer, htons(query_type));
>      put_be16(dns_answer, htons(DNS_CLASS_IN));
> -    put_be32(dns_answer, htonl(DNS_DEFAULT_RR_TTL));
> +    put_be32(dns_answer, htonl(ttl));
>  }
>
>  /* Populates dns_answer struct with a TYPE A answer. */
>  static void
>  dns_build_a_answer(
>      struct ofpbuf *dns_answer, const uint8_t *in_queryname,
> -    uint16_t query_length, const ovs_be32 addr)
> +    uint16_t query_length, const ovs_be32 addr, uint32_t ttl)
>  {
>      dns_build_base_answer(dns_answer, in_queryname, query_length,
> -                          DNS_QUERY_TYPE_A);
> +                          DNS_QUERY_TYPE_A, ttl);
>      put_be16(dns_answer, htons(sizeof(ovs_be32)));
>      put_be32(dns_answer, addr);
>  }
> @@ -3418,10 +3418,10 @@ dns_build_a_answer(
>  static void
>  dns_build_aaaa_answer(
>      struct ofpbuf *dns_answer, const uint8_t *in_queryname,
> -    uint16_t query_length, const struct in6_addr *addr)
> +    uint16_t query_length, const struct in6_addr *addr, uint32_t ttl)
>  {
>      dns_build_base_answer(dns_answer, in_queryname, query_length,
> -                          DNS_QUERY_TYPE_AAAA);
> +                          DNS_QUERY_TYPE_AAAA, ttl);
>      put_be16(dns_answer, htons(sizeof(*addr)));
>      ofpbuf_put(dns_answer, addr, sizeof(*addr));
>  }
> @@ -3430,10 +3430,10 @@ dns_build_aaaa_answer(
>  static void
>  dns_build_ptr_answer(
>      struct ofpbuf *dns_answer, const uint8_t *in_queryname,
> -    uint16_t query_length, const char *answer_data)
> +    uint16_t query_length, const char *answer_data, uint32_t ttl)
>  {
>      dns_build_base_answer(dns_answer, in_queryname, query_length,
> -                          DNS_QUERY_TYPE_PTR);
> +                          DNS_QUERY_TYPE_PTR, ttl);
>
>      size_t encoded_len = 0;
>      char *encoded = encode_fqdn_string(answer_data, &encoded_len);
> @@ -3586,8 +3586,9 @@ pinctrl_handle_dns_lookup(
>
>      uint64_t dp_key = ntohll(pin->flow_metadata.flow.metadata);
>      bool ovn_owned = false;
> +    uint32_t ttl = DNS_DEFAULT_RR_TTL;
>      const char *answer_data = ovn_dns_lookup(ds_cstr(&query_name), dp_key,
> -                                             &ovn_owned);
> +                                             &ovn_owned, &ttl);
>      ds_destroy(&query_name);
>      if (!answer_data) {
>          COVERAGE_INC(dns_cache_miss);
> @@ -3601,7 +3602,8 @@ pinctrl_handle_dns_lookup(
>      struct ofpbuf dns_answer = OFPBUF_STUB_INITIALIZER(dns_ans_stub);
>
>      if (query_type == DNS_QUERY_TYPE_PTR) {
> -        dns_build_ptr_answer(&dns_answer, in_queryname, idx, answer_data);
> +        dns_build_ptr_answer(&dns_answer, in_queryname, idx, answer_data,
> +                             ttl);
>          ancount++;
>      } else {
>          struct lport_addresses ip_addrs;
> @@ -3617,7 +3619,7 @@ pinctrl_handle_dns_lookup(
>              query_type == DNS_QUERY_TYPE_ANY) {
>              for (size_t i = 0; i < ip_addrs.n_ipv4_addrs; i++) {
>                  ovs_be32 addr = ip_addrs.ipv4_addrs[ipv4_order[i]].addr;
> -                dns_build_a_answer(&dns_answer, in_queryname, idx, addr);
> +                dns_build_a_answer(&dns_answer, in_queryname, idx, addr,
> ttl);
>                  ancount++;
>              }
>          }
> @@ -3627,7 +3629,8 @@ pinctrl_handle_dns_lookup(
>              for (size_t i = 0; i < ip_addrs.n_ipv6_addrs; i++) {
>                  struct in6_addr *addr =
>                      &ip_addrs.ipv6_addrs[ipv6_order[i]].addr;
> -                dns_build_aaaa_answer(&dns_answer, in_queryname, idx,
> addr);
> +                dns_build_aaaa_answer(&dns_answer, in_queryname, idx,
> addr,
> +                                      ttl);
>                  ancount++;
>              }
>          }
> diff --git a/lib/ovn-l7.h b/lib/ovn-l7.h
> index 5f52e1791f..58b8a4a1c3 100644
> --- a/lib/ovn-l7.h
> +++ b/lib/ovn-l7.h
> @@ -52,6 +52,7 @@ BUILD_ASSERT_DECL(BFD_PACKET_LEN == sizeof(struct
> bfd_msg));
>
>  #define DNS_CLASS_IN            0x01
>  #define DNS_DEFAULT_RR_TTL      3600
> +#define DNS_MAX_RR_TTL          2147483647U /* 2^31-1, per RFC 2181. */
>
>  /* Generic options map which is used to store dhcpv4 opts and dhcpv6
> opts. */
>  struct gen_opts_map {
> diff --git a/northd/northd.c b/northd/northd.c
> index 1c9e5d0703..a0b90646f0 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -21618,6 +21618,28 @@ sync_dns_entries(struct ovsdb_idl_txn *ovnsb_txn,
>                                         "ovn-owned", false);
>          smap_replace(&options, "ovn-owned",
>                   ovn_owned? "true" : "false");
> +
> +        /* Sync the per-row TTL option to SB.  Only values in the range
> +         * 0..DNS_MAX_RR_TTL are valid.
> +         */
> +        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
> +        const char *ttl = smap_get(&dns_info->nb_dns->options, "ttl");
> +        if (ttl) {
> +            unsigned int ttl_val;
> +            if (str_to_uint(ttl, 10, &ttl_val) && ttl_val <=
> DNS_MAX_RR_TTL) {
> +                smap_replace(&options, "ttl", ttl);
> +            } else {
> +                VLOG_WARN_RL(&rl, "Ignoring invalid \"options:ttl\" %s "
> +                                  "(expected 0-%"PRIu32") for DNS record "
> +                                  UUID_FMT, ttl, DNS_MAX_RR_TTL,
> +
> UUID_ARGS(&dns_info->nb_dns->header_.uuid));
> +                smap_remove(&options, "ttl");
> +            }
> +        } else {
> +            /* Remove any stale value so the default TTL is used. */
> +            smap_remove(&options, "ttl");
> +        }
> +
>          sbrec_dns_set_options(dns_info->sb_dns, &options);
>          smap_destroy(&options);
>
> diff --git a/ovn-nb.xml b/ovn-nb.xml
> index 57b81d4b44..078bd60687 100644
> --- a/ovn-nb.xml
> +++ b/ovn-nb.xml
> @@ -6464,6 +6464,20 @@ or
>        </p>
>      </column>
>
> +    <column name="options" key="ttl">
> +      The time-to-live (in seconds) set in the TTL field of DNS replies
> +      generated by OVN for the records in this row.
> +
> +      <p>
> +        The default is <code>3600</code> seconds.  Set this to a smaller
> +        value in dynamic environments (e.g. VM fail-over) so that
> +        clients do not cache stale records for long.  Valid values are 0
> +        to 2147483647 <(214)%20748-3647> (inclusive).  An invalid or
> out-of-range value is
> +        rejected with a warning by ovn-northd and the default of 3600
> +        seconds is used instead.
> +      </p>
> +    </column>
> +
>      <column name="external_ids">
>        See <em>External IDs</em> at the beginning of this document.
>      </column>
> diff --git a/ovn-sb.xml b/ovn-sb.xml
> index 808694fe0a..2096fc3e3c 100644
> --- a/ovn-sb.xml
> +++ b/ovn-sb.xml
> @@ -5015,6 +5015,15 @@ tcp.flags = RST;
>        will be answered locally by either an IP address or
>        <code>DNS rejection</code>.
>  </column>
> +
> +    <column name="options" key="ttl">
> +      The time-to-live (in seconds) set in the TTL field of DNS replies
> for
> +      the records in this row.  This is synced automatically by ovn-northd
> +      from the corresponding
> +      <ref table="DNS" column="options" key="ttl" db="OVN_Northbound"/>
> +      option and should not be set directly.
> +    </column>
> +
>      <group title="Common Columns">
>        <column name="external_ids">
>          See <em>External IDs</em> at the beginning of this document.
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index af231fb871..7d9bd68541 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -12354,6 +12354,66 @@ wait_row_count sb:DNS 0
>  AT_CLEANUP
>  ])
>
> +OVN_FOR_EACH_NORTHD_NO_HV([
> +AT_SETUP([DNS options:ttl synchronization to SB])
> +ovn_start
> +
> +check ovn-nbctl ls-add sw0
> +dns_uuid=$(ovn-nbctl create DNS records={})
> +check ovn-nbctl set DNS $dns_uuid records:vm1.ovn.org="10.0.0.4"
> +check ovn-nbctl set Logical_Switch sw0 dns_records="$dns_uuid"
> +check ovn-nbctl --wait=sb sync
> +
> +wait_row_count sb:DNS 1
> +sb_dns_uuid=$(fetch_column sb:DNS _uuid)
> +
> +# Without "options:ttl", the key is not present in SB.
> +AT_CHECK([test -z "$(ovn-sbctl --if-exists get DNS $sb_dns_uuid
> options:ttl)"])
> +
> +# Valid values are synced to SB, including the boundary values 0 and the
> +# RFC 2181 maximum of 2147483647 <(214)%20748-3647>.
> +check ovn-nbctl --wait=sb set DNS $dns_uuid options:ttl=30
> +AT_CHECK([ovn-sbctl get DNS $sb_dns_uuid options:ttl], [0], [dnl
> +"30"
> +])
> +
> +check ovn-nbctl --wait=sb set DNS $dns_uuid options:ttl=0
> +AT_CHECK([ovn-sbctl get DNS $sb_dns_uuid options:ttl], [0], [dnl
> +"0"
> +])
> +
> +check ovn-nbctl --wait=sb set DNS $dns_uuid options:ttl=2147483647
> <(214)%20748-3647>
> +AT_CHECK([ovn-sbctl get DNS $sb_dns_uuid options:ttl], [0], [dnl
> +"2147483647 <(214)%20748-3647>"
> +])
> +
> +# Invalid values are rejected and the key is removed from SB.
> +check ovn-nbctl --wait=sb set DNS $dns_uuid options:ttl=garbage
> +AT_CHECK([test -z "$(ovn-sbctl --if-exists get DNS $sb_dns_uuid
> options:ttl)"])
> +
> +check ovn-nbctl --wait=sb set DNS $dns_uuid options:ttl=-5
> +AT_CHECK([test -z "$(ovn-sbctl --if-exists get DNS $sb_dns_uuid
> options:ttl)"])
> +
> +# A value above the 2^31-1 cap is out of range and rejected.
> +check ovn-nbctl --wait=sb set DNS $dns_uuid options:ttl=2147483648
> <(214)%20748-3648>
> +AT_CHECK([test -z "$(ovn-sbctl --if-exists get DNS $sb_dns_uuid
> options:ttl)"])
> +
> +# A value that overflows the 32-bit unsigned range is rejected as well.
> +check ovn-nbctl --wait=sb set DNS $dns_uuid options:ttl=99999999999
> +AT_CHECK([test -z "$(ovn-sbctl --if-exists get DNS $sb_dns_uuid
> options:ttl)"])
> +
> +# Removing the option clears any previously synced value.
> +check ovn-nbctl --wait=sb set DNS $dns_uuid options:ttl=30
> +AT_CHECK([ovn-sbctl get DNS $sb_dns_uuid options:ttl], [0], [dnl
> +"30"
> +])
> +check ovn-nbctl --wait=sb remove DNS $dns_uuid options ttl
> +AT_CHECK([test -z "$(ovn-sbctl --if-exists get DNS $sb_dns_uuid
> options:ttl)"])
> +
> +OVN_CLEANUP_NORTHD
> +AT_CLEANUP
> +])
> +
>  OVN_FOR_EACH_NORTHD_NO_HV([
>  AT_SETUP([ACL/Meter incremental processing - no northd recompute])
>  ovn_start
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 8acfecb7bc..7f823de1da 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -12677,6 +12677,144 @@ OVN_CLEANUP([hv1])
>  AT_CLEANUP
>  ])
>
> +OVN_FOR_EACH_NORTHD([
> +AT_SETUP([dns lookup : configurable TTL])
> +CHECK_SCAPY
> +ovn_start
> +
> +check ovn-nbctl ls-add ls \
> +    -- lsp-add ls lsp \
> +    -- lsp-set-addresses lsp "00:00:00:00:00:01 10.0.0.1"
> +
> +d=$(ovn-nbctl create DNS records={})
> +check ovn-nbctl set DNS $d records:foo.ovn.org="10.0.0.42 aef0::42"
> +check ovn-nbctl set DNS $d records:42.0.0.10.in-addr.arpa="foo.ovn.org"
> +check ovn-nbctl set Logical_switch ls dns_records="$d"
> +
> +net_add n1
> +sim_add hv1
> +
> +as hv1
> +ovs-vsctl add-br br-phys
> +ovn_attach n1 br-phys 192.168.0.1
> +check ovs-vsctl add-port br-int hv1-vif1 -- \
> +    set interface hv1-vif1 external-ids:iface-id=lsp \
> +    options:tx_pcap=hv1/vif1-tx.pcap \
> +    options:rxq_pcap=hv1/vif1-rx.pcap
> +
> +OVN_POPULATE_ARP
> +wait_for_ports_up
> +check ovn-nbctl --wait=hv sync
> +
> +dns_req_a=$(fmt_pkt "Ether(dst='00:00:00:00:00:02',
> src='00:00:00:00:00:01') / \
> +                    IP(dst='10.0.0.254', src='10.0.0.1') / \
> +                    UDP(sport=42424, dport=53) / \
> +                    DNS(rd=1, qd=DNSQR(qname='foo.ovn.org', qtype='A'))")
> +dns_req_aaaa=$(fmt_pkt "Ether(dst='00:00:00:00:00:02',
> src='00:00:00:00:00:01') / \
> +                       IP(dst='10.0.0.254', src='10.0.0.1') / \
> +                       UDP(sport=42424, dport=53) / \
> +                       DNS(rd=1, qd=DNSQR(qname='foo.ovn.org',
> qtype='AAAA'))")
> +dns_req_ptr=$(fmt_pkt "Ether(dst='00:00:00:00:00:02',
> src='00:00:00:00:00:01') / \
> +                      IP(dst='10.0.0.254', src='10.0.0.1') / \
> +                      UDP(sport=42424, dport=53) / \
> +                      DNS(rd=1, qd=DNSQR(qname='42.0.0.10.in-addr.arpa',
> qtype='PTR'))")
> +dns_req_any=$(fmt_pkt "Ether(dst='00:00:00:00:00:02',
> src='00:00:00:00:00:01') / \
> +                       IP(dst='10.0.0.254', src='10.0.0.1') / \
> +                       UDP(sport=42424, dport=53) / \
> +                       DNS(rd=1, qd=DNSQR(qname='foo.ovn.org',
> qtype='ALL'))")
> +
> +# Without "options:ttl", the reply uses the default TTL of 3600.
> +dns_reply=$(fmt_pkt "Ether(dst='00:00:00:00:00:01',
> src='00:00:00:00:00:02') / \
> +                     IP(dst='10.0.0.1', src='10.0.0.254') / \
> +                     UDP(sport=53, dport=42424, chksum=0) / \
> +                     DNS(qr=1, qd=DNSQR(qname='foo.ovn.org', qtype='A'),
> \
> +                         an=DNSRR(rrname='foo.ovn.org', type='A',
> ttl=3600, \
> +                                  rdata='10.0.0.42'))")
> +echo ${dns_reply} > expected
> +as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> +as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 ${dns_req_a}
> +OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv1/vif1-tx.pcap], [expected])
> +
> +# options:ttl=30 is applied to the A, AAAA and PTR replies alike.
> +check ovn-nbctl --wait=hv set DNS $d options:ttl=30
> +
> +dns_reply=$(fmt_pkt "Ether(dst='00:00:00:00:00:01',
> src='00:00:00:00:00:02') / \
> +                     IP(dst='10.0.0.1', src='10.0.0.254') / \
> +                     UDP(sport=53, dport=42424, chksum=0) / \
> +                     DNS(qr=1, qd=DNSQR(qname='foo.ovn.org', qtype='A'),
> \
> +                         an=DNSRR(rrname='foo.ovn.org', type='A',
> ttl=30, \
> +                                  rdata='10.0.0.42'))")
> +echo ${dns_reply} > expected
> +as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> +as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 ${dns_req_a}
> +OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv1/vif1-tx.pcap], [expected])
> +
> +dns_reply=$(fmt_pkt "Ether(dst='00:00:00:00:00:01',
> src='00:00:00:00:00:02') / \
> +                     IP(dst='10.0.0.1', src='10.0.0.254') / \
> +                     UDP(sport=53, dport=42424, chksum=0) / \
> +                     DNS(qr=1, qd=DNSQR(qname='foo.ovn.org',
> qtype='AAAA'), \
> +                         an=DNSRR(rrname='foo.ovn.org', type='AAAA',
> ttl=30, \
> +                                  rdata='aef0::42'))")
> +echo ${dns_reply} > expected
> +as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> +as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 ${dns_req_aaaa}
> +OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv1/vif1-tx.pcap], [expected])
> +
> +dns_reply=$(fmt_pkt "Ether(dst='00:00:00:00:00:01',
> src='00:00:00:00:00:02') / \
> +                     IP(dst='10.0.0.1', src='10.0.0.254') / \
> +                     UDP(sport=53, dport=42424, chksum=0) / \
> +                     DNS(qr=1, qd=DNSQR(qname='42.0.0.10.in-addr.arpa',
> qtype='PTR'), \
> +                         an=DNSRR(rrname='42.0.0.10.in-addr.arpa',
> type='PTR', \
> +                                  ttl=30, rdata='foo.ovn.org'))")
> +echo ${dns_reply} > expected
> +as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> +as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 ${dns_req_ptr}
> +OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv1/vif1-tx.pcap], [expected])
> +
> +# The ANY reply carries the A and AAAA RRs, each with the per-row TTL.
> +dns_reply=$(fmt_pkt "Ether(dst='00:00:00:00:00:01',
> src='00:00:00:00:00:02') / \
> +                      IP(dst='10.0.0.1', src='10.0.0.254') / \
> +                      UDP(sport=53, dport=42424, chksum=0) / \
> +                      DNS(qr=1, qd=DNSQR(qname='foo.ovn.org',
> qtype='ALL'), \
> +                          an=[[DNSRR(rrname='foo.ovn.org', type='A', \
> +                                    ttl=30, rdata='10.0.0.42'), \
> +                               DNSRR(rrname='foo.ovn.org', type='AAAA', \
> +                                    ttl=30, rdata='aef0::42')]])")
> +echo ${dns_reply} > expected
> +as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> +as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 ${dns_req_any}
> +OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv1/vif1-tx.pcap], [expected])
> +
> +# Removing the option restores the default TTL of 3600.
> +check ovn-nbctl --wait=hv remove DNS $d options ttl
> +dns_reply=$(fmt_pkt "Ether(dst='00:00:00:00:00:01',
> src='00:00:00:00:00:02') / \
> +                     IP(dst='10.0.0.1', src='10.0.0.254') / \
> +                     UDP(sport=53, dport=42424, chksum=0) / \
> +                     DNS(qr=1, qd=DNSQR(qname='foo.ovn.org', qtype='A'),
> \
> +                         an=DNSRR(rrname='foo.ovn.org', type='A',
> ttl=3600, \
> +                                  rdata='10.0.0.42'))")
> +echo ${dns_reply} > expected
> +as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> +as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 ${dns_req_a}
> +OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv1/vif1-tx.pcap], [expected])
> +
> +# options:ttl=0 is honored (a reply TTL of 0).
> +check ovn-nbctl --wait=hv set DNS $d options:ttl=0
> +dns_reply=$(fmt_pkt "Ether(dst='00:00:00:00:00:01',
> src='00:00:00:00:00:02') / \
> +                     IP(dst='10.0.0.1', src='10.0.0.254') / \
> +                     UDP(sport=53, dport=42424, chksum=0) / \
> +                     DNS(qr=1, qd=DNSQR(qname='foo.ovn.org', qtype='A'),
> \
> +                         an=DNSRR(rrname='foo.ovn.org', type='A', ttl=0,
> \
> +                                  rdata='10.0.0.42'))")
> +echo ${dns_reply} > expected
> +as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> +as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 ${dns_req_a}
> +OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv1/vif1-tx.pcap], [expected])
> +
> +OVN_CLEANUP([hv1])
> +AT_CLEANUP
> +])
> +
>  OVN_FOR_EACH_NORTHD([
>  AT_SETUP([4 HV, 1 LS, 1 LR, packet test with HA distributed router
> gateway port])
>  ovn_start
> --
> 2.55.0
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
>
Looks good to me, thanks.
Acked-by: Ales Musil <[email protected]>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to