[PATCH v2 2/2] Configure VLAN from UEFI device used for PXE

2022-03-21 Thread Chad Kimes via Grub-devel
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

2022-03-21 Thread Chad Kimes via Grub-devel
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

2022-03-21 Thread Chad Kimes via Grub-devel
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

2022-03-21 Thread Chad Kimes via Grub-devel
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

2022-03-21 Thread Chad Kimes via Grub-devel
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

2022-03-21 Thread Chad Kimes via Grub-devel
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

2022-03-21 Thread Chad Kimes via Grub-devel
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

2022-03-05 Thread Chad Kimes via Grub-devel
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

2022-03-05 Thread Chad Kimes via Grub-devel
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

2022-03-04 Thread Chad Kimes via Grub-devel
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

2022-03-04 Thread Chad Kimes via Grub-devel
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

2022-03-02 Thread Chad Kimes via Grub-devel
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

2022-03-01 Thread Chad Kimes via Grub-devel
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

2022-03-01 Thread Chad Kimes via Grub-devel
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