[PATCH v2 2/2] Configure VLAN from UEFI device used for PXE
Signed-off-by: Chad Kimes --- grub-core/net/drivers/efi/efinet.c | 38 ++ 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c index 381c138db..107e1f09e 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c @@ -339,6 +339,10 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, { struct grub_net_card *card; grub_efi_device_path_t *dp; + struct grub_net_network_level_interface *inter; + grub_efi_device_path_t *vlan_dp; + grub_efi_uint16_t vlan_dp_len; + grub_efi_vlan_device_path_t *vlan; dp = grub_efi_get_device_path (hnd); if (! dp) @@ -387,11 +391,35 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, if (! pxe) continue; pxe_mode = pxe->mode; -grub_net_configure_by_dhcp_ack (card->name, card, 0, - (struct grub_net_bootp_packet *) - &pxe_mode->dhcp_ack, - sizeof (pxe_mode->dhcp_ack), - 1, device, path); + +inter = grub_net_configure_by_dhcp_ack (card->name, card, 0, + (struct grub_net_bootp_packet *) + &pxe_mode->dhcp_ack, + sizeof (pxe_mode->dhcp_ack), + 1, device, path); + +if (inter) + { + /* +* search the device path for any VLAN subtype and use it +* to configure the interface +*/ + vlan_dp = dp; + + while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (vlan_dp)) + { + if (GRUB_EFI_DEVICE_PATH_TYPE (vlan_dp) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE + && GRUB_EFI_DEVICE_PATH_SUBTYPE (vlan_dp) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE) + { + vlan = (grub_efi_vlan_device_path_t *) vlan_dp; + inter->vlantag = vlan->vlan_id; + break; + } + + vlan_dp_len = GRUB_EFI_DEVICE_PATH_LENGTH (vlan_dp); + vlan_dp = (grub_efi_device_path_t *) ((char *) vlan_dp + vlan_dp_len); + } + } return; } } -- 2.25.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 1/2] Print VLAN info in EFI device path
Signed-off-by: Chad Kimes --- grub-core/kern/efi/efi.c | 7 +++ include/grub/efi/api.h | 9 + 2 files changed, 16 insertions(+) diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index 18858c327..d60a0b3e6 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -832,6 +832,13 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) sata->lun); } break; + case GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE: + { + grub_efi_vlan_device_path_t *vlan; + vlan = (grub_efi_vlan_device_path_t *) dp; + grub_printf ("/Vlan(%u)", vlan->vlan_id); + } + break; case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE: dump_vendor_path ("Messaging", diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index 6c8d06e15..b8ec19aab 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -903,6 +903,15 @@ struct grub_efi_sata_device_path } GRUB_PACKED; typedef struct grub_efi_sata_device_path grub_efi_sata_device_path_t; +#define GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE 20 + +struct grub_efi_vlan_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t vlan_id; +} GRUB_PACKED; +typedef struct grub_efi_vlan_device_path grub_efi_vlan_device_path_t; + #define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10 /* Media Device Path. */ -- 2.25.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 0/2] Automatically configure VLAN from PXE on UEFI
This patch series introduces automatic configuration of 802.1Q VLAN identifiers if the interface used for PXE booting on UEFI hardware was configured with a VLAN. The first patch adds the necessary types for parsing VLAN info from UEFI device paths, and uses that to produce a Vlan(x) device in the grub_efi_print_device_path output. The second patch handles automatic configuration of VLAN when booting from PXE on UEFI hardware. This patch depends on types introduced in the first patch. Chad Kimes (2): Print VLAN info in EFI device path Configure VLAN from UEFI device used for PXE grub-core/kern/efi/efi.c | 7 ++ grub-core/net/drivers/efi/efinet.c | 38 ++ include/grub/efi/api.h | 9 +++ 3 files changed, 49 insertions(+), 5 deletions(-) -- 2.25.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 1/2] Add vlan information to net_ls_addr output
Example output: grub> net_ls_addr efinet1 00:11:22:33:44:55 192.0.2.100 vlan100 Signed-off-by: Chad Kimes --- grub-core/net/net.c | 19 ++- include/grub/net.h | 6 ++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 4d3eb5c1a..b957b30e4 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -781,6 +781,20 @@ grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str) grub_printf (_("Unsupported hw address type %d\n"), addr->type); } +void +grub_net_vlan_to_str (grub_uint16_t vlantag, char *str) +{ + str[0] = 0; + + /* 12 bits are used to identify the vlan in 802.1Q */ + vlantag = vlantag & 0xFFF; + + if (vlantag == 0) +return; + + grub_snprintf (str, GRUB_NET_MAX_STR_VLAN_LEN, "vlan%u", vlantag); +} + int grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, const grub_net_link_level_address_t *b) @@ -1250,9 +1264,12 @@ grub_cmd_listaddrs (struct grub_command *cmd __attribute__ ((unused)), { char bufh[GRUB_NET_MAX_STR_HWADDR_LEN]; char bufn[GRUB_NET_MAX_STR_ADDR_LEN]; +char bufv[GRUB_NET_MAX_STR_VLAN_LEN]; + grub_net_hwaddr_to_str (&inf->hwaddress, bufh); grub_net_addr_to_str (&inf->address, bufn); -grub_printf ("%s %s %s\n", inf->name, bufh, bufn); +grub_net_vlan_to_str (inf->vlantag, bufv); +grub_printf ("%s %s %s %s\n", inf->name, bufh, bufn, bufv); } return GRUB_ERR_NONE; } diff --git a/include/grub/net.h b/include/grub/net.h index 7ae4b6bd8..b2d044ceb 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -512,12 +512,18 @@ grub_net_addr_cmp (const grub_net_network_level_address_t *a, #define GRUB_NET_MAX_STR_HWADDR_LEN (sizeof ("XX:XX:XX:XX:XX:XX")) +/* Max VLAN id = 4094 */ +#define GRUB_NET_MAX_STR_VLAN_LEN (sizeof ("vlan")) + void grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf); void grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str); +void +grub_net_vlan_to_str (grub_uint16_t vlantag, char *str); + grub_err_t grub_env_set_net_property (const char *intername, const char *suffix, const char *value, grub_size_t len); -- 2.25.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 2/2] Add net_set_vlan command
Previously there was no way to set the 802.1Q VLAN identifier, despite support for vlantag in the net module. The only location vlantag was being populated was from PXE boot and only for Open Firmware hardware. This commit allows users to manually configure VLAN information for any interface. Example usage: grub> net_ls_addr efinet1 00:11:22:33:44:55 192.0.2.100 grub> net_set_vlan efinet1 100 grub> net_ls_addr efinet1 00:11:22:33:44:55 192.0.2.100 vlan100 grub> net_set_vlan efinet1 0 efinet1 00:11:22:33:44:55 192.0.2.100 Signed-off-by: Chad Kimes --- docs/grub.texi | 19 +++ grub-core/net/net.c | 42 +- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/docs/grub.texi b/docs/grub.texi index caba8befb..b903bf1d1 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -5554,6 +5554,7 @@ This command is only available on AArch64 systems. * net_ls_dns:: List DNS servers * net_ls_routes:: List routing entries * net_nslookup::Perform a DNS lookup +* net_set_vlan::Set vlan id on an interface @end menu @@ -5730,6 +5731,24 @@ is given, use default list of servers. @end deffn +@node net_set_vlan +@subsection net_set_vlan + +@deffn Command net_set_vlan @var{interface} @var{vlanid} +Set the 802.1Q VLAN identifier on @var{interface} to @var{vlanid}. For example, to set the VLAN identifier on interface @samp{efinet1} to @samp{100}: + +@example +net_set_vlan efinet1 100 +@end example + +The VLAN identifier can be removed by setting it to @samp{0}: + +@example +net_set_vlan efinet1 0 +@end example +@end deffn + + @node Internationalisation @chapter Internationalisation diff --git a/grub-core/net/net.c b/grub-core/net/net.c index b957b30e4..d79391c04 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -1176,6 +1176,43 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), } } +static grub_err_t +grub_cmd_setvlan (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + const char *vlan_string; + const char *vlan_string_end; + unsigned long vlantag; + struct grub_net_network_level_interface *inter; + + if (argc != 2) +return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); + + vlan_string = args[1]; + vlantag = grub_strtoul (vlan_string, &vlan_string_end, 10); + + if (*vlan_string == '\0' || *vlan_string_end != '\0') +return grub_error (GRUB_ERR_BAD_NUMBER, + N_("non-numeric or invalid number `%s'"), vlan_string); + + if (vlantag > 4094) +return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("vlan id `%s' not in the valid range of 0-4094"), + vlan_string); + + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) +{ + if (grub_strcmp (inter->name, args[0]) != 0) + continue; + + inter->vlantag = vlantag; + return GRUB_ERR_NONE; +} + + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("network interface not found")); +} + static void print_net_address (const grub_net_network_level_netaddress_t *target) { @@ -1892,7 +1929,7 @@ grub_net_search_config_file (char *config) static struct grub_preboot *fini_hnd; static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; -static grub_command_t cmd_lsroutes, cmd_lscards; +static grub_command_t cmd_setvlan, cmd_lsroutes, cmd_lscards; static grub_command_t cmd_lsaddr, cmd_slaac; GRUB_MOD_INIT(net) @@ -1930,6 +1967,9 @@ GRUB_MOD_INIT(net) cmd_delroute = grub_register_command ("net_del_route", grub_cmd_delroute, N_("SHORTNAME"), N_("Delete a network route.")); + cmd_setvlan = grub_register_command ("net_set_vlan", grub_cmd_setvlan, + N_("SHORTNAME VLANID"), + N_("Set an interface's vlan id.")); cmd_lsroutes = grub_register_command ("net_ls_routes", grub_cmd_listroutes, "", N_("list network routes")); cmd_lscards = grub_register_command ("net_ls_cards", grub_cmd_listcards, -- 2.25.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 0/2] Add command-line management of VLAN config
These patches provide functionality to configure 802.1Q VLAN identifiers on existing network interfaces using the GRUB command line. The first patch simply updates the output of net_ls_addr to include information about interface VLAN configuration. The second patch introduces a new command net_set_vlan that allows configuration of a target network interface, for situations where either the user wants to manually configure a VLAN or where the configuration is not properly being populated in the boot process. Chad Kimes (2): Add vlan information to net_ls_addr output Add net_set_vlan command docs/grub.texi | 19 ++ grub-core/net/net.c | 61 +++-- include/grub/net.h | 6 + 3 files changed, 84 insertions(+), 2 deletions(-) -- 2.25.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
Re: [PATCH 2/2] Add net_set_vlan command
Thanks for the review! I'll re-submit this and the other patch series shortly. On Thu, Mar 17, 2022 at 7:03 PM Daniel Kiper wrote: > > On Fri, Mar 04, 2022 at 10:46:36PM -0500, Chad Kimes via Grub-devel wrote: > > Previously there was no way to set the 802.1Q VLAN identifier, despite > > support for vlantag in the net module. The only location vlantag was > > being populated was from PXE boot and only for Open Firmware hardware. > > This commit allows users to manually configure VLAN information for any > > interface. > > > > Example usage: > > grub> net_ls_addr > > efinet1 00:11:22:33:44:55 192.168.0.100 > > grub> net_set_vlan efinet1 100 > > grub> net_ls_addr > > efinet1 00:11:22:33:44:55 192.168.0.100 vlan100 > > grub> net_set_vlan efinet1 0 > > efinet1 00:11:22:33:44:55 192.168.0.100 > > The same comment as for the patch #1. > > > Signed-off-by: Chad Kimes > > --- > > docs/grub.texi | 9 + > > grub-core/net/net.c | 34 +- > > 2 files changed, 42 insertions(+), 1 deletion(-) > > > > diff --git a/docs/grub.texi b/docs/grub.texi > > index caba8befb..5758ec285 100644 > > --- a/docs/grub.texi > > +++ b/docs/grub.texi > > @@ -5553,6 +5553,7 @@ This command is only available on AArch64 systems. > > * net_ls_cards::List network cards > > * net_ls_dns:: List DNS servers > > * net_ls_routes:: List routing entries > > +* net_set_vlan::Set vlan id on an interface > > * net_nslookup::Perform a DNS lookup > > @end menu > > > > @@ -5721,6 +5722,14 @@ List routing entries. > > @end deffn > > > > > > +@node net_set_vlan > > +@subsection net_set_vlan > > + > > +@deffn Command net_set_vlan @var{interface} @var{vlanid} > > +Set the 802.1Q VLAN identifier on @var{interface} to @var{vlanid}. > > +@end deffn > > May I ask you to add an example here? > > > @node net_nslookup > > @subsection net_nslookup > > > > diff --git a/grub-core/net/net.c b/grub-core/net/net.c > > index 33e35d5b5..f2acd2ecf 100644 > > --- a/grub-core/net/net.c > > +++ b/grub-core/net/net.c > > @@ -1176,6 +1176,35 @@ grub_cmd_addroute (struct grub_command *cmd > > __attribute__ ((unused)), > > } > > } > > > > +static grub_err_t > > +grub_cmd_setvlan (struct grub_command *cmd __attribute__ ((unused)), > > + int argc, char **args) > > +{ > > + if (argc < 2) > > +return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments > > expected")); > > + > > + const char *vlanptr = args[1]; > > Please declare all variables at the beginning of the function. > > > + unsigned long vlantag; > > + vlantag = grub_strtoul (vlanptr, &vlanptr, 10); > > + > > + if (vlantag > 4094) > > +return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid vlan id")); > > This check is bogus. Please take a look at commit ac8a37dda (net/http: > Allow use of non-standard TCP/IP ports) how it should be done properly. > > > + struct grub_net_network_level_interface *inter; > > Please move this to the beginning of the function. > > > + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) > > +{ > > + if (grub_strcmp (inter->name, args[0]) != 0) > > + continue; > > + > > + inter->vlantag = vlantag; > > + return GRUB_ERR_NONE; > > +} > > + > > + return grub_error (GRUB_ERR_BAD_ARGUMENT, > > + N_("network interface not found")); > > +} > > + > > static void > > print_net_address (const grub_net_network_level_netaddress_t *target) > > { > > @@ -1892,7 +1921,7 @@ static struct grub_preboot *fini_hnd; > > > > static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; > > static grub_command_t cmd_lsroutes, cmd_lscards; > > -static grub_command_t cmd_lsaddr, cmd_slaac; > > +static grub_command_t cmd_lsaddr, cmd_slaac, cmd_setvlan; > > > > GRUB_MOD_INIT(net) > > { > > @@ -1935,6 +1964,9 @@ GRUB_MOD_INIT(net) > > "", N_("list network cards")); > >cmd_lsaddr = grub_register_command ("net_ls_addr", grub_cmd_listaddrs, > > "", N_("list network addresses")); > > + cmd_setvlan = grub_register_command ("net_set_vlan", grub_cmd_setvlan, &
[PATCH 2/2] Configure VLAN from UEFI device used for PXE
Signed-off-by: Chad Kimes --- grub-core/net/drivers/efi/efinet.c | 38 ++ 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c index 381c138db..98b0f6bef 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c @@ -387,11 +387,39 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, if (! pxe) continue; pxe_mode = pxe->mode; -grub_net_configure_by_dhcp_ack (card->name, card, 0, - (struct grub_net_bootp_packet *) - &pxe_mode->dhcp_ack, - sizeof (pxe_mode->dhcp_ack), - 1, device, path); + +struct grub_net_network_level_interface *inter; +inter = grub_net_configure_by_dhcp_ack (card->name, card, 0, + (struct grub_net_bootp_packet *) + &pxe_mode->dhcp_ack, + sizeof (pxe_mode->dhcp_ack), + 1, device, path); + +if (inter) + { + /* +* search the device path for any VLAN subtype and use it +* to configure the interface +*/ + grub_efi_uint16_t len; + grub_efi_device_path_t *vlan_dp; + vlan_dp = dp; + + while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (vlan_dp)) + { + if (GRUB_EFI_DEVICE_PATH_TYPE (vlan_dp) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE + && GRUB_EFI_DEVICE_PATH_SUBTYPE (vlan_dp) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE) + { + grub_efi_vlan_device_path_t *vlan; + vlan = (grub_efi_vlan_device_path_t *) vlan_dp; + inter->vlantag = vlan->vlan_id; + break; + } + + len = GRUB_EFI_DEVICE_PATH_LENGTH (vlan_dp); + vlan_dp = (grub_efi_device_path_t *) ((char *) vlan_dp + len); + } + } return; } } -- 2.25.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 1/2] Print VLAN info in EFI device path
Signed-off-by: Chad Kimes --- grub-core/kern/efi/efi.c | 7 +++ include/grub/efi/api.h | 9 + 2 files changed, 16 insertions(+) diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index 18858c327..d60a0b3e6 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -832,6 +832,13 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) sata->lun); } break; + case GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE: + { + grub_efi_vlan_device_path_t *vlan; + vlan = (grub_efi_vlan_device_path_t *) dp; + grub_printf ("/Vlan(%u)", vlan->vlan_id); + } + break; case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE: dump_vendor_path ("Messaging", diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index 6c8d06e15..b8ec19aab 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -903,6 +903,15 @@ struct grub_efi_sata_device_path } GRUB_PACKED; typedef struct grub_efi_sata_device_path grub_efi_sata_device_path_t; +#define GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE 20 + +struct grub_efi_vlan_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t vlan_id; +} GRUB_PACKED; +typedef struct grub_efi_vlan_device_path grub_efi_vlan_device_path_t; + #define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10 /* Media Device Path. */ -- 2.25.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 2/2] Add net_set_vlan command
Previously there was no way to set the 802.1Q VLAN identifier, despite support for vlantag in the net module. The only location vlantag was being populated was from PXE boot and only for Open Firmware hardware. This commit allows users to manually configure VLAN information for any interface. Example usage: grub> net_ls_addr efinet1 00:11:22:33:44:55 192.168.0.100 grub> net_set_vlan efinet1 100 grub> net_ls_addr efinet1 00:11:22:33:44:55 192.168.0.100 vlan100 grub> net_set_vlan efinet1 0 efinet1 00:11:22:33:44:55 192.168.0.100 Signed-off-by: Chad Kimes --- docs/grub.texi | 9 + grub-core/net/net.c | 34 +- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/docs/grub.texi b/docs/grub.texi index caba8befb..5758ec285 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -5553,6 +5553,7 @@ This command is only available on AArch64 systems. * net_ls_cards::List network cards * net_ls_dns:: List DNS servers * net_ls_routes:: List routing entries +* net_set_vlan::Set vlan id on an interface * net_nslookup::Perform a DNS lookup @end menu @@ -5721,6 +5722,14 @@ List routing entries. @end deffn +@node net_set_vlan +@subsection net_set_vlan + +@deffn Command net_set_vlan @var{interface} @var{vlanid} +Set the 802.1Q VLAN identifier on @var{interface} to @var{vlanid}. +@end deffn + + @node net_nslookup @subsection net_nslookup diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 33e35d5b5..f2acd2ecf 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -1176,6 +1176,35 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), } } +static grub_err_t +grub_cmd_setvlan (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + if (argc < 2) +return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); + + const char *vlanptr = args[1]; + unsigned long vlantag; + vlantag = grub_strtoul (vlanptr, &vlanptr, 10); + + if (vlantag > 4094) +return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid vlan id")); + + struct grub_net_network_level_interface *inter; + + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) +{ + if (grub_strcmp (inter->name, args[0]) != 0) + continue; + + inter->vlantag = vlantag; + return GRUB_ERR_NONE; +} + + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("network interface not found")); +} + static void print_net_address (const grub_net_network_level_netaddress_t *target) { @@ -1892,7 +1921,7 @@ static struct grub_preboot *fini_hnd; static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; static grub_command_t cmd_lsroutes, cmd_lscards; -static grub_command_t cmd_lsaddr, cmd_slaac; +static grub_command_t cmd_lsaddr, cmd_slaac, cmd_setvlan; GRUB_MOD_INIT(net) { @@ -1935,6 +1964,9 @@ GRUB_MOD_INIT(net) "", N_("list network cards")); cmd_lsaddr = grub_register_command ("net_ls_addr", grub_cmd_listaddrs, "", N_("list network addresses")); + cmd_setvlan = grub_register_command ("net_set_vlan", grub_cmd_setvlan, + N_("SHORTNAME VLANID"), + N_("Set an interace's vlan id.")); grub_bootp_init (); grub_dns_init (); -- 2.25.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH 1/2] Add vlan information to net_ls_addr output
Example output: grub> net_ls_addr efinet1 00:11:22:33:44:55 192.168.0.100 vlan100 Signed-off-by: Chad Kimes --- grub-core/net/net.c | 18 +- include/grub/net.h | 8 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 4d3eb5c1a..33e35d5b5 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -781,6 +781,20 @@ grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str) grub_printf (_("Unsupported hw address type %d\n"), addr->type); } +void +grub_net_vlan_to_str (grub_uint16_t vlantag, char *str) +{ + str[0] = 0; + + /* 12 bits are used to identify the vlan in 802.1Q */ + vlantag = vlantag & 0xFFF; + + if (vlantag == 0) +return; + + grub_snprintf (str, GRUB_NET_MAX_STR_VLAN_LEN, "vlan%u", vlantag); +} + int grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, const grub_net_link_level_address_t *b) @@ -1250,9 +1264,11 @@ grub_cmd_listaddrs (struct grub_command *cmd __attribute__ ((unused)), { char bufh[GRUB_NET_MAX_STR_HWADDR_LEN]; char bufn[GRUB_NET_MAX_STR_ADDR_LEN]; +char bufv[GRUB_NET_MAX_STR_VLAN_LEN]; grub_net_hwaddr_to_str (&inf->hwaddress, bufh); grub_net_addr_to_str (&inf->address, bufn); -grub_printf ("%s %s %s\n", inf->name, bufh, bufn); +grub_net_vlan_to_str (inf->vlantag, bufv); +grub_printf ("%s %s %s %s\n", inf->name, bufh, bufn, bufv); } return GRUB_ERR_NONE; } diff --git a/include/grub/net.h b/include/grub/net.h index 7ae4b6bd8..7fccad8ec 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -512,12 +512,20 @@ grub_net_addr_cmp (const grub_net_network_level_address_t *a, #define GRUB_NET_MAX_STR_HWADDR_LEN (sizeof ("XX:XX:XX:XX:XX:XX")) +/* + Max VLAN id = 4094 + */ +#define GRUB_NET_MAX_STR_VLAN_LEN (sizeof ("vlan")) + void grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf); void grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str); +void +grub_net_vlan_to_str (grub_uint16_t vlantag, char *str); + grub_err_t grub_env_set_net_property (const char *intername, const char *suffix, const char *value, grub_size_t len); -- 2.25.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2] Fix vlan networking on little-endian systems
Vlan configuration seems to have never worked on little-endian systems. This is likely because VLANTAG_IDENTIFIER is not byte-swapped before copying into the net buffer, nor is vlantag. We can resolve this by using grub_cpu_to_be16 and its inverse when copying vlan info to/from the net buffer. Signed-off-by: Chad Kimes --- grub-core/net/ethernet.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index 4d7ceed6f..a9906338c 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -58,7 +58,7 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, struct etherhdr *eth; grub_err_t err; grub_uint8_t etherhdr_size; - grub_uint16_t vlantag_id = VLANTAG_IDENTIFIER; + grub_uint16_t vlantag_id = grub_cpu_to_be16_compile_time (VLANTAG_IDENTIFIER); etherhdr_size = sizeof (*eth); COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE); @@ -93,8 +93,9 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, (char *) nb->data + etherhdr_size - 6, 2); /* Add the tag in the middle */ + grub_uint16_t vlan = grub_cpu_to_be16 (inf->vlantag); grub_memcpy ((char *) nb->data + etherhdr_size - 6, &vlantag_id, 2); - grub_memcpy ((char *) nb->data + etherhdr_size - 4, (char *) &(inf->vlantag), 2); + grub_memcpy ((char *) nb->data + etherhdr_size - 4, &vlan, 2); } return inf->card->driver->send (inf->card, nb); @@ -118,9 +119,9 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb, /* Check if a vlan-tag is present. If so, the ethernet header is 4 bytes */ /* longer than the original one. The vlantag id is extracted and the header */ /* is reseted to the original size. */ - if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == VLANTAG_IDENTIFIER) + if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == grub_cpu_to_be16_compile_time (VLANTAG_IDENTIFIER)) { - vlantag = grub_get_unaligned16 (nb->data + etherhdr_size); + vlantag = grub_be_to_cpu16 (grub_get_unaligned16 (nb->data + etherhdr_size)); etherhdr_size += 4; /* Move eth type to the original position */ grub_memcpy((char *) nb->data + etherhdr_size - 6, -- 2.25.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH] Fix vlan networking on little-endian systems
Vlan configuration seems to have never worked on little-endian systems. This is likely because VLANTAG_IDENTIFIER is not byte-swapped before copying into the net buffer, nor is vlantag. We can resolve this by using grub_cpu_to_be16 and its inverse when copying vlan info to/from the net buffer. --- grub-core/net/ethernet.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index 4d7ceed6f..e49ccc940 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -58,7 +58,7 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, struct etherhdr *eth; grub_err_t err; grub_uint8_t etherhdr_size; - grub_uint16_t vlantag_id = VLANTAG_IDENTIFIER; + grub_uint16_t vlantag_id = grub_cpu_to_be16 (VLANTAG_IDENTIFIER); etherhdr_size = sizeof (*eth); COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE); @@ -93,8 +93,9 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, (char *) nb->data + etherhdr_size - 6, 2); /* Add the tag in the middle */ + grub_uint16_t vlan = grub_cpu_to_be16 (inf->vlantag); grub_memcpy ((char *) nb->data + etherhdr_size - 6, &vlantag_id, 2); - grub_memcpy ((char *) nb->data + etherhdr_size - 4, (char *) &(inf->vlantag), 2); + grub_memcpy ((char *) nb->data + etherhdr_size - 4, &vlan, 2); } return inf->card->driver->send (inf->card, nb); @@ -118,9 +119,9 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb, /* Check if a vlan-tag is present. If so, the ethernet header is 4 bytes */ /* longer than the original one. The vlantag id is extracted and the header */ /* is reseted to the original size. */ - if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == VLANTAG_IDENTIFIER) + if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == grub_cpu_to_be16 (VLANTAG_IDENTIFIER)) { - vlantag = grub_get_unaligned16 (nb->data + etherhdr_size); + vlantag = grub_be_to_cpu16 (grub_get_unaligned16 (nb->data + etherhdr_size)); etherhdr_size += 4; /* Move eth type to the original position */ grub_memcpy((char *) nb->data + etherhdr_size - 6, -- 2.25.1 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH] Fix vlan networking on little-endian systems
The interface vlantag appears to have never worked on little-endian systems. This small initial patch is mostly to get my feet wet in the GRUB dev process. Once this is accepted, I intend to submit a few more patches that (a) allow vlan configuration via a command from the net module and (b) auto-configure vlan from the UEFI device used for PXE booting. diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index 4d7ceed6f..e49ccc940 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -58,7 +58,7 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, struct etherhdr *eth; grub_err_t err; grub_uint8_t etherhdr_size; - grub_uint16_t vlantag_id = VLANTAG_IDENTIFIER; + grub_uint16_t vlantag_id = grub_cpu_to_be16 (VLANTAG_IDENTIFIER); etherhdr_size = sizeof (*eth); COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE); @@ -93,8 +93,9 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, (char *) nb->data + etherhdr_size - 6, 2); /* Add the tag in the middle */ + grub_uint16_t vlantag = grub_cpu_to_be16 (inf->vlantag); grub_memcpy ((char *) nb->data + etherhdr_size - 6, &vlantag_id, 2); - grub_memcpy ((char *) nb->data + etherhdr_size - 4, (char *) &(inf->vlantag), 2); + grub_memcpy ((char *) nb->data + etherhdr_size - 4, &vlantag, 2); } return inf->card->driver->send (inf->card, nb); @@ -118,9 +119,9 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb, /* Check if a vlan-tag is present. If so, the ethernet header is 4 bytes */ /* longer than the original one. The vlantag id is extracted and the header */ /* is reseted to the original size. */ - if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == VLANTAG_IDENTIFIER) + if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == grub_cpu_to_be16 (VLANTAG_IDENTIFIER)) { - vlantag = grub_get_unaligned16 (nb->data + etherhdr_size); + vlantag = grub_be_to_cpu16 (grub_get_unaligned16 (nb->data + etherhdr_size)); etherhdr_size += 4; /* Move eth type to the original position */ grub_memcpy((char *) nb->data + etherhdr_size - 6, ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel