discover/pxe: Format IPAPPEND mac addresses correctly
authorSamuel Mendoza-Jonas <sam.mj@au1.ibm.com>
Wed, 3 Dec 2014 04:08:23 +0000 (15:08 +1100)
committerJeremy Kerr <jk@ozlabs.org>
Wed, 3 Dec 2014 04:12:47 +0000 (12:12 +0800)
The SYSAPPEND/IPAPPEND option 2 in PXE configs requires
the MAC address of the booting interface to be appended
to the boot options. Previously we formatted this as

"BOOTIF=01:02:03:04:05:06",

but syslinux/pxelinux implementation use this format:

"BOOTIF=01-01-02-03-04-05-06",

where the leading '01' represents the hardware type.

The relevant part of the pxelinux doc is at:

http://www.syslinux.org/wiki/index.php/SYSLINUX#SYSAPPEND_bitmask

Signed-off-by: Samuel Mendoza-Jonas <sam.mj@au1.ibm.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
discover/device-handler.c
discover/device-handler.h
discover/network.c
discover/network.h
discover/pxe-parser.c
test/parser/Makefile.am
test/parser/network.c [new file with mode: 0644]
test/parser/parser-test.h
test/parser/test-pxe-ipappend.c
test/parser/utils.c

index 7cf52636e56766db936d3bdb70ff104b17dd7797..64fc9fab2a5031556ea5e27a76be98903629999a 100644 (file)
@@ -626,6 +626,7 @@ struct discover_context *device_handler_discover_context_create(
 
        ctx = talloc_zero(handler, struct discover_context);
        ctx->device = device;
 
        ctx = talloc_zero(handler, struct discover_context);
        ctx->device = device;
+       ctx->network = handler->network;
        list_init(&ctx->boot_options);
 
        return ctx;
        list_init(&ctx->boot_options);
 
        return ctx;
index e8e71ad9eedf4fd2e38c63e3c8722d64fa9cbedc..b592c462494da3179deda8f9cb69e540bf26ee98 100644 (file)
@@ -55,6 +55,7 @@ struct discover_context {
        struct discover_device  *device;
        struct list             boot_options;
        struct pb_url           *conf_url;
        struct discover_device  *device;
        struct list             boot_options;
        struct pb_url           *conf_url;
+       struct network          *network;
        void                    *test_data;
 };
 
        void                    *test_data;
 };
 
index c9460ac5ae4a0802c15eebf9a1c3c948a5eaabf8..3946694615fd4d931352610fd8abbafafd8a8264 100644 (file)
@@ -109,6 +109,19 @@ static struct interface *find_interface_by_name(struct network *network,
        return NULL;
 }
 
        return NULL;
 }
 
