grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
From: "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com>
To: The development of GNU GRUB <grub-devel@gnu.org>
Subject: Re: [PATCH] fix PXE transmit failure if P_UNKNOWN is not supported
Date: Fri, 25 Jul 2014 23:38:34 +0200	[thread overview]
Message-ID: <53D2CE5A.2040102@gmail.com> (raw)
In-Reply-To: <1406303622-31501-1-git-send-email-arvidjaar@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 3847 bytes --]

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 <zaphod@berentweb.com>
> Tested-By: Beeblebrox <zaphod@berentweb.com>
> 
> ---
>  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 <grub/env.h>
>  #include <grub/i18n.h>
>  #include <grub/loader.h>
> +#include <grub/net/ethernet.h>
>  
>  #include <grub/machine/pxe.h>
>  #include <grub/machine/int.h>
> @@ -38,6 +39,11 @@ GRUB_MOD_LICENSE ("GPLv3+");
>  #define SEGOFS(x)	((SEGMENT(x) << 16) + OFFSET(x))
>  #define LINEAR(x)	(void *) ((((x) >> 16) << 4) + ((x) & 0xFFFF))
>  
> +#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;
>  }
>  
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]

  reply	other threads:[~2014-07-25 21:38 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-25 15:53 [PATCH] fix PXE transmit failure if P_UNKNOWN is not supported Andrey Borzenkov
2014-07-25 21:38 ` Vladimir 'φ-coder/phcoder' Serbinenko [this message]
2014-07-26  3:55   ` Andrey Borzenkov
2014-09-27  6:26     ` Andrei Borzenkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53D2CE5A.2040102@gmail.com \
    --to=phcoder@gmail.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).