Re: [PATCH] fix PXE transmit failure if P_UNKNOWN is not supported

2014-09-26 Thread Andrei Borzenkov
В Sat, 26 Jul 2014 07:55:03 +0400
Andrey Borzenkov  пишет:

> В Fri, 25 Jul 2014 23:38:34 +0200
> Vladimir 'φ-coder/phcoder' Serbinenko  пишет:
> 
> > On 25.07.2014 17:53, Andrey Borzenkov wrote:
> > > Some PXE stacks do not support P_UNKNOWN in UNDI TRANSMIT; nothing is
> > > sent at all. So strip Ethernet header for known frame types and let PXE
> > > stack add it.
> > > 
> > If I'm reading this patch correctly it discards several fields of the
> > packet and i.a. kills vlan fields.
> 
> No, it does not. It discards Ethernet headers only when packet type is
> IP or ARP. VLAN packet will have different type and will be passed
> through as happens currently.
> 

Ping? It fixes real problem in the wild and this exact approach is used
by other PXE stacks, so it is not as it is completely untested.

If this is not acceptable - any idea how this problem can be fixed
short of maintaining explicit black lists?

> 
> >Such low in the stack it should
> > replace the header only in the case of perfect match. It will be perfect
> > match in 99% of configs but we shouldn0t break configs on unaffected
> > machines.



signature.asc
Description: PGP signature
___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH] fix PXE transmit failure if P_UNKNOWN is not supported

2014-07-25 Thread Andrey Borzenkov
В Fri, 25 Jul 2014 23:38:34 +0200
Vladimir 'φ-coder/phcoder' Serbinenko  пишет:

> On 25.07.2014 17:53, Andrey Borzenkov wrote:
> > Some PXE stacks do not support P_UNKNOWN in UNDI TRANSMIT; nothing is
> > sent at all. So strip Ethernet header for known frame types and let PXE
> > stack add it.
> > 
> If I'm reading this patch correctly it discards several fields of the
> packet and i.a. kills vlan fields.

No, it does not. It discards Ethernet headers only when packet type is
IP or ARP. VLAN packet will have different type and will be passed
through as happens currently.


>Such low in the stack it should
> replace the header only in the case of perfect match. It will be perfect
> match in 99% of configs but we shouldn0t break configs on unaffected
> machines.


signature.asc
Description: PGP signature
___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH] fix PXE transmit failure if P_UNKNOWN is not supported

2014-07-25 Thread Vladimir 'φ-coder/phcoder' Serbinenko
On 25.07.2014 17:53, Andrey Borzenkov wrote:
> Some PXE stacks do not support P_UNKNOWN in UNDI TRANSMIT; nothing is
> sent at all. So strip Ethernet header for known frame types and let PXE
> stack add it.
> 
If I'm reading this patch correctly it discards several fields of the
packet and i.a. kills vlan fields. Such low in the stack it should
replace the header only in the case of perfect match. It will be perfect
match in 99% of configs but we shouldn0t break configs on unaffected
machines.
> PXE implementation that fail is e.g.
> 
> 64bit_foxconn with PXE-2.0 (build 082) NIC: SIS900 PXE
> BootROM v1.09 Hook Int19
> 
> Reported-By: Beeblebrox 
> Tested-By: Beeblebrox 
> 
> ---
>  grub-core/net/drivers/i386/pc/pxe.c | 46 
> ++---
>  1 file changed, 43 insertions(+), 3 deletions(-)
> 
> diff --git a/grub-core/net/drivers/i386/pc/pxe.c 
> b/grub-core/net/drivers/i386/pc/pxe.c
> index e8c0b22..3d78bdd 100644
> --- a/grub-core/net/drivers/i386/pc/pxe.c
> +++ b/grub-core/net/drivers/i386/pc/pxe.c
> @@ -25,6 +25,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> @@ -38,6 +39,11 @@ GRUB_MOD_LICENSE ("GPLv3+");
>  #define SEGOFS(x)((SEGMENT(x) << 16) + OFFSET(x))
>  #define LINEAR(x)(void *) x) >> 16) << 4) + ((x) & 0x))
>  
> +#define P_UNKNOWN0
> +#define P_IP 1
> +#define P_ARP2
> +#define P_RARP   3
> +
>  struct grub_pxe_undi_open
>  {
>grub_uint16_t status;
> @@ -256,22 +262,56 @@ grub_pxe_send (struct grub_net_card *dev __attribute__ 
> ((unused)),
>struct grub_pxe_undi_transmit *trans;
>struct grub_pxe_undi_tbd *tbd;
>char *buf;
> +  grub_uint8_t *dst;
> +  grub_uint16_t type;
>  
>trans = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
>grub_memset (trans, 0, sizeof (*trans));
> +  dst = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 128 - 6);
> +  /* First 6 bytes are destination address */
> +  grub_memcpy (dst, pack->data, 6);
> +
> +  /* Some PXE stacks do not support P_UNKNOWN. So strip Ethernet
> + header for known protocols and let PXE implementation add it */
> +  grub_memcpy (&type, pack->data + 12, 2);
> +  switch (type)
> +{
> +case grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP):
> +  trans->protocol = P_IP;
> +  break;
> +case grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_ARP):
> +  trans->protocol = P_ARP;
> +  break;
> +/* grub does not use RARP */
> +default:
> +  trans->protocol = P_UNKNOWN;
> +  break;
> +}
> +  if (trans->protocol)
> +{
> +  grub_err_t err;
> +
> +  err = grub_netbuff_pull (pack, 14);
> +  if (err)
> + return err;
> +  if (dst[0] == 0xff && dst[1] == 0xff && dst[2] == 0xff &&
> +   dst[3] == 0xff && dst[4] == 0xff && dst[5] == 0xff)
> + trans->xmitflag = 1;
> +  else
> + trans->dest = SEGOFS ((grub_addr_t) dst);
> +}
> +
>tbd = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 128);
>grub_memset (tbd, 0, sizeof (*tbd));
>buf = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 256);
>grub_memcpy (buf, pack->data, pack->tail - pack->data);
> -
>trans->tbd = SEGOFS ((grub_addr_t) tbd);
> -  trans->protocol = 0;
>tbd->len = pack->tail - pack->data;
>tbd->buf = SEGOFS ((grub_addr_t) buf);
>  
>grub_pxe_call (GRUB_PXENV_UNDI_TRANSMIT, trans, pxe_rm_entry);
>if (trans->status)
> -return grub_error (GRUB_ERR_IO, N_("couldn't send network packet"));
> +return grub_error (GRUB_ERR_IO, N_("couldn't send network packet, PXE 
> status: 0x%04x"), trans->status);
>return 0;
>  }
>  
> 




signature.asc
Description: OpenPGP digital signature
___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH] fix PXE transmit failure if P_UNKNOWN is not supported

