On 6/2/23 09:45, Ales Musil wrote:
On Fri, Jun 2, 2023 at 12:43 PM Ales Musil <[email protected]> wrote:

Add support for FQDN option (39), if specified the server
can overwrite FQDN for the client. It behaves similarly
to DHCP hostname option (12).


Reported-at: https://bugzilla.redhat.com/2211890

I have created BZ for this it should be added on merge or I'll add it
if there is a need for v2.

Signed-off-by: Ales Musil <[email protected]>
---
  NEWS                 |   2 +
  controller/pinctrl.c |  27 +++++++-
  lib/actions.c        |  30 ++++++++-
  lib/ovn-l7.h         |  10 +++
  northd/ovn-northd.c  |   3 +-
  ovn-nb.xml           |   7 ++
  ovn-sb.ovsschema     |   6 +-
  tests/ovn.at         | 156 ++++++++++++++++++++++++-------------------
  tests/test-ovn.c     |   1 +
  9 files changed, 166 insertions(+), 76 deletions(-)

diff --git a/NEWS b/NEWS
index 1532f635a..b4dd0da05 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,7 @@
  Post v23.06.0
  -------------
+  - Add DHCPv6 "fqdn" (39) option, that works similarly to
+    DHCPv4 "hostname" (12) option.

  OVN v23.06.0 - xx xxx xxxx
  --------------------------
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index c396ad4c2..51dbadc99 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -2288,7 +2288,7 @@ exit:
  static bool
  compose_out_dhcpv6_opts(struct ofpbuf *userdata,
                          struct ofpbuf *out_dhcpv6_opts,
-                        ovs_be32 iaid, bool ipxe_req)
+                        ovs_be32 iaid, bool ipxe_req, uint8_t fqdn_flags)
  {
      while (userdata->size) {
          struct dhcpv6_opt_header *userdata_opt = ofpbuf_try_pull(
@@ -2412,6 +2412,24 @@ compose_out_dhcpv6_opts(struct ofpbuf *userdata,
              break;
          }

+        case DHCPV6_OPT_FQDN_CODE: {
+            if (fqdn_flags != DHCPV6_FQDN_FLAGS_UNDEFINED) {
+                struct dhcpv6_opt_header *header =
+                        ofpbuf_put_zeros(out_dhcpv6_opts, sizeof *header);
+                header->code = htons(DHCPV6_OPT_FQDN_CODE);
+                header->len = htons(size + 1);
+                uint8_t *flags = ofpbuf_put_zeros(out_dhcpv6_opts, 1);
+                /* If client requested N or S inform him that it
+                 * was overwritten by the server. */
+                if (fqdn_flags & DHCPV6_FQDN_FLAGS_N ||
+                    fqdn_flags & DHCPV6_FQDN_FLAGS_S) {
+                    *flags |= DHCPV6_FQDN_FLAGS_O;
+                }

I read through RFC 4704 section 4.1, and I think the flag-handling is slightly off here.

First, here's what is said about the "O" bit:

   The "O" bit indicates whether the server has overridden the client's
   preference for the "S" bit.  A client MUST set this bit to 0.  A
   server MUST set this bit to 1 if the "S" bit in its reply to the
   client does not match the "S" bit received from the client.

Based on my reading, we only need to set the O bit if the client set the S bit to 1. The client N bit should not factor into our setting of the O bit.

Then later, when discussing the "N" bit:

   ... A server sets the "N" bit to indicate whether the
   server SHALL (0) or SHALL NOT (1) perform DNS updates.  If the "N"
   bit is 1, the "S" bit MUST be 0.

I think our stance is that we are not performing DNS updates as the server, so we probably should be setting the N bit to 1 in all our replies.


+                ofpbuf_put(out_dhcpv6_opts, userdata_opt_data, size);
+            }
+            break;
+        }
+
          default:
              return false;
          }
@@ -2500,6 +2518,7 @@ pinctrl_handle_put_dhcpv6_opts(
      size_t l4_len = dp_packet_l4_size(pkt_in);
      uint8_t *end = (uint8_t *)in_udp + MIN(udp_len, l4_len);
      bool ipxe_req = false;
+    uint8_t fqdn_flags = DHCPV6_FQDN_FLAGS_UNDEFINED;
      while (in_dhcpv6_data < end) {
          struct dhcpv6_opt_header const *in_opt =
               (struct dhcpv6_opt_header *)in_dhcpv6_data;
@@ -2524,6 +2543,10 @@ pinctrl_handle_put_dhcpv6_opts(
              break;
          }

+        case DHCPV6_OPT_FQDN_CODE:
+            fqdn_flags = *(in_dhcpv6_data + sizeof *in_opt);
+            break;
+
          default:
              break;
          }
@@ -2547,7 +2570,7 @@ pinctrl_handle_put_dhcpv6_opts(
          OFPBUF_STUB_INITIALIZER(out_ofpacts_dhcpv6_opts_stub);

      if (!compose_out_dhcpv6_opts(userdata, &out_dhcpv6_opts,
-                                 iaid, ipxe_req)) {
+                                 iaid, ipxe_req, fqdn_flags)) {
          VLOG_WARN_RL(&rl, "Invalid userdata");
          goto exit;
      }
diff --git a/lib/actions.c b/lib/actions.c
index ec27223f9..0ec69bec9 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -2470,7 +2470,8 @@ parse_gen_opt(struct action_context *ctx, struct
ovnact_gen_option *o,
      }

      if (!strcmp(o->option->type, "str") ||
-        !strcmp(o->option->type, "domains")) {
+        !strcmp(o->option->type, "domains") ||
+        !strcmp(o->option->type, "domain")) {
          if (o->value.type != EXPR_C_STRING) {
              lexer_error(ctx->lexer, "%s option %s requires string value.",
                          opts_type, o->option->name);
@@ -2903,6 +2904,33 @@ encode_put_dhcpv6_option(const struct
ovnact_gen_option *o,
          size = strlen(c->string);
          opt->len = htons(size);
          ofpbuf_put(ofpacts, c->string, size);
+    } else if (!strcmp(o->option->type, "domain")) {
+        /* The DNS format is 2 bytes longer than the "domain".
+         * It replaces every '.' with len of the next name. */
+        size_t domain_len = strlen(c->string);
+        size = domain_len + 2;
+        char *encoded = xzalloc(size);
+
+        int8_t label_len = 0;
+        for (size_t i = 0; i < domain_len; i++) {
+            if (c->string[i] == '.') {
+                encoded[i - label_len] = label_len;
+                label_len = 0;
+            } else {
+                encoded[i + 1] = c->string[i];
+                label_len++;
+            }
+        }
+
+        /* This is required for the last label if it doesn't end with '.'
*/
+        if (label_len) {
+            encoded[domain_len - label_len] = label_len;
+        }

This section where you encode the domain name is nearly identical to existing code in dns_build_ptr_answer() in controller/pinctrl.c

I suggest extracting the common code into a function and calling that function here and in dns_build_ptr_answer().

+
+        opt->len = htons(size);
+        ofpbuf_put(ofpacts, encoded, size);
+
+        free(encoded);
      }
  }

diff --git a/lib/ovn-l7.h b/lib/ovn-l7.h
index d9b103119..9dc331421 100644
--- a/lib/ovn-l7.h
+++ b/lib/ovn-l7.h
@@ -270,6 +270,7 @@ BUILD_ASSERT_DECL(DHCP_OPT_HEADER_LEN == sizeof(struct
dhcp_opt_header));
  #define DHCPV6_OPT_DOMAIN_SEARCH_CODE    24
  #define DHCPV6_OPT_IA_PD                 25
  #define DHCPV6_OPT_IA_PREFIX             26
+#define DHCPV6_OPT_FQDN_CODE             39
  #define DHCPV6_OPT_BOOT_FILE_URL         59
  #define DHCPV6_OPT_BOOT_FILE_URL_ALT    254

@@ -291,6 +292,15 @@ BUILD_ASSERT_DECL(DHCP_OPT_HEADER_LEN ==
sizeof(struct dhcp_opt_header));
  #define DHCPV6_OPT_BOOTFILE_NAME_ALT \
      DHCP_OPTION("bootfile_name_alt", DHCPV6_OPT_BOOT_FILE_URL_ALT, "str")

+#define DHCPV6_OPT_FQDN \
+    DHCP_OPTION("fqdn", DHCPV6_OPT_FQDN_CODE, "domain")
+
+/* DHCPv6 FQDN flags. RFC 4704 */
+#define DHCPV6_FQDN_FLAGS_UNDEFINED 0xff
+#define DHCPV6_FQDN_FLAGS_S 1 << 0
+#define DHCPV6_FQDN_FLAGS_O 1 << 1
+#define DHCPV6_FQDN_FLAGS_N 1 << 2
+
  OVS_PACKED(
  struct dhcpv6_opt_header {
      ovs_be16 code;
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index 3515b68a2..2bafbd4af 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -273,7 +273,8 @@ static struct gen_opts_map supported_dhcpv6_opts[] = {
      DHCPV6_OPT_DOMAIN_SEARCH,
      DHCPV6_OPT_DNS_SERVER,
      DHCPV6_OPT_BOOTFILE_NAME,
-    DHCPV6_OPT_BOOTFILE_NAME_ALT
+    DHCPV6_OPT_BOOTFILE_NAME_ALT,
+    DHCPV6_OPT_FQDN,
  };

  static bool
diff --git a/ovn-nb.xml b/ovn-nb.xml
index 9afe3b584..05e155b89 100644
--- a/ovn-nb.xml
+++ b/ovn-nb.xml
@@ -4191,6 +4191,13 @@ or
              way. Default value for this option is false.
            </p>
          </column>
+
+        <column name="options" key="fqdn">
+          <p>
+            The DHCPv6 option code for this option is 39.
+            If set, indicates the DHCPv6 option "FQDN".
+          </p>
+        </column>
        </group>
      </group>

diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema
index f59af8cc5..06e16b403 100644
--- a/ovn-sb.ovsschema
+++ b/ovn-sb.ovsschema
@@ -1,7 +1,7 @@
  {
      "name": "OVN_Southbound",
-    "version": "20.27.2",
-    "cksum": "1291808617 30462",
+    "version": "20.27.3",
+    "cksum": "3876528905 30472",
      "tables": {
          "SB_Global": {
              "columns": {
@@ -311,7 +311,7 @@
                  "type": {
                      "type": {"key": {
                          "type": "string",
-                        "enum": ["set", ["ipv6", "str", "mac"]]}}}},
+                        "enum": ["set", ["ipv6", "str", "mac",
"domain"]]}}}},
              "isRoot": true},
          "Connection": {
              "columns": {
diff --git a/tests/ovn.at b/tests/ovn.at
index d8c694002..ab6052299 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -1697,6 +1697,9 @@ reg1[0] = put_dhcpv6_opts(bootfile_name="
https://127.0.0.1/boot.ipxe";);
  reg1[0] = put_dhcpv6_opts(bootfile_name_alt="https://127.0.0.1/boot.ipxe
");
      formats as reg1[0] = put_dhcpv6_opts(bootfile_name_alt = "
https://127.0.0.1/boot.ipxe";);
      encodes as
controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.fe.00.1b.68.74.74.70.73.3a.2f.2f.31.32.37.2e.30.2e.30.2e.31.2f.62.6f.6f.74.2e.69.70.78.65,pause)
+reg1[0] = put_dhcpv6_opts(fqdn="ovn.org");
+    formats as reg1[0] = put_dhcpv6_opts(fqdn = "ovn.org");
+    encodes as
controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.27.00.09.03.6f.76.6e.03.6f.72.67.00,pause)

  # lookup_nd
  reg2[0] = lookup_nd(inport, ip6.dst, eth.src);
@@ -7083,6 +7086,7 @@ AT_CLEANUP

  OVN_FOR_EACH_NORTHD([
  AT_SETUP([dhcpv6 : 1 HV, 2 LS, 5 LSPs])
+AT_SKIP_IF([test $HAVE_SCAPY = no])
  ovn_start

  ovn-nbctl ls-add ls1
@@ -7171,61 +7175,56 @@ trim_zeros() {
  # packet should be received twice (one from ovn-controller and the other
  # from the "ovs-ofctl monitor br-int resume"
  test_dhcpv6() {
-    local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5 ipxe=$6
-    if test $ipxe -eq 2; then
-        req_len=34
-    elif test $msg_code != 0b; then
-        req_len=2a
-    else
-        req_len=1a
-    fi
-    local
request=ffffffffffff${src_mac}86dd6000000000${req_len}1101${src_lla}
-    # dst ip ff02::1:2
-    request=${request}ff020000000000000000000000010002
-    # udp header and dhcpv6 header
-    request=${request}0222022300${req_len}ffff${msg_code}010203
-    # Client identifier
-    request=${request}0001000a00030001${src_mac}
+    local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
boot_file=$6
+    local fqdn=$7
+
+    local req_scapy="Ether(dst='ff:ff:ff:ff:ff:ff', src='${src_mac}')/ \
+                     IPv6(dst='ff02::1:2', src='${src_lla}')/ \
+                     UDP(sport=546, dport=547)/ \
+                     DHCP6(msgtype=${msg_code}, trid=0x010203)/ \
+                     DHCP6OptClientId(duid=DUID_LL(lladdr='${src_mac}'))"
+

Yay for switching to a more readable method of generating packets!

      # Add IA-NA (Identity Association for Non Temporary Address) if
msg_code
      # is not 11 (information request packet)
-    if test $msg_code != 0b; then
-        request=${request}0003000c0102030400000e1000001518
+    if test $msg_code != 11; then
+        req_scapy="${req_scapy}/DHCP6OptIA_NA(iaid=0x01020304, T1=3600,
T2=5400)"
      fi
-    if test $ipxe -eq 2; then
-        request=${request}000f0006000669505845
+    if test "$boot_file" = "bootfile_name"; then
+        local uc_data="USER_CLASS_DATA(data=b'iPXE')"
+
req_scapy="${req_scapy}/DHCP6OptUserClass(userclassdata=[[${uc_data}]])"
      fi
-    shift; shift; shift; shift; shift; shift;
+    if test -n "$fqdn"; then
+        req_scapy="${req_scapy}/DHCP6OptClientFQDN(flags=0x01,
fqdn=b'test')"
+    fi
+    request=$(fmt_pkt "${req_scapy}")
+    shift; shift; shift; shift; shift; shift; shift;
      if test $offer_ip != 0; then
-        local server_mac=000000100001
-        local server_lla=fe80000000000000020000fffe100001
-        local reply_code=07
-        if test $msg_code = 01; then
-            reply_code=02
-        fi
-        local msg_len=54
-        if test $ipxe -eq 1; then
-            msg_len=69
-        elif test $ipxe -eq 2; then
-            msg_len=65
-        elif test $offer_ip = 1; then
-            msg_len=28
+        local reply_code=7
+        if test $msg_code = 1; then
+            reply_code=2
          fi
-        local
reply=${src_mac}${server_mac}86dd6000000000${msg_len}1101${server_lla}${src_lla}
-        # udp header and dhcpv6 header
-        reply=${reply}0223022200${msg_len}ffff${reply_code}010203
-        # Client identifier
-        reply=${reply}0001000a00030001${src_mac}
-        # IA-NA
+
+        local rep_scapy="Ether(dst='${src_mac}',
src='00:00:00:10:00:01')/ \
+                         IPv6(dst='${src_lla}',
src='fe80::0200:00ff:fe10:0001')/ \
+                         UDP(sport=547, dport=546)/ \
+                         DHCP6(msgtype=${reply_code}, trid=0x010203)/ \
+
  DHCP6OptClientId(duid=DUID_LL(lladdr='${src_mac}'))"
+
          if test $offer_ip != 1; then
-
reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
+            local ip_scapy="DHCP6OptIAAddress(addr='${offer_ip}', \
+                            preflft=0xffffffff, validlft=0xffffffff)"
+            rep_scapy="${rep_scapy}/ \
+                       DHCP6OptIA_NA(iaid=0x01020304, T1=0xffffffff, \
+                       T2=0xffffffff, ianaopts=[[${ip_scapy}]])"
          fi
-        if test $ipxe -eq 1; then
-            reply=${reply}003b0011626f6f7466696c655f6e616d655f616c74
-        elif test $ipxe -eq 2; then
-            reply=${reply}003b000d626f6f7466696c655f6e616d65
+        if test -n "$boot_file"; then
+
rep_scapy="${rep_scapy}/DHCP6OptBootFileUrl(optdata=b'${boot_file}')"
          fi
-        # Server identifier
-        reply=${reply}0002000a00030001${server_mac}
+        if test -n "$fqdn"; then
+            rep_scapy="${rep_scapy}/DHCP6OptClientFQDN(flags=0x02,
fqdn=b'${fqdn}')"
+        fi
+
rep_scapy="${rep_scapy}/DHCP6OptServerId(duid=DUID_LL(lladdr='00:00:00:10:00:01'))"
+        reply=$(fmt_pkt "${rep_scapy}")
          echo $reply | trim_zeros >> $inport.expected
      else
          for outport; do
@@ -7249,16 +7248,16 @@ echo "---------------------"
  ovn-sbctl list logical_flow
  echo "---------------------"

-ovn-sbctl dump-flows > sbflows
+#ovn-sbctl dump-flows > sbflows
  AT_CAPTURE_FILE([sbflows])

  echo "------ hv1 dump ----------"
  as hv1 ovs-ofctl dump-flows br-int

-src_mac=f00000000001
-src_lla=fe80000000000000f20000fffe000001
-offer_ip=ae700000000000000000000000000004
-test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip 0
+src_mac="f0:00:00:00:00:01"
+src_lla="fe80::f200:00ff:fe00:0001"
+offer_ip="ae70::4"
+test_dhcpv6 1 $src_mac $src_lla 1 $offer_ip "" ""

  # NXT_RESUMEs should be 1.
  OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
@@ -7281,12 +7280,12 @@ rm  1.expected
  reset_pcap_file hv1-vif1 hv1/vif1
  reset_pcap_file hv1-vif2 hv1/vif2

-src_mac=f00000000002
-src_lla=fe80000000000000f20000fffe000002
-offer_ip=ae700000000000000000000000000005
+src_mac="f0:00:00:00:00:02"
+src_lla="fe80::f200:00ff:fe00:0002"
+offer_ip="ae70::5"
  # Set invalid msg_type

-test_dhcpv6 2 $src_mac $src_lla 10 0 0 1 1
+test_dhcpv6 2 $src_mac $src_lla 16 0 "" "" 1 1

  # NXT_RESUMEs should be 2.
  OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
@@ -7305,9 +7304,9 @@ AT_CHECK([cat 1.packets], [0], [expout])
  # There should be no DHCPv6 reply from ovn-controller and the request
packet
  # should be received by ls2-lp2.

-src_mac=f00000000003
-src_lla=fe80000000000000f20000fffe000003
-test_dhcpv6 3 $src_mac $src_lla 01 0 0 4
+src_mac="f0:00:00:00:00:03"
+src_lla="fe80::f200:00ff:fe00:0003"
+test_dhcpv6 3 $src_mac $src_lla 1 0 "" "" 4

  # NXT_RESUMEs should be 2 only.
  OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
@@ -7323,10 +7322,10 @@ AT_CHECK([cat 4.packets], [0], [expout])

  # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode
for this port.
  # The DHCPv6 reply shouldn't contain offer_ip.
-src_mac=f00000000022
-src_lla=fe80000000000000f20000fffe000022
+src_mac="f0:00:00:00:00:22"
+src_lla="fe80::f200:00ff:fe00:0022"
  reset_pcap_file hv1-vif5 hv1/vif5
-test_dhcpv6 5 $src_mac $src_lla 01 1 0 5
+test_dhcpv6 5 $src_mac $src_lla 1 1 "" "" 5

  # NXT_RESUMEs should be 3.
  OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
@@ -7338,11 +7337,11 @@ AT_CHECK([cat 5.packets | cut -c 1-120,125- ],
[0], [expout])

  # Send DHCPv6 information request (code 11) on ls1-lp3. The DHCPv6 reply
  # shouldn't contain offer_ip
-src_mac=f00000000022
-src_lla=fe80000000000000f20000fffe000022
+src_mac="f0:00:00:00:00:22"
+src_lla="fe80::f200:00ff:fe00:0022"
  reset_pcap_file hv1-vif5 hv1/vif5
  rm -f 5.expected
-test_dhcpv6 5 $src_mac $src_lla 0b 1 0 5
+test_dhcpv6 5 $src_mac $src_lla 11 1 "" "" 5

  # NXT_RESUMEs should be 4.
  OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
@@ -7363,11 +7362,11 @@ ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}

  reset_pcap_file hv1-vif2 hv1/vif2

-src_mac=f00000000002
-src_lla=fe80000000000000f20000fffe000002
-offer_ip=ae700000000000000000000000000005
+src_mac="f0:00:00:00:00:02"
+src_lla="fe80::f200:00ff:fe00:0002"
+offer_ip="ae70::5"

-test_dhcpv6 2 $src_mac $src_lla 01 $offer_ip 1
+test_dhcpv6 2 $src_mac $src_lla 1 $offer_ip "bootfile_name_alt" ""
  # NXT_RESUMEs should be 5.
  OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])

@@ -7381,7 +7380,7 @@ AT_CHECK([cat 2.packets | cut -c 1-120,125- ], [0],
[expout])
  reset_pcap_file hv1-vif2 hv1/vif2
  rm 2.packets 2.expected

-test_dhcpv6 2 $src_mac $src_lla 01 $offer_ip 2
+test_dhcpv6 2 $src_mac $src_lla 1 $offer_ip "bootfile_name" ""
  # NXT_RESUMEs should be 6.
  OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])

@@ -7389,6 +7388,25 @@ $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in"
hv1/vif2-tx.pcap | trim_zeros > 2.pa
  cat 2.expected | cut -c 1-120,125- > expout
  AT_CHECK([cat 2.packets | cut -c 1-120,125- ], [0], [expout])

+ovn-nbctl --all destroy dhcp-option
+d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64")"
+ovn-nbctl dhcp-options-set-options $d1 \
+    server_id=00:00:00:10:00:01 \
+    fqdn=\"ovn.org\"
+ovn-nbctl --wait=hv lsp-set-dhcpv6-options ls1-lp2 ${d1}
+
+reset_pcap_file hv1-vif2 hv1/vif2
+rm 2.packets 2.expected
+
+test_dhcpv6 2 $src_mac $src_lla 1 $offer_ip "" "ovn.org"
+# NXT_RESUMEs should be 7.
+OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
+
+$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap |
trim_zeros > 2.packets
+cat 2.expected | cut -c 1-120,125- > expout
+cat 2.packets
+AT_CHECK([cat 2.packets | cut -c 1-120,125- ], [0], [expout])
+
  OVN_CLEANUP([hv1])

  AT_CLEANUP
diff --git a/tests/test-ovn.c b/tests/test-ovn.c
index ce9213c1d..6c7754eac 100644
--- a/tests/test-ovn.c
+++ b/tests/test-ovn.c
@@ -207,6 +207,7 @@ create_gen_opts(struct hmap *dhcp_opts, struct hmap
*dhcpv6_opts,
      dhcp_opt_add(dhcpv6_opts, "domain_search",  24, "str");
      dhcp_opt_add(dhcpv6_opts, "bootfile_name", 59, "str");
      dhcp_opt_add(dhcpv6_opts, "bootfile_name_alt", 254, "str");
+    dhcp_opt_add(dhcpv6_opts, "fqdn", 39, "domain");

      /* IPv6 ND RA options. */
      hmap_init(nd_ra_opts);
--
2.40.1




_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to