+uint8_t *find_mac_by_name(void *ctx, struct network *network,
+               const char *name)
+{
+       struct interface *interface;
+
+       interface = find_interface_by_name(network, name);
+       if (!interface)
+               return NULL;
+
+       return talloc_memdup(ctx, &interface->hwaddr,
+                            sizeof(uint8_t) * HWADDR_SIZE);
+}
+
 static int network_init_netlink(struct network *network)
 {
        struct sockaddr_nl addr;
 static int network_init_netlink(struct network *network)
 {
        struct sockaddr_nl addr;
index bfd1ab12ecea2a013080b85856b960bb715e2723..e5e05d5f8081ff3047cf7e7655318215c082483c 100644 (file)
@@ -15,5 +15,8 @@ void network_register_device(struct network *network,
 void network_unregister_device(struct network *network,
                struct discover_device *dev);
 
 void network_unregister_device(struct network *network,
                struct discover_device *dev);
 
+uint8_t *find_mac_by_name(void *ctx, struct network *network,
+               const char *name);
+
 #endif /* NETWORK_H */
 
 #endif /* NETWORK_H */
 
index 0456f5b90645b08cd8cc5a4499ec05ba219626df..95547c389799ab06ed7dc4f5a06f937e9ed4743e 100644 (file)
@@ -16,6 +16,7 @@
 #include "paths.h"
 #include "event.h"
 #include "user-event.h"
 #include "paths.h"
 #include "event.h"
 #include "user-event.h"
+#include "network.h"
 
 static const char *pxelinux_prefix = "pxelinux.cfg/";
 
 
 static const char *pxelinux_prefix = "pxelinux.cfg/";
 
@@ -79,6 +80,16 @@ static void pxe_append_string(struct discover_boot_option *opt,
                opt->option->boot_args = talloc_strdup(opt->option, str);
 }
 
                opt->option->boot_args = talloc_strdup(opt->option, str);
 }
 
+static char *pxe_sysappend_mac(void *ctx, uint8_t *mac)
+{
+       if (!mac)
+               return NULL;
+
+       return talloc_asprintf(ctx,
+               "BOOTIF=01-%02x-%02x-%02x-%02x-%02x-%02x",
+               mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
 static void pxe_process_sysappend(struct discover_context *ctx,
                struct discover_boot_option *opt,
                unsigned long val)
 static void pxe_process_sysappend(struct discover_context *ctx,
                struct discover_boot_option *opt,
                unsigned long val)
@@ -90,9 +101,10 @@ static void pxe_process_sysappend(struct discover_context *ctx,
                return;
 
        if (val & 0x2) {
                return;
 
        if (val & 0x2) {
-               const char *mac = event_get_param(event, "mac");
-               if (mac) {
-                       str = talloc_asprintf(ctx, "BOOTIF=%s", mac);
+               uint8_t *mac = find_mac_by_name(ctx, ctx->network,
+                                       event->device);
+               str = pxe_sysappend_mac(ctx, mac);
+               if (str) {
                        pxe_append_string(opt, str);
                        talloc_free(str);
                }
                        pxe_append_string(opt, str);
                        talloc_free(str);
                }
index dbf400eaf709424914c866a0b85da9f4fc1904eb..1bb45e8fa11b1cc7bdb796f687affbb02d3f1e67 100644 (file)
@@ -94,6 +94,7 @@ test_parser_libtest_ro_SOURCES = \
        test/parser/main.c \
        test/parser/utils.c \
        test/parser/handler.c \
        test/parser/main.c \
        test/parser/utils.c \
        test/parser/handler.c \
+       test/parser/network.c \
        test/parser/parser-test.h \
        discover/yaboot-parser.c \
        discover/kboot-parser.c \
        test/parser/parser-test.h \
        discover/yaboot-parser.c \
        discover/kboot-parser.c \
diff --git a/test/parser/network.c b/test/parser/network.c
new file mode 100644 (file)
index 0000000..9c57309
--- /dev/null
@@ -0,0 +1,53 @@
+#include <string.h>
+#include <types/types.h>
+#include <talloc/talloc.h>
+#include <sys/socket.h>
+#include <linux/if.h>
+#include "network.h"
+
+struct interface {
+       int     ifindex;
+       char    name[IFNAMSIZ];
+       uint8_t hwaddr[HWADDR_SIZE];
+
+       enum {
+               IFSTATE_NEW,
+               IFSTATE_UP_WAITING_LINK,
+               IFSTATE_CONFIGURED,
+               IFSTATE_IGNORED,
+       } state;
+
+       struct list_item list;
+       struct process *udhcpc_process;
+       struct discover_device *dev;
+};
+
+static struct interface test = {
+       .name = "em1",
+       .hwaddr = {1,2,3,4,5,6},
+};
+
+static struct interface *find_interface_by_name(struct network *network,
+                               const char *name)
+{
+       (void)network;
+
+       if (!strcmp(test.name, name))
+               return &test;
+
+       return NULL;
+}
+
+uint8_t *find_mac_by_name(void *ctx, struct network *network,
+               const char *name)
+{
+       struct interface *interface;
+       (void)network;
+
+       interface = find_interface_by_name(network, name);
+       if (!interface)
+               return NULL;
+
+       return talloc_memdup(ctx, &interface->hwaddr,
+                            sizeof(uint8_t) * HWADDR_SIZE);
+}
index c0339b89a4f2ca809f6ca27e9ffe9986cf99022a..21b5b9ca1c98e48ecb70ba5ad38831d1c32024ba 100644 (file)
@@ -40,6 +40,7 @@ void test_add_dir(struct parser_test *test, struct discover_device *dev,
 void test_set_event_source(struct parser_test *test);
 void test_set_event_param(struct event *event, const char *name,
                const char *value);
 void test_set_event_source(struct parser_test *test);
 void test_set_event_param(struct event *event, const char *name,
                const char *value);
+void test_set_event_device(struct event *event, const char *dev);
 
 #define test_add_file_string(test, dev, filename, str) \
        test_add_file_data(test, dev, filename, str, sizeof(str) - 1)
 
 #define test_add_file_string(test, dev, filename, str) \
        test_add_file_data(test, dev, filename, str, sizeof(str) - 1)
index 4719b5cfacf293a763888bfe1e4bf1292619c94a..3fec6a7d5f2d07f23cdbfd650f52612f5c7edc3e 100644 (file)
@@ -1,5 +1,6 @@
 
 #include "parser-test.h"
 
 #include "parser-test.h"
+#include "network.h"
 
 #if 0 /* PARSER_EMBEDDED_CONFIG */
 default linux
 
 #if 0 /* PARSER_EMBEDDED_CONFIG */
 default linux
@@ -20,8 +21,7 @@ void run_test(struct parser_test *test)
        test_set_event_source(test);
        test_set_event_param(test->ctx->event, "pxeconffile",
                        "tftp://host/dir/conf.txt");
        test_set_event_source(test);
        test_set_event_param(test->ctx->event, "pxeconffile",
                        "tftp://host/dir/conf.txt");
-       test_set_event_param(test->ctx->event, "mac",
-                       "01:02:03:04:05:06");
+       test_set_event_device(test->ctx->event, "em1");
 
        test_run_parser(test, "pxe");
 
 
        test_run_parser(test, "pxe");
 
@@ -31,5 +31,5 @@ void run_test(struct parser_test *test)
        opt = get_boot_option(ctx, 0);
 
        check_name(opt, "linux");
        opt = get_boot_option(ctx, 0);
 
        check_name(opt, "linux");
-       check_args(opt, "command line BOOTIF=01:02:03:04:05:06");
+       check_args(opt, "command line BOOTIF=01-01-02-03-04-05-06");
 }
 }
index 8a6314b442673751eb2dc329d691713b4dd98435..0050d131c6409a9afc80ce53ec16434c95f09cbc 100644 (file)
@@ -207,6 +207,11 @@ void test_set_event_param(struct event *event, const char *name,
         event_set_param(event, name, value);
 }
 
         event_set_param(event, name, value);
 }
 
+void test_set_event_device(struct event *event, const char *dev)
+{
+       event->device = talloc_strdup(event, dev);
+}
+
 int parser_request_file(struct discover_context *ctx,
                struct discover_device *dev, const char *filename,
                char **buf, int *len)
 int parser_request_file(struct discover_context *ctx,
                struct discover_device *dev, const char *filename,
                char **buf, int *len)