On Fri, Oct 23, 2020 at 4:04 PM Lorenzo Bianconi
<lorenzo.bianc...@redhat.com> wrote:
>
> Add iPXE support to OVN introducing "bootfile_name_alt" dhcp option.
> "bootfile_name_alt" dhcp userdata is encoded as option 254 since
> it is not currently used.
> When both "bootfile_name" and "bootfile_name_alt" are provided
> by the CMS, "bootfile_name" will be used for option 67 if the
> dhcp request contains etherboot option (175), otherwise
> "bootfile_name_alt" will be used.
> "bootfile_name" and "bootfile_name_alt" are placed just after offer_ip
> in userdata buffer.
>
> Tested-by: Lucas Alvares Gomes Martins <lmart...@redhat.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianc...@redhat.com>

Thanks Lorenzo.

I did the below changes and applied to master.

**********

diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index 6f5499f0b..f15afc54f 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -2024,16 +2024,16 @@ pinctrl_handle_put_dhcp_opts(
      */
     struct dhcp_opt_header *in_dhcp_opt =
         (struct dhcp_opt_header *)reply_dhcp_opts_ptr->data;
-    if (in_dhcp_opt->code == 67) { /* DHCP_OPT_BOOTFILENAME */
+    if (in_dhcp_opt->code == DHCP_OPT_BOOTFILE_CODE) {
         unsigned char *ptr = (unsigned char *)in_dhcp_opt;
         int len = sizeof *in_dhcp_opt + in_dhcp_opt->len;
         struct dhcp_opt_header *next_dhcp_opt =
             (struct dhcp_opt_header *)(ptr + len);

-        if (next_dhcp_opt->code == 254) { /* DHCP_OPT_BOOTFILE_ALT */
+        if (next_dhcp_opt->code == DHCP_OPT_BOOTFILE_ALT_CODE) {
             if (!ipxe_req) {
                 ofpbuf_pull(reply_dhcp_opts_ptr, len);
-                next_dhcp_opt->code = 67;
+                next_dhcp_opt->code = DHCP_OPT_BOOTFILE_CODE;
             } else {
                 char *buf = xmalloc(len);

@@ -2044,8 +2044,8 @@ pinctrl_handle_put_dhcp_opts(
                 free(buf);
             }
         }
-    } else if (in_dhcp_opt->code == 254) { /* DHCP_OPT_BOOTFILE_ALT */
-        in_dhcp_opt->code = 67;
+    } else if (in_dhcp_opt->code == DHCP_OPT_BOOTFILE_ALT_CODE) {
+        in_dhcp_opt->code = DHCP_OPT_BOOTFILE_CODE;
     }

     uint16_t new_l4_size = UDP_HEADER_LEN + DHCP_HEADER_LEN + 16;
diff --git a/lib/actions.c b/lib/actions.c
index b0d03bc96..23e54ef2a 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -2542,9 +2542,9 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo,
     ovs_be32 offerip = offerip_opt->value.values[0].value.ipv4;
     ofpbuf_put(ofpacts, &offerip, sizeof offerip);

-    /* Encode and bootfile_name opt (67) */
-    const struct ovnact_gen_option *boot_opt = find_opt(
-            pdo->options, pdo->n_options, 67);
+    /* Encode bootfile_name opt (67) */
+    const struct ovnact_gen_option *boot_opt =
+        find_opt(pdo->options, pdo->n_options, DHCP_OPT_BOOTFILE_CODE);
     if (boot_opt) {
         uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2);
         const union expr_constant *c = boot_opt->value.values;
@@ -2553,8 +2553,8 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo,
         ofpbuf_put(ofpacts, c->string, opt_header[1]);
     }
     /* Encode bootfile_name_alt opt (254) */
-    const struct ovnact_gen_option *boot_alt_opt = find_opt(
-            pdo->options, pdo->n_options, 254);
+    const struct ovnact_gen_option *boot_alt_opt =
+        find_opt(pdo->options, pdo->n_options, DHCP_OPT_BOOTFILE_ALT_CODE);
     if (boot_alt_opt) {
         uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2);
         const union expr_constant *c = boot_alt_opt->value.values;
@@ -2565,7 +2565,7 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo,

     for (const struct ovnact_gen_option *o = pdo->options;
          o < &pdo->options[pdo->n_options]; o++) {
-        if (o != offerip_opt && o != boot_alt_opt && o != boot_opt) {
+        if (o != offerip_opt && o != boot_opt && o != boot_alt_opt) {
             encode_put_dhcpv4_option(o, ofpacts);
         }
     }
diff --git a/lib/ovn-l7.h b/lib/ovn-l7.h
index fb0088582..c3e8fd660 100644
--- a/lib/ovn-l7.h
+++ b/lib/ovn-l7.h
@@ -93,10 +93,14 @@ struct gen_opts_map {
 #define DHCP_OPT_DOMAIN_SEARCH_LIST \
     DHCP_OPTION("domain_search_list", 119, "domains")

-/* let's use unused 254 option for iPXE bootfile_name_alt
- * userdata dhcp option
+#define DHCP_OPT_BOOTFILE_CODE 67
+
+/* Use unused 254 option for iPXE bootfile_name_alt userdata DHCP option.
+ * This option code is replaced by 67 when sending the DHCP reply.
  */
-#define DHCP_OPT_BOOTFILE_ALT DHCP_OPTION("bootfile_name_alt", 254, "str")
+#define DHCP_OPT_BOOTFILE_ALT_CODE 254
+#define DHCP_OPT_BOOTFILE_ALT DHCP_OPTION("bootfile_name_alt", \
+                                          DHCP_OPT_BOOTFILE_ALT_CODE, "str")

 #define DHCP_OPT_ETHERBOOT     175


*********

> ---
> Changes since v2:
> - encode "bootfile_name" and "bootfile_name_alt" are placed just after
>   offer_ip in userdata buffer in order to avoid loops in
>   pinctrl_handle_put_dhcp_opts()
> Changes since v1:
> - encode bootfile_name_alt option as 254 in order to not increase userdata
>   buffer size
> ---
>  controller/pinctrl.c |  30 ++++++++++++
>  lib/actions.c        |  33 ++++++++++---
>  lib/ovn-l7.h         |   7 +++
>  northd/ovn-northd.c  |   1 +
>  ovn-nb.xml           |  10 ++++
>  tests/ovn.at         | 110 ++++++++++++++++++++++++++++++-------------
>  tests/test-ovn.c     |   1 +
>  7 files changed, 154 insertions(+), 38 deletions(-)
>
> diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> index d85ba504d..6f5499f0b 100644
> --- a/controller/pinctrl.c
> +++ b/controller/pinctrl.c
> @@ -1868,6 +1868,7 @@ pinctrl_handle_put_dhcp_opts(
>      }
>      in_dhcp_ptr += sizeof magic_cookie;
>
> +    bool ipxe_req = false;
>      const uint8_t *in_dhcp_msg_type = NULL;
>      ovs_be32 request_ip = in_dhcp_data->ciaddr;
>      while (in_dhcp_ptr < end) {
> @@ -1900,6 +1901,9 @@ pinctrl_handle_put_dhcp_opts(
>                  request_ip = 
> get_unaligned_be32(DHCP_OPT_PAYLOAD(in_dhcp_opt));
>              }
>              break;
> +        case DHCP_OPT_ETHERBOOT:
> +            ipxe_req = true;
> +            break;
>          default:
>              break;
>          }
> @@ -2018,6 +2022,32 @@ pinctrl_handle_put_dhcp_opts(
>       *| 4 Bytes padding | 1 Byte (option end 0xFF ) | 4 Bytes padding|
>       * --------------------------------------------------------------
>       */
> +    struct dhcp_opt_header *in_dhcp_opt =
> +        (struct dhcp_opt_header *)reply_dhcp_opts_ptr->data;
> +    if (in_dhcp_opt->code == 67) { /* DHCP_OPT_BOOTFILENAME */
> +        unsigned char *ptr = (unsigned char *)in_dhcp_opt;
> +        int len = sizeof *in_dhcp_opt + in_dhcp_opt->len;
> +        struct dhcp_opt_header *next_dhcp_opt =
> +            (struct dhcp_opt_header *)(ptr + len);
> +
> +        if (next_dhcp_opt->code == 254) { /* DHCP_OPT_BOOTFILE_ALT */
> +            if (!ipxe_req) {
> +                ofpbuf_pull(reply_dhcp_opts_ptr, len);
> +                next_dhcp_opt->code = 67;
> +            } else {
> +                char *buf = xmalloc(len);
> +
> +                memcpy(buf, in_dhcp_opt, len);
> +                ofpbuf_pull(reply_dhcp_opts_ptr,
> +                            sizeof *in_dhcp_opt + next_dhcp_opt->len);
> +                memcpy(reply_dhcp_opts_ptr->data, buf, len);
> +                free(buf);
> +            }
> +        }
> +    } else if (in_dhcp_opt->code == 254) { /* DHCP_OPT_BOOTFILE_ALT */
> +        in_dhcp_opt->code = 67;
> +    }
> +
>      uint16_t new_l4_size = UDP_HEADER_LEN + DHCP_HEADER_LEN + 16;
>      if (msg_type != DHCP_MSG_NAK) {
>          new_l4_size += reply_dhcp_opts_ptr->size;
> diff --git a/lib/actions.c b/lib/actions.c
> index 1e1bdeff2..b0d03bc96 100644
> --- a/lib/actions.c
> +++ b/lib/actions.c
> @@ -2086,10 +2086,10 @@ parse_gen_opt(struct action_context *ctx, struct 
> ovnact_gen_option *o,
>  }
>
>  static const struct ovnact_gen_option *
> -find_offerip(const struct ovnact_gen_option *options, size_t n)
> +find_opt(const struct ovnact_gen_option *options, size_t n, size_t code)
>  {
>      for (const struct ovnact_gen_option *o = options; o < &options[n]; o++) {
> -        if (o->option->code == 0) {
> +        if (o->option->code == code) {
>              return o;
>          }
>      }
> @@ -2288,7 +2288,7 @@ parse_put_dhcp_opts(struct action_context *ctx,
>      parse_put_opts(ctx, dst, po, dhcp_opts, opts_type);
>
>      if (!ctx->lexer->error && po->ovnact.type == OVNACT_PUT_DHCPV4_OPTS
> -        && !find_offerip(po->options, po->n_options)) {
> +        && !find_opt(po->options, po->n_options, 0)) {
>          lexer_error(ctx->lexer,
>                      "put_dhcp_opts requires offerip to be specified.");
>          return;
> @@ -2537,14 +2537,35 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts 
> *pdo,
>      /* Encode the offerip option first, because it's a special case and needs
>       * to be first in the actual DHCP response, and then encode the rest
>       * (skipping offerip the second time around). */
> -    const struct ovnact_gen_option *offerip_opt = find_offerip(
> -        pdo->options, pdo->n_options);
> +    const struct ovnact_gen_option *offerip_opt = find_opt(
> +        pdo->options, pdo->n_options, 0);
>      ovs_be32 offerip = offerip_opt->value.values[0].value.ipv4;
>      ofpbuf_put(ofpacts, &offerip, sizeof offerip);
>
> +    /* Encode and bootfile_name opt (67) */
> +    const struct ovnact_gen_option *boot_opt = find_opt(
> +            pdo->options, pdo->n_options, 67);
> +    if (boot_opt) {
> +        uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2);
> +        const union expr_constant *c = boot_opt->value.values;
> +        opt_header[0] = boot_opt->option->code;
> +        opt_header[1] = strlen(c->string);
> +        ofpbuf_put(ofpacts, c->string, opt_header[1]);
> +    }
> +    /* Encode bootfile_name_alt opt (254) */
> +    const struct ovnact_gen_option *boot_alt_opt = find_opt(
> +            pdo->options, pdo->n_options, 254);
> +    if (boot_alt_opt) {
> +        uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2);
> +        const union expr_constant *c = boot_alt_opt->value.values;
> +        opt_header[0] = boot_alt_opt->option->code;
> +        opt_header[1] = strlen(c->string);
> +        ofpbuf_put(ofpacts, c->string, opt_header[1]);
> +    }
> +
>      for (const struct ovnact_gen_option *o = pdo->options;
>           o < &pdo->options[pdo->n_options]; o++) {
> -        if (o != offerip_opt) {
> +        if (o != offerip_opt && o != boot_alt_opt && o != boot_opt) {
>              encode_put_dhcpv4_option(o, ofpacts);
>          }
>      }
> diff --git a/lib/ovn-l7.h b/lib/ovn-l7.h
> index 30a795531..a2671ddd2 100644
> --- a/lib/ovn-l7.h
> +++ b/lib/ovn-l7.h
> @@ -93,6 +93,13 @@ struct gen_opts_map {
>  #define DHCP_OPT_DOMAIN_SEARCH_LIST \
>      DHCP_OPTION("domain_search_list", 119, "domains")
>
> +/* let's use unused 254 option for iPXE bootfile_name_alt
> + * userdata dhcp option
> + */
> +#define DHCP_OPT_BOOTFILE_ALT DHCP_OPTION("bootfile_name_alt", 254, "str")
> +
> +#define DHCP_OPT_ETHERBOOT     175
> +
>  #define DHCP_OPT_ARP_CACHE_TIMEOUT \
>      DHCP_OPTION("arp_cache_timeout", 35, "uint32")
>  #define DHCP_OPT_TCP_KEEPALIVE_INTERVAL \
> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
> index 5b76868df..a3cdf8afc 100644
> --- a/northd/ovn-northd.c
> +++ b/northd/ovn-northd.c
> @@ -12472,6 +12472,7 @@ static struct gen_opts_map supported_dhcp_opts[] = {
>      DHCP_OPT_ARP_CACHE_TIMEOUT,
>      DHCP_OPT_TCP_KEEPALIVE_INTERVAL,
>      DHCP_OPT_DOMAIN_SEARCH_LIST,
> +    DHCP_OPT_BOOTFILE_ALT,
>  };
>
>  static struct gen_opts_map supported_dhcpv6_opts[] = {
> diff --git a/ovn-nb.xml b/ovn-nb.xml
> index 86195af34..43694535e 100644
> --- a/ovn-nb.xml
> +++ b/ovn-nb.xml
> @@ -3096,6 +3096,16 @@
>              resolving hostnames via the Domain Name System.
>            </p>
>          </column>
> +
> +        <column name="options" key="bootfile_name_alt">
> +          <p>
> +          </p>
> +            "bootfile_name_alt" option is used to support iPXE.
> +            When both "bootfile_name" and "bootfile_name_alt" are provided
> +            by the CMS, "bootfile_name" will be used for option 67 if the
> +            dhcp request contains etherboot option (175), otherwise
> +            "bootfile_name_alt" will be used.
> +        </column>
>        </group>
>
>        <group title="DHCP Options of type host_id">
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 27a94e64f..60066ebe2 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -1280,7 +1280,7 @@ reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 
> 10.0.0.1);
>      encodes as 
> controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.40.01.02.03.04.03.04.0a.00.00.01,pause)
>  reg2[5] = 
> put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain_name="ovn.org",wpad="https://example.org",bootfile_name="https://127.0.0.1/boot.ipxe",path_prefix="/tftpboot";);
>      formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 
> 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain_name = "ovn.org", wpad 
> = "https://example.org";, bootfile_name = "https://127.0.0.1/boot.ipxe";, 
> path_prefix = "/tftpboot");
> -    encodes as 
> controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67.43.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.d2.09.2f.74.66.74.70.62.6f.6f.74,pause)
> +    encodes as 
> controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.43.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.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67.d2.09.2f.74.66.74.70.62.6f.6f.74,pause)
>  reg0[15] = 
> put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.255.0,mtu=1400,ip_forward_enable=1,default_ttl=121,dns_server={8.8.8.8,7.7.7.7},classless_static_route={30.0.0.0/24,10.0.0.4,40.0.0.0/16,10.0.0.6,0.0.0.0/0,10.0.0.1},ethernet_encap=1,router_discovery=0,tftp_server_address={10.0.0.4,10.0.0.5},arp_cache_timeout=10,tcp_keepalive_interval=10);
>      formats as reg0[15] = put_dhcp_opts(offerip = 10.0.0.4, router = 
> 10.0.0.1, netmask = 255.255.255.0, mtu = 1400, ip_forward_enable = 1, 
> default_ttl = 121, dns_server = {8.8.8.8, 7.7.7.7}, classless_static_route = 
> {30.0.0.0/24, 10.0.0.4, 40.0.0.0/16, 10.0.0.6, 0.0.0.0/0, 10.0.0.1}, 
> ethernet_encap = 1, router_discovery = 0, tftp_server_address = {10.0.0.4, 
> 10.0.0.5}, arp_cache_timeout = 10, tcp_keepalive_interval = 10);
>      encodes as 
> controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.6f.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.ff.00.1a.02.05.78.13.01.01.17.01.79.06.08.08.08.08.08.07.07.07.07.79.14.18.1e.00.00.0a.00.00.04.10.28.00.0a.00.00.06.00.0a.00.00.01.24.01.01.1f.01.00.96.08.0a.00.00.04.0a.00.00.05.23.04.00.00.00.0a.26.04.00.00.00.0a,pause)
> @@ -1292,10 +1292,10 @@ reg0[15] = 
> put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.255.0,
>      encodes as 
> controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.6f.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.ff.00.1a.02.05.78.13.01.01.17.01.79.06.08.08.08.08.08.07.07.07.07.79.14.18.1e.00.00.0a.00.00.04.10.28.00.0a.00.00.06.00.0a.00.00.01.24.01.01.1f.01.00.42.10.74.66.74.70.5f.73.65.72.76.65.72.5f.74.65.73.74,pause)
>  reg2[5] = 
> put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain_name="ovn.org",wpad="https://example.org",bootfile_name="https://127.0.0.1/boot.ipxe",path_prefix="/tftpboot",domain_search_list="ovn.org,abc.ovn.org";);
>      formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 
> 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain_name = "ovn.org", wpad 
> = "https://example.org";, bootfile_name = "https://127.0.0.1/boot.ipxe";, 
> path_prefix = "/tftpboot", domain_search_list = "ovn.org,abc.ovn.org");
> -    encodes as 
> controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67.43.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.d2.09.2f.74.66.74.70.62.6f.6f.74.77.0f.03.6f.76.6e.03.6f.72.67.00.03.61.62.63.c0.00,pause)
> +    encodes as 
> controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.43.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.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67.d2.09.2f.74.66.74.70.62.6f.6f.74.77.0f.03.6f.76.6e.03.6f.72.67.00.03.61.62.63.c0.00,pause)
>  reg2[5] = 
> put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain_name="ovn.org",wpad="https://example.org",bootfile_name="https://127.0.0.1/boot.ipxe",path_prefix="/tftpboot",domain_search_list="ovn.org,abc.ovn.org,def.ovn.org,ovn.test,def.ovn.test,test.org,abc.com";);
>      formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 
> 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain_name = "ovn.org", wpad 
> = "https://example.org";, bootfile_name = "https://127.0.0.1/boot.ipxe";, 
> path_prefix = "/tftpboot", domain_search_list = 
> "ovn.org,abc.ovn.org,def.ovn.org,ovn.test,def.ovn.test,test.org,abc.com");
> -    encodes as 
> controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67.43.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.d2.09.2f.74.66.74.70.62.6f.6f.74.77.35.03.6f.76.6e.03.6f.72.67.00.03.61.62.63.c0.00.03.64.65.66.c0.00.03.6f.76.6e.04.74.65.73.74.00.03.64.65.66.c0.15.04.74.65.73.74.c0.04.03.61.62.63.03.63.6f.6d.00,pause)
> +    encodes as 
> controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.43.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.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67.d2.09.2f.74.66.74.70.62.6f.6f.74.77.35.03.6f.76.6e.03.6f.72.67.00.03.61.62.63.c0.00.03.64.65.66.c0.00.03.6f.76.6e.04.74.65.73.74.00.03.64.65.66.c0.15.04.74.65.73.74.c0.04.03.61.62.63.03.63.6f.6d.00,pause)
>
>  reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
>      Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
> @@ -5310,10 +5310,10 @@ sleep 2
>  as hv1 ovs-vsctl show
>
>  # This shell function sends a DHCP request packet
> -# test_dhcp INPORT SRC_MAC DHCP_TYPE BROADCAST CIADDR OFFER_IP REQUEST_IP 
> USE_IP ...
> +# test_dhcp INPORT SRC_MAC DHCP_TYPE BROADCAST CIADDR OFFER_IP REQUEST_IP 
> ETH_BOOT USE_IP ...
>  test_dhcp() {
> -    local inport=$1 src_mac=$2 dhcp_type=$3 broadcast=$4 ciaddr=$5 
> offer_ip=$6 request_ip=$7 use_ip=$8
> -    shift; shift; shift; shift; shift; shift; shift; shift;
> +    local inport=$1 src_mac=$2 dhcp_type=$3 broadcast=$4 ciaddr=$5 
> offer_ip=$6 request_ip=$7 eth_boot=$8 use_ip=$9
> +    shift; shift; shift; shift; shift; shift; shift; shift; shift;
>
>      if test $use_ip != 0; then
>          src_ip=$1
> @@ -5325,11 +5325,21 @@ test_dhcp() {
>      fi
>
>      if test $request_ip != 0; then
> -        ip_len=0120
> -        udp_len=010b
> +        if test $eth_boot != 0; then
> +            ip_len=0124
> +            udp_len=010f
> +        else
> +            ip_len=0120
> +            udp_len=010b
> +        fi
>      else
> -        ip_len=011a
> -        udp_len=0106
> +        if test $eth_boot != 0; then
> +            ip_len=011e
> +            udp_len=010a
> +        else
> +            ip_len=011a
> +            udp_len=0106
> +        fi
>      fi
>
>      if test $broadcast != 0; then
> @@ -5370,6 +5380,9 @@ test_dhcp() {
>          # dhcp requested ip
>          request=${request}3204${request_ip}
>      fi
> +    if test $eth_boot != 0; then
> +        request=${request}af020000
> +    fi
>      # dhcp end option
>      request=${request}ff
>
> @@ -5465,7 +5478,7 @@ server_ip=`ip_to_hex 10 0 0 1`
>  ciaddr=`ip_to_hex 0 0 0 0`
>  request_ip=0
>  expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
> -test_dhcp 1 f00000000001 01 0 $ciaddr $offer_ip $request_ip 0 ff1000000001 
> $server_ip 02 $expected_dhcp_opts
> +test_dhcp 1 f00000000001 01 0 $ciaddr $offer_ip $request_ip 0 0 ff1000000001 
> $server_ip 02 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 1.
>  OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5491,7 +5504,7 @@ server_ip=`ip_to_hex 10 0 0 1`
>  ciaddr=`ip_to_hex 0 0 0 0`
>  request_ip=$offer_ip
>  expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
> -test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 ff1000000001 
> $server_ip 05 $expected_dhcp_opts
> +test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0 ff1000000001 
> $server_ip 05 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 2.
>  OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5515,7 +5528,7 @@ server_ip=`ip_to_hex 10 0 0 1`
>  ciaddr=`ip_to_hex 0 0 0 0`
>  request_ip=`ip_to_hex 10 0 0 7`
>  expected_dhcp_opts=""
> -test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 ff1000000001 
> $server_ip 06 $expected_dhcp_opts
> +test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0 ff1000000001 
> $server_ip 06 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 3.
>  OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5539,7 +5552,7 @@ rm -f 2.expected
>  ciaddr=`ip_to_hex 0 0 0 0`
>  offer_ip=0
>  request_ip=0
> -test_dhcp 2 f00000000002 09 0 $ciaddr $offer_ip $request_ip 0 1 1
> +test_dhcp 2 f00000000002 09 0 $ciaddr $offer_ip $request_ip 0 0 1 1
>
>  # NXT_RESUMEs should be 4.
>  OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5556,18 +5569,18 @@ rm -f 2.expected
>  # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
>
>  ciaddr=`ip_to_hex 0 0 0 0`
> -test_dhcp 3 f00000000003 01 0 $ciaddr 0 0 4 0
> +test_dhcp 3 f00000000003 01 0 $ciaddr 0 0 0 4 0
>
>  # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
>  # this lport.
>  ciaddr=`ip_to_hex 0 0 0 0`
> -test_dhcp 4 f00000000004 01 0 $ciaddr 0 0 3 0
> +test_dhcp 4 f00000000004 01 0 $ciaddr 0 0 0 3 0
>
>  # NXT_RESUMEs should be 4.
>  OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
>
> -#OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
> -#OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
> +OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
> +OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
>
>  # Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 
> 10.0.0.6
>  # and ip4.dst set to 10.0.0.1.
> @@ -5578,7 +5591,7 @@ request_ip=0
>  src_ip=$offer_ip
>  dst_ip=$server_ip
>  expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
> -test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> +test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 5.
>  OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5604,7 +5617,7 @@ request_ip=0
>  src_ip=$offer_ip
>  dst_ip=`ip_to_hex 255 255 255 255`
>  expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
> -test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> +test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 6.
>  OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5630,7 +5643,7 @@ request_ip=0
>  src_ip=$offer_ip
>  dst_ip=`ip_to_hex 255 255 255 255`
>  expected_dhcp_opts=""
> -test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
> +test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 7.
>  OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5656,7 +5669,7 @@ request_ip=0
>  src_ip=$offer_ip
>  dst_ip=`ip_to_hex 255 255 255 255`
>  expected_dhcp_opts=""
> -test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
> +test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 8.
>  OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5678,7 +5691,7 @@ rm -f 2.expected
>  ciaddr=`ip_to_hex 0 0 0 0`
>  src_ip=`ip_to_hex 10 0 0 6`
>  dst_ip=`ip_to_hex 10 0 0 4`
> -test_dhcp 2 f00000000002 03 0 $ciaddr 0 0 1 $src_ip $dst_ip 1
> +test_dhcp 2 f00000000002 03 0 $ciaddr 0 0 0 1 $src_ip $dst_ip 1
>
>  # NXT_RESUMEs should be 8.
>  OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5697,7 +5710,7 @@ server_ip=`ip_to_hex 10 0 0 1`
>  ciaddr=`ip_to_hex 0 0 0 0`
>  request_ip=0
>  expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
> -test_dhcp 1 f00000000001 01 1 $ciaddr $offer_ip $request_ip 0 ff1000000001 
> $server_ip 02 $expected_dhcp_opts
> +test_dhcp 1 f00000000001 01 1 $ciaddr $offer_ip $request_ip 0 0 ff1000000001 
> $server_ip 02 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 9.
>  OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5720,7 +5733,7 @@ server_ip=`ip_to_hex 10 0 0 1`
>  ciaddr=`ip_to_hex 10 0 0 6`
>  request_ip=0
>  expected_dhcp_opts=0
> -test_dhcp 2 f00000000002 07 0 $ciaddr $offer_ip $request_ip 0 ff1000000001
> +test_dhcp 2 f00000000002 07 0 $ciaddr $offer_ip $request_ip 0 0 ff1000000001
>
>  # NXT_RESUMEs should be 10.
>  OVS_WAIT_UNTIL([test 10 = $(cat ofctl_monitor*.log | grep -c NXT_RESUME)])
> @@ -5747,7 +5760,7 @@ dst_ip=$server_ip
>  # In the expected_dhcp_opts we should not see 330400000e10 which is
>  # dhcp lease time option and 0104ffffff00 which is subnet mask option.
>  expected_dhcp_opts=03040a00000136040a000001
> -test_dhcp 2 f00000000002 08 0 $ciaddr $offer_ip $request_ip 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> +test_dhcp 2 f00000000002 08 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 11.
>  OVS_WAIT_UNTIL([test 11 = $(cat ofctl_monitor*.log | grep -c NXT_RESUME)])
> @@ -5777,7 +5790,7 @@ dst_ip=$server_ip
>  # In the expected_dhcp_opts we should not see 330400000e10 which is
>  # dhcp lease time option.
>  
> expected_dhcp_opts=3a0400000fa0330400000e100104ffffff0003040a00000136040a000001
> -test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> +test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 12.
>  OVS_WAIT_UNTIL([test 12 = $(cat ofctl_monitor*.log | grep -c NXT_RESUME)])
> @@ -5804,7 +5817,7 @@ dst_ip=$server_ip
>  # In the expected_dhcp_opts we should not see 330400000e10 which is
>  # dhcp lease time option and 0104ffffff00 which is subnet mask option.
>  expected_dhcp_opts=03040a00000136040a000001
> -test_dhcp 2 f00000000002 08 0 $ciaddr $offer_ip $request_ip 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> +test_dhcp 2 f00000000002 08 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip 
> $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 13.
>  OVS_WAIT_UNTIL([test 13 = $(cat ofctl_monitor*.log | grep -c NXT_RESUME)])
> @@ -5835,7 +5848,7 @@ server_ip=`ip_to_hex 10 0 0 1`
>  ciaddr=`ip_to_hex 0 0 0 0`
>  request_ip=$offer_ip
>  
> expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a00000142040a0a0a0a
> -test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 ff1000000001 
> $server_ip 05 $expected_dhcp_opts
> +test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0 ff1000000001 
> $server_ip 05 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 14.
>  OVS_WAIT_UNTIL([test 14 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5866,7 +5879,7 @@ server_ip=`ip_to_hex 10 0 0 1`
>  ciaddr=`ip_to_hex 0 0 0 0`
>  request_ip=$offer_ip
>  
> expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a0000014210746573745f746674705f736572766572
> -test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 ff1000000001 
> $server_ip 05 $expected_dhcp_opts
> +test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0 ff1000000001 
> $server_ip 05 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 15.
>  OVS_WAIT_UNTIL([test 15 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5897,7 +5910,7 @@ server_ip=`ip_to_hex 10 0 0 1`
>  ciaddr=`ip_to_hex 0 0 0 0`
>  request_ip=$offer_ip
>  
> expected_dhcp_opts=771305746573743103636f6d00057465737432c006330400000e100104ffffff0003040a00000136040a000001
> -test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 ff1000000001 
> $server_ip 05 $expected_dhcp_opts
> +test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0 ff1000000001 
> $server_ip 05 $expected_dhcp_opts
>
>  # NXT_RESUMEs should be 16.
>  OVS_WAIT_UNTIL([test 16 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
> @@ -5915,9 +5928,42 @@ server_ip=`ip_to_hex 10 0 0 1`
>  ciaddr=`ip_to_hex 0 0 0 0`
>  request_ip=0
>  expected_dhcp_opts=""
> -test_dhcp 1 f00000000001 04 0 $ciaddr $offer_ip $request_ip 0 ff1000000001 
> $server_ip 02 $expected_dhcp_opts
> +test_dhcp 1 f00000000001 04 0 $ciaddr $offer_ip $request_ip 0 0 ff1000000001 
> $server_ip 02 $expected_dhcp_opts
>  AT_CHECK([fgrep -iq 'DHCPDECLINE from f0:00:00:00:00:01, 10.0.0.4 
> duplicated' hv1/ovn-controller.log], [0], [])
>
> +# Send Etherboot.
> +
> +reset_pcap_file hv1-vif1 hv1/vif1
> +reset_pcap_file hv1-vif2 hv1/vif2
> +rm -f 1.expected
> +rm -f 2.expected
> +
> +ovn-nbctl --all destroy dhcp-option
> +
> +ovn-nbctl dhcp-options-create 10.0.0.0/24
> +d3=$(ovn-nbctl --bare --columns=_uuid find dhcp_options cidr="10.0.0.0/24")
> +ovn-nbctl dhcp-options-set-options $d3 \
> +   server_id=10.0.0.1 server_mac=ff:10:00:00:00:01 \
> +   lease_time=3600 router=10.0.0.1 bootfile_name_alt=\"bootfile_name_alt\" \
> +   bootfile_name=\"bootfile\"
> +
> +ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 $d3
> +
> +offer_ip=`ip_to_hex 10 0 0 4`
> +server_ip=`ip_to_hex 10 0 0 1`
> +ciaddr=`ip_to_hex 0 0 0 0`
> +request_ip=0
> +boofile=4308626f6f7466696c65
> +expected_dhcp_opts=${boofile}330400000e100104ffffff0003040a00000136040a000001
> +test_dhcp 1 f00000000001 01 0 $ciaddr $offer_ip $request_ip 1 0 ff1000000001 
> $server_ip 02 $expected_dhcp_opts
> +
> +$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
> +cat 1.expected | cut -c -48 > expout
> +AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
> +# Skipping the IPv4 checksum.
> +cat 1.expected | cut -c 53- > expout
> +AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
> +
>  OVN_CLEANUP([hv1])
>
>  AT_CLEANUP
> diff --git a/tests/test-ovn.c b/tests/test-ovn.c
> index d94ab025d..80d99b7a8 100644
> --- a/tests/test-ovn.c
> +++ b/tests/test-ovn.c
> @@ -191,6 +191,7 @@ create_gen_opts(struct hmap *dhcp_opts, struct hmap 
> *dhcpv6_opts,
>      dhcp_opt_add(dhcp_opts, "arp_cache_timeout", 35, "uint32");
>      dhcp_opt_add(dhcp_opts, "tcp_keepalive_interval", 38, "uint32");
>      dhcp_opt_add(dhcp_opts, "domain_search_list", 119, "domains");
> +    dhcp_opt_add(dhcp_opts, "bootfile_name_alt", 254, "str");
>
>      /* DHCPv6 options. */
>      hmap_init(dhcpv6_opts);
> --
> 2.26.2
>
> _______________________________________________
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to