diff -urNp grub-2.02-rc1.orig/grub-core/kern/ieee1275/init.c grub-2.02-rc1/grub-core/kern/ieee1275/init.c --- grub-2.02-rc1.orig/grub-core/kern/ieee1275/init.c 2017-02-08 15:06:05.420317447 +0000 +++ grub-2.02-rc1/grub-core/kern/ieee1275/init.c 2017-02-08 15:06:17.784317308 +0000 @@ -125,6 +125,7 @@ grub_machine_get_bootlocation (char **de char *dev, *canon; char *ptr; dev = grub_ieee1275_get_aliasdevname (bootpath); + grub_ieee1275_parse_net_options (bootpath); canon = grub_ieee1275_canonicalise_devname (dev); ptr = canon + grub_strlen (canon) - 1; while (ptr > canon && (*ptr == ',' || *ptr == ':')) diff -urNp grub-2.02-rc1.orig/grub-core/kern/ieee1275/openfw.c grub-2.02-rc1/grub-core/kern/ieee1275/openfw.c --- grub-2.02-rc1.orig/grub-core/kern/ieee1275/openfw.c 2017-02-08 15:06:05.420317447 +0000 +++ grub-2.02-rc1/grub-core/kern/ieee1275/openfw.c 2017-02-08 15:06:17.785317308 +0000 @@ -23,6 +23,7 @@ #include #include #include +#include enum grub_ieee1275_parse_type { @@ -451,6 +452,35 @@ fail: return ret; } +int +grub_ieee1275_parse_net_options (const char *path) +{ + char *comma; + char *args; + char *option = 0; + + args = grub_ieee1275_get_devargs (path); + if (!args) + /* There is no option. */ + return -1; + + do + { + comma = grub_strchr (args, ','); + if (! comma) + option = grub_strdup (args); + else + option = grub_strndup (args, (grub_size_t)(comma - args)); + args = comma + 1; + + if (! grub_strncmp(option, "vtag", 4)) + grub_env_set ("vlan-tag", option + grub_strlen("vtag=")); + + } while (comma); + + return 0; +} + char * grub_ieee1275_get_device_type (const char *path) { diff -urNp grub-2.02-rc1.orig/grub-core/net/ethernet.c grub-2.02-rc1/grub-core/net/ethernet.c --- grub-2.02-rc1.orig/grub-core/net/ethernet.c 2017-02-08 15:06:05.433317447 +0000 +++ grub-2.02-rc1/grub-core/net/ethernet.c 2017-02-08 15:06:17.785317308 +0000 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -56,10 +57,19 @@ send_ethernet_packet (struct grub_net_ne { struct etherhdr *eth; grub_err_t err; + grub_uint32_t vlantag = 0; + grub_uint8_t etherhdr_size; - COMPILE_TIME_ASSERT (sizeof (*eth) < GRUB_NET_MAX_LINK_HEADER_SIZE); + etherhdr_size = sizeof (*eth); + COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE); - err = grub_netbuff_push (nb, sizeof (*eth)); + const char *vlantag_text = grub_env_get ("vlan-tag"); + if (vlantag_text != 0) { + etherhdr_size += 4; + vlantag = grub_strtoul (vlantag_text, 0, 16); + } + + err = grub_netbuff_push (nb, etherhdr_size); if (err) return err; eth = (struct etherhdr *) nb->data; @@ -76,6 +86,19 @@ send_ethernet_packet (struct grub_net_ne return err; inf->card->opened = 1; } + + /* Check if a vlan-tag is needed. */ + if (vlantag != 0) + { + /* Move eth type to the right */ + grub_memcpy((char *) nb->data + etherhdr_size - 2, + (char *) nb->data + etherhdr_size - 6, 2); + + /* Add the tag in the middle */ + grub_memcpy((char *) nb->data + etherhdr_size - 6, + &vlantag, 4); + } + return inf->card->driver->send (inf->card, nb); } @@ -90,10 +113,23 @@ grub_net_recv_ethernet_packet (struct gr grub_net_link_level_address_t hwaddress; grub_net_link_level_address_t src_hwaddress; grub_err_t err; + grub_uint8_t etherhdr_size = sizeof (*eth); + + grub_uint16_t vlantag_identifier = 0; + grub_memcpy (&vlantag_identifier, nb->data + etherhdr_size - 2, 2); + + /* Check if a vlan-tag is present. */ + if (vlantag_identifier == VLANTAG_IDENTIFIER) + { + etherhdr_size += 4; + /* Move eth type to the original position */ + grub_memcpy((char *) nb->data + etherhdr_size - 6, + (char *) nb->data + etherhdr_size - 2, 2); + } eth = (struct etherhdr *) nb->data; type = grub_be_to_cpu16 (eth->type); - err = grub_netbuff_pull (nb, sizeof (*eth)); + err = grub_netbuff_pull (nb, etherhdr_size); if (err) return err; diff -urNp grub-2.02-rc1.orig/include/grub/ieee1275/ieee1275.h grub-2.02-rc1/include/grub/ieee1275/ieee1275.h --- grub-2.02-rc1.orig/include/grub/ieee1275/ieee1275.h 2017-02-08 15:06:05.445317447 +0000 +++ grub-2.02-rc1/include/grub/ieee1275/ieee1275.h 2017-02-08 15:06:17.787317308 +0000 @@ -227,6 +227,7 @@ char *EXPORT_FUNC(grub_ieee1275_get_alia char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path); char *EXPORT_FUNC(grub_ieee1275_get_device_type) (const char *path); char *EXPORT_FUNC(grub_ieee1275_get_devname) (const char *path); +int EXPORT_FUNC(grub_ieee1275_parse_net_options) (const char *path); void EXPORT_FUNC(grub_ieee1275_devalias_init_iterator) (struct grub_ieee1275_devalias *alias); void EXPORT_FUNC(grub_ieee1275_devalias_free) (struct grub_ieee1275_devalias *alias); diff -urNp grub-2.02-rc1.orig/include/grub/net.h grub-2.02-rc1/include/grub/net.h --- grub-2.02-rc1.orig/include/grub/net.h 2017-02-08 15:06:05.446317447 +0000 +++ grub-2.02-rc1/include/grub/net.h 2017-02-08 15:06:17.788317308 +0000 @@ -561,4 +561,6 @@ extern char *grub_net_default_server; #define GRUB_NET_INTERVAL 400 #define GRUB_NET_INTERVAL_ADDITION 20 +#define VLANTAG_IDENTIFIER 0x8100 + #endif /* ! GRUB_NET_HEADER */