2014-07-25 Thread Andrey Borzenkov
Some PXE stacks do not support P_UNKNOWN in UNDI TRANSMIT; nothing is
sent at all. So strip Ethernet header for known frame types and let PXE
stack add it.

PXE implementation that fail is e.g.

64bit_foxconn with PXE-2.0 (build 082) NIC: SIS900 PXE
BootROM v1.09 Hook Int19

Reported-By: Beeblebrox 
Tested-By: Beeblebrox 

---
 grub-core/net/drivers/i386/pc/pxe.c | 46 ++---
 1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/grub-core/net/drivers/i386/pc/pxe.c 
b/grub-core/net/drivers/i386/pc/pxe.c
index e8c0b22..3d78bdd 100644
--- a/grub-core/net/drivers/i386/pc/pxe.c
+++ b/grub-core/net/drivers/i386/pc/pxe.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -38,6 +39,11 @@ GRUB_MOD_LICENSE ("GPLv3+");
 #define SEGOFS(x)  ((SEGMENT(x) << 16) + OFFSET(x))
 #define LINEAR(x)  (void *) x) >> 16) << 4) + ((x) & 0x))
 
+#define P_UNKNOWN  0
+#define P_IP   1
+#define P_ARP  2
+#define P_RARP 3
+
 struct grub_pxe_undi_open
 {
   grub_uint16_t status;
@@ -256,22 +262,56 @@ grub_pxe_send (struct grub_net_card *dev __attribute__ 
((unused)),
   struct grub_pxe_undi_transmit *trans;
   struct grub_pxe_undi_tbd *tbd;
   char *buf;
+  grub_uint8_t *dst;
+  grub_uint16_t type;
 
   trans = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
   grub_memset (trans, 0, sizeof (*trans));
+  dst = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 128 - 6);
+  /* First 6 bytes are destination address */
+  grub_memcpy (dst, pack->data, 6);
+
+  /* Some PXE stacks do not support P_UNKNOWN. So strip Ethernet
+ header for known protocols and let PXE implementation add it */
+  grub_memcpy (&type, pack->data + 12, 2);
+  switch (type)
+{
+case grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP):
+  trans->protocol = P_IP;
+  break;
+case grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_ARP):
+  trans->protocol = P_ARP;
+  break;
+/* grub does not use RARP */
+default:
+  trans->protocol = P_UNKNOWN;
+  break;
+}
+  if (trans->protocol)
+{
+  grub_err_t err;
+
+  err = grub_netbuff_pull (pack, 14);
+  if (err)
+   return err;
+  if (dst[0] == 0xff && dst[1] == 0xff && dst[2] == 0xff &&
+ dst[3] == 0xff && dst[4] == 0xff && dst[5] == 0xff)
+   trans->xmitflag = 1;
+  else
+   trans->dest = SEGOFS ((grub_addr_t) dst);
+}
+
   tbd = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 128);
   grub_memset (tbd, 0, sizeof (*tbd));
   buf = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 256);
   grub_memcpy (buf, pack->data, pack->tail - pack->data);
-
   trans->tbd = SEGOFS ((grub_addr_t) tbd);
-  trans->protocol = 0;
   tbd->len = pack->tail - pack->data;
   tbd->buf = SEGOFS ((grub_addr_t) buf);
 
   grub_pxe_call (GRUB_PXENV_UNDI_TRANSMIT, trans, pxe_rm_entry);
   if (trans->status)
-return grub_error (GRUB_ERR_IO, N_("couldn't send network packet"));
+return grub_error (GRUB_ERR_IO, N_("couldn't send network packet, PXE 
status: 0x%04x"), trans->status);
   return 0;
 }
 
-- 
tg: (0901e78..) e/pxe-send-fix (depends on: master)

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel