All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: iPXE efi chainloading grub2 pxe efi file
       [not found]   ` <EEEB59C9688B214382E250B0063276B96CF050@ORSMSX102.amr.corp.intel.com>
@ 2015-10-14  6:13     ` Andrei Borzenkov
  2015-10-14 16:56       ` Rivard, Matthew T
  2015-10-15 17:46       ` [ipxe-devel] iPXE efi chainloading grub2 pxe efi file Michael Brown
  0 siblings, 2 replies; 12+ messages in thread
From: Andrei Borzenkov @ 2015-10-14  6:13 UTC (permalink / raw)
  To: Rivard, Matthew T, The development of GNU GRUB, ipxe-devel,
	edk2-devel-01

[Redirecting to grub-devel where similar problem is being discussed 
right now and trying iPXE/EDK2 as well]

18.09.2015 22:59, Rivard, Matthew T пишет:
> Thanks, its loading the menu now, however, I appear to be hitting the same problem I was going from grub to ipxe.  The adapters are there, but won't autoconfigure,

Exclusive SNP open used by iPXE quite likely tears down PXE information, 
so GRUB has nothing to autoconfigure card from.

> and if I try to manually set an IP address, I see the debugging data start spewing from ipxe (which appears to be still running underneath grub) before the system eventually halts.
>

Well, now we have two *applications* each holding exclusive open on 
adapter. I do not know details about iPXE but if there is any remote 
chance it does background polling we are back at square one.

Unfortunately I do not really see what we can do in this case (iPXE => 
GRUB) from GRUB side. Switching GRUB to MNP may fix GRUB => iPXE case 
though. OTOH I do not know what happens long term. GRUB calls other 
image (let's say iPXE) passes control to it. Now firmware continues to 
queue packets for GRUB MNP instance, which GRUB never consumes. Does not 
really look good either.

In principle the same is true for GRUB pure if it is left sitting in 
menu/CLI for a long time. And for every other active MNP instance.

> I'll try your rollback, but was it mean to come out in the email as a long hash string?
>

Did you have chance to test it?

>
> -----Original Message-----
> From: Andrei Borzenkov [mailto:arvidjaar@gmail.com]
> Sent: Thursday, September 17, 2015 8:52 PM
> To: Rivard, Matthew T; help-grub@gnu.org
> Subject: Re: iPXE efi chainloading grub2 pxe efi file
>
> 18.09.2015 03:05, Rivard, Matthew T пишет:
>> I've got a good working EFI Grub2 efi Bootloader that works fine when its directly handed off to by the DHCP for PXE, however, if I attempt to chainload it from iPXE snponly.efi, it goes straight to the grub command prompt.
>>
>> I've tried embedding the grub.cfg file via -c on the grub-mkimage command, but it spews out the grub file as a stream of "command not found prompts" and then still goes to the grub command line.
>>
>
> Embedded config is processed very early, before normal.mod is loaded, so only commands available at rescue prompts are present.
>
>> If I try embedding all of the modules directly into grub.efi during mkimage, along with the config file, it then throws a grub_divmod64_full not found error.
>>
>
> Embedding all modules in grub.efi is usually wrong (not all modules can be loaded concurrently) either.
>
> Try creating standalone image with grub-mkstandalone. This image contains all grub modules in memory disk (as cpio archive) and grub is configured with $prefix pointing to this disk. You can also add own files, in particular put grub.cfg in memory disk.
>
>> What is the ideal way to chain load my grub.efi file from iPXE so that it works the same as if it was the direct handoff from the DHCP/TFTP server?
>>
>> Unfortunately, in order to allow for selecting either our EFI WDS Server or our EFI Linux Server, I have to use iPXE first, as chainloading snponly.efi from grub2 ends up with iPXE snp not being able to enumerate anything from the PCI Bus.
>>
>
> Hmm ... this actually sounds like exclusive SNP open (used by both iPXE and GRUB) messes something up. For testing you could try to revert
> 49426e9fd2e562c73a4f1206f32eff9e424a1a73 (and f348aee7b33dd85e7da62b497a96a7319a0bf9dd which depends on it) to see if it makes any difference.
>
>> Using git pulls for both that were from yesterday.
>>
>> Matt R.
>>
>>
>>
>>
>> _______________________________________________
>> Help-grub mailing list
>> Help-grub@gnu.org
>> https://lists.gnu.org/mailman/listinfo/help-grub
>>
>



^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: iPXE efi chainloading grub2 pxe efi file
  2015-10-14  6:13     ` iPXE efi chainloading grub2 pxe efi file Andrei Borzenkov
@ 2015-10-14 16:56       ` Rivard, Matthew T
  2015-10-14 18:03         ` Andrei Borzenkov
  2015-10-15 17:46       ` [ipxe-devel] iPXE efi chainloading grub2 pxe efi file Michael Brown
  1 sibling, 1 reply; 12+ messages in thread
From: Rivard, Matthew T @ 2015-10-14 16:56 UTC (permalink / raw)
  To: Andrei Borzenkov, The development of GNU GRUB, ipxe-devel, edk2-devel-01

Sorry, I thought I had replied back to this.   

I found a work around by calling net_bootp on the adapters (I wrote a manual block of 64 potential devices given that that's not an unrealistic number of adapter ports to be found in a server in our lab), and setting a bootp range on our DHCP server for that purpose.   Since there's no command in grub to simply tell it to do a standard DHCP on the adapters, this has been the only feasible workaround to make them play together nicely.   

Ironically, executing the chainload from iPXE via embedded script vs their shell has solved the issue with it hanging if multiple adapters have IP addresses in grub when loading off to a Linux Kernel.   



-----Original Message-----
From: Andrei Borzenkov [mailto:arvidjaar@gmail.com] 
Sent: Tuesday, October 13, 2015 11:14 PM
To: Rivard, Matthew T; The development of GNU GRUB; ipxe-devel@lists.ipxe.org; edk2-devel-01
Subject: Re: iPXE efi chainloading grub2 pxe efi file

[Redirecting to grub-devel where similar problem is being discussed right now and trying iPXE/EDK2 as well]

18.09.2015 22:59, Rivard, Matthew T пишет:
> Thanks, its loading the menu now, however, I appear to be hitting the 
> same problem I was going from grub to ipxe.  The adapters are there, 
> but won't autoconfigure,

Exclusive SNP open used by iPXE quite likely tears down PXE information, so GRUB has nothing to autoconfigure card from.

> and if I try to manually set an IP address, I see the debugging data start spewing from ipxe (which appears to be still running underneath grub) before the system eventually halts.
>

Well, now we have two *applications* each holding exclusive open on adapter. I do not know details about iPXE but if there is any remote chance it does background polling we are back at square one.

Unfortunately I do not really see what we can do in this case (iPXE =>
GRUB) from GRUB side. Switching GRUB to MNP may fix GRUB => iPXE case though. OTOH I do not know what happens long term. GRUB calls other image (let's say iPXE) passes control to it. Now firmware continues to queue packets for GRUB MNP instance, which GRUB never consumes. Does not really look good either.

In principle the same is true for GRUB pure if it is left sitting in menu/CLI for a long time. And for every other active MNP instance.

> I'll try your rollback, but was it mean to come out in the email as a long hash string?
>

Did you have chance to test it?

>
> -----Original Message-----
> From: Andrei Borzenkov [mailto:arvidjaar@gmail.com]
> Sent: Thursday, September 17, 2015 8:52 PM
> To: Rivard, Matthew T; help-grub@gnu.org
> Subject: Re: iPXE efi chainloading grub2 pxe efi file
>
> 18.09.2015 03:05, Rivard, Matthew T пишет:
>> I've got a good working EFI Grub2 efi Bootloader that works fine when its directly handed off to by the DHCP for PXE, however, if I attempt to chainload it from iPXE snponly.efi, it goes straight to the grub command prompt.
>>
>> I've tried embedding the grub.cfg file via -c on the grub-mkimage command, but it spews out the grub file as a stream of "command not found prompts" and then still goes to the grub command line.
>>
>
> Embedded config is processed very early, before normal.mod is loaded, so only commands available at rescue prompts are present.
>
>> If I try embedding all of the modules directly into grub.efi during mkimage, along with the config file, it then throws a grub_divmod64_full not found error.
>>
>
> Embedding all modules in grub.efi is usually wrong (not all modules can be loaded concurrently) either.
>
> Try creating standalone image with grub-mkstandalone. This image contains all grub modules in memory disk (as cpio archive) and grub is configured with $prefix pointing to this disk. You can also add own files, in particular put grub.cfg in memory disk.
>
>> What is the ideal way to chain load my grub.efi file from iPXE so that it works the same as if it was the direct handoff from the DHCP/TFTP server?
>>
>> Unfortunately, in order to allow for selecting either our EFI WDS Server or our EFI Linux Server, I have to use iPXE first, as chainloading snponly.efi from grub2 ends up with iPXE snp not being able to enumerate anything from the PCI Bus.
>>
>
> Hmm ... this actually sounds like exclusive SNP open (used by both 
> iPXE and GRUB) messes something up. For testing you could try to 
> revert
> 49426e9fd2e562c73a4f1206f32eff9e424a1a73 (and f348aee7b33dd85e7da62b497a96a7319a0bf9dd which depends on it) to see if it makes any difference.
>
>> Using git pulls for both that were from yesterday.
>>
>> Matt R.
>>
>>
>>
>>
>> _______________________________________________
>> Help-grub mailing list
>> Help-grub@gnu.org
>> https://lists.gnu.org/mailman/listinfo/help-grub
>>
>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iPXE efi chainloading grub2 pxe efi file
  2015-10-14 16:56       ` Rivard, Matthew T
@ 2015-10-14 18:03         ` Andrei Borzenkov
  2015-10-14 18:09           ` Rivard, Matthew T
  0 siblings, 1 reply; 12+ messages in thread
From: Andrei Borzenkov @ 2015-10-14 18:03 UTC (permalink / raw)
  To: Rivard, Matthew T, The development of GNU GRUB

14.10.2015 19:56, Rivard, Matthew T пишет:
> Sorry, I thought I had replied back to this.
>
> I found a work around by calling net_bootp on the adapters (I wrote a manual block of 64 potential devices given that that's not an unrealistic number of adapter ports to be found in a server in our lab), and setting a bootp range on our DHCP server for that purpose.   Since there's no command in grub to simply tell it to do a standard DHCP on the adapters,

Huh? net_bootp does standard DHCP on adapters (do not be confused by 
name). What do you mean by this?

> this has been the only feasible workaround to make them play together nicely.
>
> Ironically, executing the chainload from iPXE via embedded script vs their shell has solved the issue with it hanging if multiple adapters have IP addresses in grub when loading off to a Linux Kernel.
>
>
>
> -----Original Message-----
> From: Andrei Borzenkov [mailto:arvidjaar@gmail.com]
> Sent: Tuesday, October 13, 2015 11:14 PM
> To: Rivard, Matthew T; The development of GNU GRUB; ipxe-devel@lists.ipxe.org; edk2-devel-01
> Subject: Re: iPXE efi chainloading grub2 pxe efi file
>
> [Redirecting to grub-devel where similar problem is being discussed right now and trying iPXE/EDK2 as well]
>
> 18.09.2015 22:59, Rivard, Matthew T пишет:
>> Thanks, its loading the menu now, however, I appear to be hitting the
>> same problem I was going from grub to ipxe.  The adapters are there,
>> but won't autoconfigure,
>
> Exclusive SNP open used by iPXE quite likely tears down PXE information, so GRUB has nothing to autoconfigure card from.
>
>> and if I try to manually set an IP address, I see the debugging data start spewing from ipxe (which appears to be still running underneath grub) before the system eventually halts.
>>
>
> Well, now we have two *applications* each holding exclusive open on adapter. I do not know details about iPXE but if there is any remote chance it does background polling we are back at square one.
>
> Unfortunately I do not really see what we can do in this case (iPXE =>
> GRUB) from GRUB side. Switching GRUB to MNP may fix GRUB => iPXE case though. OTOH I do not know what happens long term. GRUB calls other image (let's say iPXE) passes control to it. Now firmware continues to queue packets for GRUB MNP instance, which GRUB never consumes. Does not really look good either.
>
> In principle the same is true for GRUB pure if it is left sitting in menu/CLI for a long time. And for every other active MNP instance.
>
>> I'll try your rollback, but was it mean to come out in the email as a long hash string?
>>
>
> Did you have chance to test it?
>
>>
>> -----Original Message-----
>> From: Andrei Borzenkov [mailto:arvidjaar@gmail.com]
>> Sent: Thursday, September 17, 2015 8:52 PM
>> To: Rivard, Matthew T; help-grub@gnu.org
>> Subject: Re: iPXE efi chainloading grub2 pxe efi file
>>
>> 18.09.2015 03:05, Rivard, Matthew T пишет:
>>> I've got a good working EFI Grub2 efi Bootloader that works fine when its directly handed off to by the DHCP for PXE, however, if I attempt to chainload it from iPXE snponly.efi, it goes straight to the grub command prompt.
>>>
>>> I've tried embedding the grub.cfg file via -c on the grub-mkimage command, but it spews out the grub file as a stream of "command not found prompts" and then still goes to the grub command line.
>>>
>>
>> Embedded config is processed very early, before normal.mod is loaded, so only commands available at rescue prompts are present.
>>
>>> If I try embedding all of the modules directly into grub.efi during mkimage, along with the config file, it then throws a grub_divmod64_full not found error.
>>>
>>
>> Embedding all modules in grub.efi is usually wrong (not all modules can be loaded concurrently) either.
>>
>> Try creating standalone image with grub-mkstandalone. This image contains all grub modules in memory disk (as cpio archive) and grub is configured with $prefix pointing to this disk. You can also add own files, in particular put grub.cfg in memory disk.
>>
>>> What is the ideal way to chain load my grub.efi file from iPXE so that it works the same as if it was the direct handoff from the DHCP/TFTP server?
>>>
>>> Unfortunately, in order to allow for selecting either our EFI WDS Server or our EFI Linux Server, I have to use iPXE first, as chainloading snponly.efi from grub2 ends up with iPXE snp not being able to enumerate anything from the PCI Bus.
>>>
>>
>> Hmm ... this actually sounds like exclusive SNP open (used by both
>> iPXE and GRUB) messes something up. For testing you could try to
>> revert
>> 49426e9fd2e562c73a4f1206f32eff9e424a1a73 (and f348aee7b33dd85e7da62b497a96a7319a0bf9dd which depends on it) to see if it makes any difference.
>>
>>> Using git pulls for both that were from yesterday.
>>>
>>> Matt R.
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> Help-grub mailing list
>>> Help-grub@gnu.org
>>> https://lists.gnu.org/mailman/listinfo/help-grub
>>>
>>
>



^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: iPXE efi chainloading grub2 pxe efi file
  2015-10-14 18:03         ` Andrei Borzenkov
@ 2015-10-14 18:09           ` Rivard, Matthew T
  2015-10-14 18:23             ` Andrei Borzenkov
  2015-10-14 20:09             ` Andrei Borzenkov
  0 siblings, 2 replies; 12+ messages in thread
From: Rivard, Matthew T @ 2015-10-14 18:09 UTC (permalink / raw)
  To: Andrei Borzenkov, The development of GNU GRUB

Just going by these definitions of bootp and dhcp here:
https://technet.microsoft.com/en-us/library/cc781243%28v=ws.10%29.aspx

The net_bootp only works with a bootp enabled scope on the dhcp server after chaining from iPXE to grub2.   Without a "bootp" scope setup on the dhcp, calling net_bootp on the adapter fails to get an IP address.   

So, I guess I could more clearly word that the bootp protocol works when calling net_bootp, but standard dhcp isn't.


-----Original Message-----
From: Andrei Borzenkov [mailto:arvidjaar@gmail.com] 
Sent: Wednesday, October 14, 2015 11:04 AM
To: Rivard, Matthew T; The development of GNU GRUB
Subject: Re: iPXE efi chainloading grub2 pxe efi file

14.10.2015 19:56, Rivard, Matthew T пишет:
> Sorry, I thought I had replied back to this.
>
> I found a work around by calling net_bootp on the adapters (I wrote a manual block of 64 potential devices given that that's not an unrealistic number of adapter ports to be found in a server in our lab), and setting a bootp range on our DHCP server for that purpose.   Since there's no command in grub to simply tell it to do a standard DHCP on the adapters,

Huh? net_bootp does standard DHCP on adapters (do not be confused by name). What do you mean by this?

> this has been the only feasible workaround to make them play together nicely.
>
> Ironically, executing the chainload from iPXE via embedded script vs their shell has solved the issue with it hanging if multiple adapters have IP addresses in grub when loading off to a Linux Kernel.
>
>
>
> -----Original Message-----
> From: Andrei Borzenkov [mailto:arvidjaar@gmail.com]
> Sent: Tuesday, October 13, 2015 11:14 PM
> To: Rivard, Matthew T; The development of GNU GRUB; 
> ipxe-devel@lists.ipxe.org; edk2-devel-01
> Subject: Re: iPXE efi chainloading grub2 pxe efi file
>
> [Redirecting to grub-devel where similar problem is being discussed 
> right now and trying iPXE/EDK2 as well]
>
> 18.09.2015 22:59, Rivard, Matthew T пишет:
>> Thanks, its loading the menu now, however, I appear to be hitting the 
>> same problem I was going from grub to ipxe.  The adapters are there, 
>> but won't autoconfigure,
>
> Exclusive SNP open used by iPXE quite likely tears down PXE information, so GRUB has nothing to autoconfigure card from.
>
>> and if I try to manually set an IP address, I see the debugging data start spewing from ipxe (which appears to be still running underneath grub) before the system eventually halts.
>>
>
> Well, now we have two *applications* each holding exclusive open on adapter. I do not know details about iPXE but if there is any remote chance it does background polling we are back at square one.
>
> Unfortunately I do not really see what we can do in this case (iPXE =>
> GRUB) from GRUB side. Switching GRUB to MNP may fix GRUB => iPXE case though. OTOH I do not know what happens long term. GRUB calls other image (let's say iPXE) passes control to it. Now firmware continues to queue packets for GRUB MNP instance, which GRUB never consumes. Does not really look good either.
>
> In principle the same is true for GRUB pure if it is left sitting in menu/CLI for a long time. And for every other active MNP instance.
>
>> I'll try your rollback, but was it mean to come out in the email as a long hash string?
>>
>
> Did you have chance to test it?
>
>>
>> -----Original Message-----
>> From: Andrei Borzenkov [mailto:arvidjaar@gmail.com]
>> Sent: Thursday, September 17, 2015 8:52 PM
>> To: Rivard, Matthew T; help-grub@gnu.org
>> Subject: Re: iPXE efi chainloading grub2 pxe efi file
>>
>> 18.09.2015 03:05, Rivard, Matthew T пишет:
>>> I've got a good working EFI Grub2 efi Bootloader that works fine when its directly handed off to by the DHCP for PXE, however, if I attempt to chainload it from iPXE snponly.efi, it goes straight to the grub command prompt.
>>>
>>> I've tried embedding the grub.cfg file via -c on the grub-mkimage command, but it spews out the grub file as a stream of "command not found prompts" and then still goes to the grub command line.
>>>
>>
>> Embedded config is processed very early, before normal.mod is loaded, so only commands available at rescue prompts are present.
>>
>>> If I try embedding all of the modules directly into grub.efi during mkimage, along with the config file, it then throws a grub_divmod64_full not found error.
>>>
>>
>> Embedding all modules in grub.efi is usually wrong (not all modules can be loaded concurrently) either.
>>
>> Try creating standalone image with grub-mkstandalone. This image contains all grub modules in memory disk (as cpio archive) and grub is configured with $prefix pointing to this disk. You can also add own files, in particular put grub.cfg in memory disk.
>>
>>> What is the ideal way to chain load my grub.efi file from iPXE so that it works the same as if it was the direct handoff from the DHCP/TFTP server?
>>>
>>> Unfortunately, in order to allow for selecting either our EFI WDS Server or our EFI Linux Server, I have to use iPXE first, as chainloading snponly.efi from grub2 ends up with iPXE snp not being able to enumerate anything from the PCI Bus.
>>>
>>
>> Hmm ... this actually sounds like exclusive SNP open (used by both 
>> iPXE and GRUB) messes something up. For testing you could try to 
>> revert
>> 49426e9fd2e562c73a4f1206f32eff9e424a1a73 (and f348aee7b33dd85e7da62b497a96a7319a0bf9dd which depends on it) to see if it makes any difference.
>>
>>> Using git pulls for both that were from yesterday.
>>>
>>> Matt R.
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> Help-grub mailing list
>>> Help-grub@gnu.org
>>> https://lists.gnu.org/mailman/listinfo/help-grub
>>>
>>
>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iPXE efi chainloading grub2 pxe efi file
  2015-10-14 18:09           ` Rivard, Matthew T
@ 2015-10-14 18:23             ` Andrei Borzenkov
  2015-10-14 21:12               ` Rivard, Matthew T
  2015-10-14 20:09             ` Andrei Borzenkov
  1 sibling, 1 reply; 12+ messages in thread
From: Andrei Borzenkov @ 2015-10-14 18:23 UTC (permalink / raw)
  To: Rivard, Matthew T, The development of GNU GRUB

14.10.2015 21:09, Rivard, Matthew T пишет:
> Just going by these definitions of bootp and dhcp here:
> https://technet.microsoft.com/en-us/library/cc781243%28v=ws.10%29.aspx
>
> The net_bootp only works with a bootp enabled scope on the dhcp server after chaining from iPXE to grub2.   Without a "bootp" scope setup on the dhcp, calling net_bootp on the adapter fails to get an IP address.
>

What is "bootp enabled scope"? Do you refer to Windows DHCP server? 
Could you give link to manual that describes this setting?

> So, I guess I could more clearly word that the bootp protocol works when calling net_bootp, but standard dhcp isn't.
>

Could you make available network traces from both working and 
non-workign attempts?

>
> -----Original Message-----
> From: Andrei Borzenkov [mailto:arvidjaar@gmail.com]
> Sent: Wednesday, October 14, 2015 11:04 AM
> To: Rivard, Matthew T; The development of GNU GRUB
> Subject: Re: iPXE efi chainloading grub2 pxe efi file
>
> 14.10.2015 19:56, Rivard, Matthew T пишет:
>> Sorry, I thought I had replied back to this.
>>
>> I found a work around by calling net_bootp on the adapters (I wrote a manual block of 64 potential devices given that that's not an unrealistic number of adapter ports to be found in a server in our lab), and setting a bootp range on our DHCP server for that purpose.   Since there's no command in grub to simply tell it to do a standard DHCP on the adapters,
>
> Huh? net_bootp does standard DHCP on adapters (do not be confused by name). What do you mean by this?
>
>> this has been the only feasible workaround to make them play together nicely.
>>
>> Ironically, executing the chainload from iPXE via embedded script vs their shell has solved the issue with it hanging if multiple adapters have IP addresses in grub when loading off to a Linux Kernel.
>>
>>
>>
>> -----Original Message-----
>> From: Andrei Borzenkov [mailto:arvidjaar@gmail.com]
>> Sent: Tuesday, October 13, 2015 11:14 PM
>> To: Rivard, Matthew T; The development of GNU GRUB;
>> ipxe-devel@lists.ipxe.org; edk2-devel-01
>> Subject: Re: iPXE efi chainloading grub2 pxe efi file
>>
>> [Redirecting to grub-devel where similar problem is being discussed
>> right now and trying iPXE/EDK2 as well]
>>
>> 18.09.2015 22:59, Rivard, Matthew T пишет:
>>> Thanks, its loading the menu now, however, I appear to be hitting the
>>> same problem I was going from grub to ipxe.  The adapters are there,
>>> but won't autoconfigure,
>>
>> Exclusive SNP open used by iPXE quite likely tears down PXE information, so GRUB has nothing to autoconfigure card from.
>>
>>> and if I try to manually set an IP address, I see the debugging data start spewing from ipxe (which appears to be still running underneath grub) before the system eventually halts.
>>>
>>
>> Well, now we have two *applications* each holding exclusive open on adapter. I do not know details about iPXE but if there is any remote chance it does background polling we are back at square one.
>>
>> Unfortunately I do not really see what we can do in this case (iPXE =>
>> GRUB) from GRUB side. Switching GRUB to MNP may fix GRUB => iPXE case though. OTOH I do not know what happens long term. GRUB calls other image (let's say iPXE) passes control to it. Now firmware continues to queue packets for GRUB MNP instance, which GRUB never consumes. Does not really look good either.
>>
>> In principle the same is true for GRUB pure if it is left sitting in menu/CLI for a long time. And for every other active MNP instance.
>>
>>> I'll try your rollback, but was it mean to come out in the email as a long hash string?
>>>
>>
>> Did you have chance to test it?
>>
>>>
>>> -----Original Message-----
>>> From: Andrei Borzenkov [mailto:arvidjaar@gmail.com]
>>> Sent: Thursday, September 17, 2015 8:52 PM
>>> To: Rivard, Matthew T; help-grub@gnu.org
>>> Subject: Re: iPXE efi chainloading grub2 pxe efi file
>>>
>>> 18.09.2015 03:05, Rivard, Matthew T пишет:
>>>> I've got a good working EFI Grub2 efi Bootloader that works fine when its directly handed off to by the DHCP for PXE, however, if I attempt to chainload it from iPXE snponly.efi, it goes straight to the grub command prompt.
>>>>
>>>> I've tried embedding the grub.cfg file via -c on the grub-mkimage command, but it spews out the grub file as a stream of "command not found prompts" and then still goes to the grub command line.
>>>>
>>>
>>> Embedded config is processed very early, before normal.mod is loaded, so only commands available at rescue prompts are present.
>>>
>>>> If I try embedding all of the modules directly into grub.efi during mkimage, along with the config file, it then throws a grub_divmod64_full not found error.
>>>>
>>>
>>> Embedding all modules in grub.efi is usually wrong (not all modules can be loaded concurrently) either.
>>>
>>> Try creating standalone image with grub-mkstandalone. This image contains all grub modules in memory disk (as cpio archive) and grub is configured with $prefix pointing to this disk. You can also add own files, in particular put grub.cfg in memory disk.
>>>
>>>> What is the ideal way to chain load my grub.efi file from iPXE so that it works the same as if it was the direct handoff from the DHCP/TFTP server?
>>>>
>>>> Unfortunately, in order to allow for selecting either our EFI WDS Server or our EFI Linux Server, I have to use iPXE first, as chainloading snponly.efi from grub2 ends up with iPXE snp not being able to enumerate anything from the PCI Bus.
>>>>
>>>
>>> Hmm ... this actually sounds like exclusive SNP open (used by both
>>> iPXE and GRUB) messes something up. For testing you could try to
>>> revert
>>> 49426e9fd2e562c73a4f1206f32eff9e424a1a73 (and f348aee7b33dd85e7da62b497a96a7319a0bf9dd which depends on it) to see if it makes any difference.
>>>
>>>> Using git pulls for both that were from yesterday.
>>>>
>>>> Matt R.
>>>>
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> Help-grub mailing list
>>>> Help-grub@gnu.org
>>>> https://lists.gnu.org/mailman/listinfo/help-grub
>>>>
>>>
>>
>



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: iPXE efi chainloading grub2 pxe efi file
  2015-10-14 18:09           ` Rivard, Matthew T
  2015-10-14 18:23             ` Andrei Borzenkov
@ 2015-10-14 20:09             ` Andrei Borzenkov
  2016-01-17 15:41               ` [PATCH][WiP] native DHCPv4 support in net_bootp Andrei Borzenkov
  1 sibling, 1 reply; 12+ messages in thread
From: Andrei Borzenkov @ 2015-10-14 20:09 UTC (permalink / raw)
  To: Rivard, Matthew T, The development of GNU GRUB

14.10.2015 21:09, Rivard, Matthew T пишет:
> Just going by these definitions of bootp and dhcp here:
> https://technet.microsoft.com/en-us/library/cc781243%28v=ws.10%29.aspx
>
> The net_bootp only works with a bootp enabled scope on the dhcp server after chaining from iPXE to grub2.   Without a "bootp" scope setup on the dhcp, calling net_bootp on the adapter fails to get an IP address.
>
> So, I guess I could more clearly word that the bootp protocol works when calling net_bootp, but standard dhcp isn't.
>

Hmm ... you are right; we are actually doing BOOTP here, not DHCP.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: iPXE efi chainloading grub2 pxe efi file
  2015-10-14 18:23             ` Andrei Borzenkov
@ 2015-10-14 21:12               ` Rivard, Matthew T
  0 siblings, 0 replies; 12+ messages in thread
From: Rivard, Matthew T @ 2015-10-14 21:12 UTC (permalink / raw)
  To: Andrei Borzenkov, The development of GNU GRUB

ISC DHCPD, specifically, v4.1.1 running on RHEL6.6x64   

The code block needed is adding to the top of the config file:
"allow bootp;"

Then in the subnet (I call them scopes since I have a wide variety of different dhcps setup in our lab and there's more windows units than linux),
A bootp specific range needed to be added:

range dynamic-bootp 10.0.100.1 10.0.100.254;

Without these two lines, grub won't get a DHCP address after being chainloaded by ipxe when you perform net_bootp efinetX (X represents the adapter number, e.g efinet0, efinet1, etc....).  


-----Original Message-----
From: Andrei Borzenkov [mailto:arvidjaar@gmail.com] 
Sent: Wednesday, October 14, 2015 11:24 AM
To: Rivard, Matthew T; The development of GNU GRUB
Subject: Re: iPXE efi chainloading grub2 pxe efi file

14.10.2015 21:09, Rivard, Matthew T пишет:
> Just going by these definitions of bootp and dhcp here:
> https://technet.microsoft.com/en-us/library/cc781243%28v=ws.10%29.aspx
>
> The net_bootp only works with a bootp enabled scope on the dhcp server after chaining from iPXE to grub2.   Without a "bootp" scope setup on the dhcp, calling net_bootp on the adapter fails to get an IP address.
>

What is "bootp enabled scope"? Do you refer to Windows DHCP server? 
Could you give link to manual that describes this setting?

> So, I guess I could more clearly word that the bootp protocol works when calling net_bootp, but standard dhcp isn't.
>

Could you make available network traces from both working and non-workign attempts?

>
> -----Original Message-----
> From: Andrei Borzenkov [mailto:arvidjaar@gmail.com]
> Sent: Wednesday, October 14, 2015 11:04 AM
> To: Rivard, Matthew T; The development of GNU GRUB
> Subject: Re: iPXE efi chainloading grub2 pxe efi file
>
> 14.10.2015 19:56, Rivard, Matthew T пишет:
>> Sorry, I thought I had replied back to this.
>>
>> I found a work around by calling net_bootp on the adapters (I wrote a manual block of 64 potential devices given that that's not an unrealistic number of adapter ports to be found in a server in our lab), and setting a bootp range on our DHCP server for that purpose.   Since there's no command in grub to simply tell it to do a standard DHCP on the adapters,
>
> Huh? net_bootp does standard DHCP on adapters (do not be confused by name). What do you mean by this?
>
>> this has been the only feasible workaround to make them play together nicely.
>>
>> Ironically, executing the chainload from iPXE via embedded script vs their shell has solved the issue with it hanging if multiple adapters have IP addresses in grub when loading off to a Linux Kernel.
>>
>>
>>
>> -----Original Message-----
>> From: Andrei Borzenkov [mailto:arvidjaar@gmail.com]
>> Sent: Tuesday, October 13, 2015 11:14 PM
>> To: Rivard, Matthew T; The development of GNU GRUB; 
>> ipxe-devel@lists.ipxe.org; edk2-devel-01
>> Subject: Re: iPXE efi chainloading grub2 pxe efi file
>>
>> [Redirecting to grub-devel where similar problem is being discussed 
>> right now and trying iPXE/EDK2 as well]
>>
>> 18.09.2015 22:59, Rivard, Matthew T пишет:
>>> Thanks, its loading the menu now, however, I appear to be hitting 
>>> the same problem I was going from grub to ipxe.  The adapters are 
>>> there, but won't autoconfigure,
>>
>> Exclusive SNP open used by iPXE quite likely tears down PXE information, so GRUB has nothing to autoconfigure card from.
>>
>>> and if I try to manually set an IP address, I see the debugging data start spewing from ipxe (which appears to be still running underneath grub) before the system eventually halts.
>>>
>>
>> Well, now we have two *applications* each holding exclusive open on adapter. I do not know details about iPXE but if there is any remote chance it does background polling we are back at square one.
>>
>> Unfortunately I do not really see what we can do in this case (iPXE 
>> =>
>> GRUB) from GRUB side. Switching GRUB to MNP may fix GRUB => iPXE case though. OTOH I do not know what happens long term. GRUB calls other image (let's say iPXE) passes control to it. Now firmware continues to queue packets for GRUB MNP instance, which GRUB never consumes. Does not really look good either.
>>
>> In principle the same is true for GRUB pure if it is left sitting in menu/CLI for a long time. And for every other active MNP instance.
>>
>>> I'll try your rollback, but was it mean to come out in the email as a long hash string?
>>>
>>
>> Did you have chance to test it?
>>
>>>
>>> -----Original Message-----
>>> From: Andrei Borzenkov [mailto:arvidjaar@gmail.com]
>>> Sent: Thursday, September 17, 2015 8:52 PM
>>> To: Rivard, Matthew T; help-grub@gnu.org
>>> Subject: Re: iPXE efi chainloading grub2 pxe efi file
>>>
>>> 18.09.2015 03:05, Rivard, Matthew T пишет:
>>>> I've got a good working EFI Grub2 efi Bootloader that works fine when its directly handed off to by the DHCP for PXE, however, if I attempt to chainload it from iPXE snponly.efi, it goes straight to the grub command prompt.
>>>>
>>>> I've tried embedding the grub.cfg file via -c on the grub-mkimage command, but it spews out the grub file as a stream of "command not found prompts" and then still goes to the grub command line.
>>>>
>>>
>>> Embedded config is processed very early, before normal.mod is loaded, so only commands available at rescue prompts are present.
>>>
>>>> If I try embedding all of the modules directly into grub.efi during mkimage, along with the config file, it then throws a grub_divmod64_full not found error.
>>>>
>>>
>>> Embedding all modules in grub.efi is usually wrong (not all modules can be loaded concurrently) either.
>>>
>>> Try creating standalone image with grub-mkstandalone. This image contains all grub modules in memory disk (as cpio archive) and grub is configured with $prefix pointing to this disk. You can also add own files, in particular put grub.cfg in memory disk.
>>>
>>>> What is the ideal way to chain load my grub.efi file from iPXE so that it works the same as if it was the direct handoff from the DHCP/TFTP server?
>>>>
>>>> Unfortunately, in order to allow for selecting either our EFI WDS Server or our EFI Linux Server, I have to use iPXE first, as chainloading snponly.efi from grub2 ends up with iPXE snp not being able to enumerate anything from the PCI Bus.
>>>>
>>>
>>> Hmm ... this actually sounds like exclusive SNP open (used by both 
>>> iPXE and GRUB) messes something up. For testing you could try to 
>>> revert
>>> 49426e9fd2e562c73a4f1206f32eff9e424a1a73 (and f348aee7b33dd85e7da62b497a96a7319a0bf9dd which depends on it) to see if it makes any difference.
>>>
>>>> Using git pulls for both that were from yesterday.
>>>>
>>>> Matt R.
>>>>
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> Help-grub mailing list
>>>> Help-grub@gnu.org
>>>> https://lists.gnu.org/mailman/listinfo/help-grub
>>>>
>>>
>>
>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [ipxe-devel] iPXE efi chainloading grub2 pxe efi file
  2015-10-14  6:13     ` iPXE efi chainloading grub2 pxe efi file Andrei Borzenkov
  2015-10-14 16:56       ` Rivard, Matthew T
@ 2015-10-15 17:46       ` Michael Brown
  1 sibling, 0 replies; 12+ messages in thread
From: Michael Brown @ 2015-10-15 17:46 UTC (permalink / raw)
  To: Andrei Borzenkov, Rivard, Matthew T, The development of GNU GRUB,
	ipxe-devel, edk2-devel-01

On 14/10/15 07:13, Andrei Borzenkov wrote:
> Well, now we have two *applications* each holding exclusive open on
> adapter. I do not know details about iPXE but if there is any remote
> chance it does background polling we are back at square one.

iPXE will obtain exclusive access to the underlying SNP, NII, or PCI I/O 
protocol, and will (quite forcibly) kick off anything else connected to 
this handle.  It will then create an entirely new EFI handle on which is 
installed iPXE's own SNP and NII protocol instances, along with our own 
PXEBC and LoadFile protocols.  MNP is then allowed to attach to this new 
handle.

We don't set up a timer for background polling ourselves, but MNP will 
set up a timer and periodically poll via our provided SNP protocol 
instance.  We forcibly prevent these MNP polls whenever we're in the 
middle of a blocking operation (such as when shim.efi calls our PXEBC's 
Mtftp() method).

Hope that helps to explain how iPXE works in some more detail.  Please 
note that all of the above applies only to very recent builds of iPXE 
(September 2015 onwards).

I have personally observed grub.efi being able to obtain the cached IP 
address (from our reconstructed DHCP packet) and being able to 
communicate via the SNP instance provided by iPXE.  It _is_ expected to 
work, and I'm definitely interested in fixing any interoperability 
problems with GRUB.

Could someone give me a short and simple set of instructions for 
reproducing the problem being discussed here?

Thanks,

Michael


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH][WiP] native DHCPv4 support in net_bootp
  2015-10-14 20:09             ` Andrei Borzenkov
@ 2016-01-17 15:41               ` Andrei Borzenkov
  2016-01-21 18:37                 ` Mark Rutland
  2016-03-19  1:03                 ` Rivard, Matthew T
  0 siblings, 2 replies; 12+ messages in thread
From: Andrei Borzenkov @ 2016-01-17 15:41 UTC (permalink / raw)
  To: Rivard, Matthew T, The development of GNU GRUB

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

14.10.2015 23:09, Andrei Borzenkov пишет:
> 14.10.2015 21:09, Rivard, Matthew T пишет:
>> Just going by these definitions of bootp and dhcp here:
>> https://technet.microsoft.com/en-us/library/cc781243%28v=ws.10%29.aspx
>>
>> The net_bootp only works with a bootp enabled scope on the dhcp server
>> after chaining from iPXE to grub2.   Without a "bootp" scope setup on
>> the dhcp, calling net_bootp on the adapter fails to get an IP address.
>>
>> So, I guess I could more clearly word that the bootp protocol works
>> when calling net_bootp, but standard dhcp isn't.
>>
> 
> Hmm ... you are right; we are actually doing BOOTP here, not DHCP.
> 

This patch adds support for native DHCPv4 and removes requirement for
BOOTP compatibility support in DHCP server.

This is work in progress, but this works for me in test environment.

Patch changes net_bootp to implement full DHCP transaction. it still
/should/ work with BOOTP pure server (untested, I do not have one). It
also re-implements option processing to support overloaded fields and
consolidates it in one place.

What is currently not implemented

- per interface, per transaction stage retransmit timer. Will be done.

- DHCP server selection. We take first DHCPOFFER or BOOTPREPLY. No plans
to implement.

- DHCP option concatenation (RFC3396). I do not expect to hit it in real
life; could be implemented relatively easy if needed.

- client identifier (RFC6842). I do not expect to hit it in real life;
could be added easily if needed.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: grub-dhcp.diff --]
[-- Type: text/x-patch; name="grub-dhcp.diff", Size: 27054 bytes --]

diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
index 4fdeac3..4d5df64 100644
--- a/grub-core/net/bootp.c
+++ b/grub-core/net/bootp.c
@@ -25,20 +25,89 @@
 #include <grub/net/udp.h>
 #include <grub/datetime.h>
 
-static void
-parse_dhcp_vendor (const char *name, const void *vend, int limit, int *mask)
+struct grub_dhcp_discover_options
+  {
+  grub_uint8_t magic[4];
+  struct
+    {
+      grub_uint8_t code;
+      grub_uint8_t len;
+      grub_uint8_t data;
+    } GRUB_PACKED  message_type;
+    grub_uint8_t end;
+  } GRUB_PACKED;
+
+struct grub_dhcp_request_options
+  {
+    grub_uint8_t magic[4];
+    struct
+      {
+	grub_uint8_t code;
+	grub_uint8_t len;
+	grub_uint8_t data;
+      } GRUB_PACKED  message_type;
+    struct
+      {
+	grub_uint8_t type;
+	grub_uint8_t len;
+	grub_uint32_t data;
+      } GRUB_PACKED 	server_identifier;
+    struct
+      {
+	grub_uint8_t type;
+	grub_uint8_t len;
+	grub_uint32_t data;
+      } GRUB_PACKED 	requested_ip;
+    struct
+      {
+	grub_uint8_t type;
+	grub_uint8_t len;
+	grub_uint8_t data[7];
+      } GRUB_PACKED 	parameter_request;
+    grub_uint8_t end;
+  } GRUB_PACKED;
+
+enum
+  {
+    GRUB_DHCP_MESSAGE_UNKNOWN,
+    GRUB_DHCP_MESSAGE_DISCOVER,
+    GRUB_DHCP_MESSAGE_OFFER,
+    GRUB_DHCP_MESSAGE_REQUEST,
+    GRUB_DHCP_MESSAGE_DECLINE,
+    GRUB_DHCP_MESSAGE_ACK,
+    GRUB_DHCP_MESSAGE_NAK,
+    GRUB_DHCP_MESSAGE_RELEASE,
+    GRUB_DHCP_MESSAGE_INFORM,
+  };
+
+#define GRUB_BOOTP_MAX_OPTIONS_SIZE 64
+#define OFFSET_OF(x, y) ((grub_size_t)((grub_uint8_t *)((y)->x) - (grub_uint8_t *)(y)))
+
+static const void *
+find_dhcp_option (const struct grub_net_bootp_packet *bp, unsigned size,
+		 grub_uint8_t opt_code, grub_uint8_t *opt_len)
 {
   const grub_uint8_t *ptr, *ptr0;
+  grub_uint8_t overload = 0;
+  int end = 0;
+
+  /* Magic + message type option */
+  if (size < sizeof (*bp) + sizeof (grub_uint32_t))
+    goto out;
 
-  ptr = ptr0 = vend;
+  ptr = ptr0 = (grub_uint8_t *) (bp + 1);
 
   if (ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0
       || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1
       || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2
       || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3)
-    return;
+    goto out;
+
   ptr = ptr + sizeof (grub_uint32_t);
-  while (ptr - ptr0 < limit)
+  size -= (sizeof (*bp) + sizeof (grub_uint32_t));
+
+again:
+  while (ptr - ptr0 < size)
     {
       grub_uint8_t tagtype;
       grub_uint8_t taglength;
@@ -51,84 +120,75 @@ parse_dhcp_vendor (const char *name, const void *vend, int limit, int *mask)
 
       /* End tag.  */
       if (tagtype == GRUB_NET_BOOTP_END)
-	return;
+	{
+	  end = 1;
+	  break;
+	}
+
+      if (ptr - ptr0 >= size)
+	goto out;
 
       taglength = *ptr++;
 
-      switch (tagtype)
-	{
-	case GRUB_NET_BOOTP_NETMASK:
-	  if (taglength == 4)
-	    {
-	      int i;
-	      for (i = 0; i < 32; i++)
-		if (!(ptr[i / 8] & (1 << (7 - (i % 8)))))
-		  break;
-	      *mask = i;
-	    }
-	  break;
+      if (ptr + taglength - ptr0 >= size)
+	goto out;
 
-	case GRUB_NET_BOOTP_ROUTER:
-	  if (taglength == 4)
-	    {
-	      grub_net_network_level_netaddress_t target;
-	      grub_net_network_level_address_t gw;
-	      char *rname;
-	      
-	      target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
-	      target.ipv4.base = 0;
-	      target.ipv4.masksize = 0;
-	      gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
-	      grub_memcpy (&gw.ipv4, ptr, sizeof (gw.ipv4));
-	      rname = grub_xasprintf ("%s:default", name);
-	      if (rname)
-		grub_net_add_route_gw (rname, target, gw);
-	      grub_free (rname);
-	    }
-	  break;
-	case GRUB_NET_BOOTP_DNS:
-	  {
-	    int i;
-	    for (i = 0; i < taglength / 4; i++)
-	      {
-		struct grub_net_network_level_address s;
-		s.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
-		s.ipv4 = grub_get_unaligned32 (ptr);
-		s.option = DNS_OPTION_PREFER_IPV4;
-		grub_net_add_dns_server (&s);
-		ptr += 4;
-	      }
-	  }
-	  continue;
-	case GRUB_NET_BOOTP_HOSTNAME:
-          grub_env_set_net_property (name, "hostname", (const char *) ptr,
-                                     taglength);
-          break;
-
-	case GRUB_NET_BOOTP_DOMAIN:
-          grub_env_set_net_property (name, "domain", (const char *) ptr,
-                                     taglength);
-          break;
-
-	case GRUB_NET_BOOTP_ROOT_PATH:
-          grub_env_set_net_property (name, "rootpath", (const char *) ptr,
-                                     taglength);
-          break;
-
-	case GRUB_NET_BOOTP_EXTENSIONS_PATH:
-          grub_env_set_net_property (name, "extensionspath", (const char *) ptr,
-                                     taglength);
-          break;
-
-	  /* If you need any other options please contact GRUB
-	     development team.  */
+      if (tagtype == opt_code)
+	{
+	  if (opt_len)
+	    *opt_len = taglength;
+	  return ptr;
 	}
 
+      if (tagtype == GRUB_NET_DHCP_OVERLOAD)
+	overload = *ptr;
+
       ptr += taglength;
     }
-}
 
-#define OFFSET_OF(x, y) ((grub_size_t)((grub_uint8_t *)((y)->x) - (grub_uint8_t *)(y)))
+    /* RFC2131, 4.1, 23ff:
+       If the options in a DHCP message extend into the 'sname' and 'file'
+       fields, the 'option overload' option MUST appear in the 'options'
+       field, with value 1, 2 or 3, as specified in RFC 1533.  If the
+       'option overload' option is present in the 'options' field, the
+       options in the 'options' field MUST be terminated by an 'end' option,
+       and MAY contain one or more 'pad' options to fill the options field.
+       The options in the 'sname' and 'file' fields (if in use as indicated
+       by the 'options overload' option) MUST begin with the first octet of
+       the field, MUST be terminated by an 'end' option, and MUST be
+       followed by 'pad' options to fill the remainder of the field.  Any
+       individual option in the 'options', 'sname' and 'file' fields MUST be
+       entirely contained in that field.  The options in the 'options' field
+       MUST be interpreted first, so that any 'option overload' options may
+       be interpreted.  The 'file' field MUST be interpreted next (if the
+       'option overload' option indicates that the 'file' field contains
+       DHCP options), followed by the 'sname' field.
+
+       FIXME: We do not explicitly check for trailing 'pad' options here.
+     */
+    if (end)
+      {
+	end = 0;
+	if (overload & 1U)
+	  {
+	    overload &= ~1U;
+	    ptr = ptr0 = (grub_uint8_t *) &bp->boot_file[0];
+	    size = sizeof (bp->boot_file);
+	    goto again;
+	  }
+
+	if (overload & 2U)
+	  {
+	    overload &= ~2U;
+	    ptr = ptr0 = (grub_uint8_t *) &bp->server_name[0];
+	    size = sizeof (bp->server_name);
+	    goto again;
+	  }
+      }
+
+out:
+  return 0;
+}
 
 struct grub_net_network_level_interface *
 grub_net_configure_by_dhcp_ack (const char *name,
@@ -142,6 +202,10 @@ grub_net_configure_by_dhcp_ack (const char *name,
   grub_net_link_level_address_t hwaddr;
   struct grub_net_network_level_interface *inter;
   int mask = -1;
+  const grub_uint8_t *opt;
+  grub_uint8_t opt_len = 0;
+  const char *boot_file = 0, *server_name = 0;
+  grub_size_t boot_file_len, server_name_len;
 
   addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
   addr.ipv4 = bp->your_ip;
@@ -157,38 +221,31 @@ grub_net_configure_by_dhcp_ack (const char *name,
   hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
 
   inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags);
-#if 0
-  /* This is likely based on misunderstanding. gateway_ip refers to
-     address of BOOTP relay and should not be used after BOOTP transaction
-     is complete.
-     See RFC1542, 3.4 Interpretation of the 'giaddr' field
-   */
-  if (bp->gateway_ip)
+
+  opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_TFTP_SERVER_NAME, &opt_len);
+  if (opt && opt_len)
     {
-      grub_net_network_level_netaddress_t target;
-      grub_net_network_level_address_t gw;
-      char *rname;
-	  
-      target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
-      target.ipv4.base = bp->server_ip;
-      target.ipv4.masksize = 32;
-      gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
-      gw.ipv4 = bp->gateway_ip;
-      rname = grub_xasprintf ("%s:gw", name);
-      if (rname)
-	grub_net_add_route_gw (rname, target, gw);
-      grub_free (rname);
+      server_name = (const char *) opt;
+      server_name_len = opt_len;
+    }
+  else if (size > OFFSET_OF (server_name, bp) && bp->server_name[0])
+    {
+      server_name = bp->server_name;
+      server_name_len = sizeof (bp->server_name);
+    }
 
-      target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
-      target.ipv4.base = bp->gateway_ip;
-      target.ipv4.masksize = 32;
-      grub_net_add_route (name, target, inter);
+  opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_BOOTFILE_NAME, &opt_len);
+  if (opt && opt_len)
+    {
+      boot_file = (const char *) opt;
+      boot_file_len = opt_len;
+    }
+  else if (size > OFFSET_OF (boot_file, bp) && bp->boot_file[0])
+    {
+      boot_file = bp->boot_file;
+      boot_file_len = sizeof (bp->boot_file);
     }
-#endif
 
-  if (size > OFFSET_OF (boot_file, bp))
-    grub_env_set_net_property (name, "boot_file", bp->boot_file,
-                               sizeof (bp->boot_file));
   if (is_def)
     grub_net_default_server = 0;
   if (is_def && !grub_net_default_server && bp->server_ip)
@@ -216,40 +273,104 @@ grub_net_configure_by_dhcp_ack (const char *name,
 				((grub_uint8_t *) &bp->server_ip)[3]);
       grub_print_error ();
     }
-  if (size > OFFSET_OF (server_name, bp)
-      && bp->server_name[0])
+
+  if (server_name)
     {
-      grub_env_set_net_property (name, "dhcp_server_name", bp->server_name,
-                                 sizeof (bp->server_name));
+      /* FIXME this is actually TFTP server name; should not we change it? */
+      grub_env_set_net_property (name, "dhcp_server_name", server_name, server_name_len);
       if (is_def && !grub_net_default_server)
 	{
-	  grub_net_default_server = grub_strdup (bp->server_name);
+	  grub_net_default_server = grub_strdup (server_name);
 	  grub_print_error ();
 	}
       if (device && !*device)
 	{
-	  *device = grub_xasprintf ("tftp,%s", bp->server_name);
+	  *device = grub_xasprintf ("tftp,%s", server_name);
 	  grub_print_error ();
 	}
     }
 
-  if (size > OFFSET_OF (boot_file, bp) && path)
+  if (boot_file)
     {
-      *path = grub_strndup (bp->boot_file, sizeof (bp->boot_file));
-      grub_print_error ();
-      if (*path)
+      grub_env_set_net_property (name, "boot_file", boot_file, boot_file_len);
+      if (path)
 	{
-	  char *slash;
-	  slash = grub_strrchr (*path, '/');
-	  if (slash)
-	    *slash = 0;
-	  else
-	    **path = 0;
+	  *path = grub_strndup (boot_file, boot_file_len);
+	  grub_print_error ();
+	  if (*path)
+	    {
+	      char *slash;
+	      slash = grub_strrchr (*path, '/');
+	      if (slash)
+		*slash = 0;
+	      else
+		**path = 0;
+	    }
 	}
     }
-  if (size > OFFSET_OF (vendor, bp))
-    parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask);
+
+  opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_NETMASK, &opt_len);
+  if (opt && opt_len == 4)
+    {
+      int i;
+      for (i = 0; i < 32; i++)
+	if (!(opt[i / 8] & (1 << (7 - (i % 8)))))
+	  break;
+      mask = i;
+    }
   grub_net_add_ipv4_local (inter, mask);
+
+  /* We do not implement dead gateway detection and the first entry SHOULD
+     be preferred one */
+  opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_ROUTER, &opt_len);
+  if (opt && opt_len && !(opt_len & 3))
+    {
+      grub_net_network_level_netaddress_t target;
+      grub_net_network_level_address_t gw;
+      char *rname;
+
+      target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+      target.ipv4.base = 0;
+      target.ipv4.masksize = 0;
+      gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+      gw.ipv4 = grub_get_unaligned32 (opt);
+      rname = grub_xasprintf ("%s:default", name);
+      if (rname)
+	grub_net_add_route_gw (rname, target, gw);
+      grub_free (rname);
+    }
+
+  opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_DNS, &opt_len);
+  if (opt && opt_len && !(opt_len & 3))
+    {
+      int i;
+      for (i = 0; i < opt_len / 4; i++)
+	{
+	  struct grub_net_network_level_address s;
+
+	  s.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+	  s.ipv4 = grub_get_unaligned32 (opt);
+	  s.option = DNS_OPTION_PREFER_IPV4;
+	  grub_net_add_dns_server (&s);
+	  opt += 4;
+	}
+    }
+
+  opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_HOSTNAME, &opt_len);
+  if (opt && opt_len)
+    grub_env_set_net_property (name, "hostname", (const char *) opt, opt_len);
+
+  opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_DOMAIN, &opt_len);
+  if (opt && opt_len)
+    grub_env_set_net_property (name, "domain", (const char *) opt, opt_len);
+
+  opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_ROOT_PATH, &opt_len);
+  if (opt && opt_len)
+    grub_env_set_net_property (name, "rootpath", (const char *) opt, opt_len);
+
+  opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_EXTENSIONS_PATH, &opt_len);
+  if (opt && opt_len)
+    grub_env_set_net_property (name, "extensionspath", (const char *) opt, opt_len);
   
   inter->dhcp_ack = grub_malloc (size);
   if (inter->dhcp_ack)
@@ -263,36 +384,211 @@ grub_net_configure_by_dhcp_ack (const char *name,
   return inter;
 }
 
+static grub_err_t
+send_dhcp_packet (struct grub_net_network_level_interface *iface)
+{
+  grub_err_t err;
+  struct grub_net_bootp_packet *pack;
+  struct grub_datetime date;
+  grub_int32_t t = 0;
+  struct grub_net_buff *nb;
+  struct udphdr *udph;
+  grub_net_network_level_address_t target;
+  grub_net_link_level_address_t ll_target;
+
+  static struct grub_dhcp_discover_options discover_options =
+    {
+      {
+	GRUB_NET_BOOTP_RFC1048_MAGIC_0,
+	GRUB_NET_BOOTP_RFC1048_MAGIC_1,
+	GRUB_NET_BOOTP_RFC1048_MAGIC_2,
+	GRUB_NET_BOOTP_RFC1048_MAGIC_3,
+      },
+      {
+	GRUB_NET_DHCP_MESSAGE_TYPE,
+	sizeof (discover_options.message_type.data),
+	GRUB_DHCP_MESSAGE_DISCOVER,
+      },
+      GRUB_NET_BOOTP_END,
+    };
+
+  static struct grub_dhcp_request_options request_options =
+    {
+      {
+	GRUB_NET_BOOTP_RFC1048_MAGIC_0,
+	GRUB_NET_BOOTP_RFC1048_MAGIC_1,
+	GRUB_NET_BOOTP_RFC1048_MAGIC_2,
+	GRUB_NET_BOOTP_RFC1048_MAGIC_3,
+      },
+      {
+	GRUB_NET_DHCP_MESSAGE_TYPE,
+	sizeof (request_options.message_type.data),
+	GRUB_DHCP_MESSAGE_REQUEST,
+      },
+      {
+	GRUB_NET_DHCP_SERVER_IDENTIFIER,
+	sizeof (request_options.server_identifier.data),
+	0,
+      },
+      {
+	GRUB_NET_DHCP_REQUESTED_IP_ADDRESS,
+	sizeof (request_options.requested_ip.data),
+	0,
+      },
+      {
+	GRUB_NET_DHCP_PARAMETER_REQUEST_LIST,
+	sizeof (request_options.parameter_request.data),
+	{
+	  GRUB_NET_BOOTP_NETMASK,
+	  GRUB_NET_BOOTP_ROUTER,
+	  GRUB_NET_BOOTP_DNS,
+	  GRUB_NET_BOOTP_DOMAIN,
+	  GRUB_NET_BOOTP_HOSTNAME,
+	  GRUB_NET_BOOTP_ROOT_PATH,
+	  GRUB_NET_BOOTP_EXTENSIONS_PATH,
+	},
+      },
+      GRUB_NET_BOOTP_END,
+    };
+
+  COMPILE_TIME_ASSERT (sizeof (discover_options) <= GRUB_BOOTP_MAX_OPTIONS_SIZE);
+  COMPILE_TIME_ASSERT (sizeof (request_options) <= GRUB_BOOTP_MAX_OPTIONS_SIZE);
+
+  nb = grub_netbuff_alloc (sizeof (*pack) + GRUB_BOOTP_MAX_OPTIONS_SIZE + 128);
+  if (!nb)
+    return grub_errno;
+
+  err = grub_netbuff_reserve (nb, sizeof (*pack) + GRUB_BOOTP_MAX_OPTIONS_SIZE + 128);
+  if (err)
+    goto out;
+
+  err = grub_netbuff_push (nb, GRUB_BOOTP_MAX_OPTIONS_SIZE);
+  if (err)
+    goto out;
+
+  grub_memset (nb->data, 0, GRUB_BOOTP_MAX_OPTIONS_SIZE);
+  if (!iface->srv_id)
+    {
+      grub_memcpy (nb->data, &discover_options, sizeof (discover_options));
+    }
+  else
+    {
+      struct grub_dhcp_request_options *ro = (struct grub_dhcp_request_options *) nb->data;
+
+      grub_memcpy (nb->data, &request_options, sizeof (request_options));
+      grub_set_unaligned32 (&ro->server_identifier.data, iface->srv_id);
+      grub_set_unaligned32 (&ro->requested_ip.data, iface->my_ip);
+    }
+
+  err = grub_netbuff_push (nb, sizeof (*pack));
+  if (err)
+    goto out;
+
+  pack = (void *) nb->data;
+  grub_memset (pack, 0, sizeof (*pack));
+  pack->opcode = 1;
+  pack->hw_type = 1;
+  pack->hw_len = 6;
+  err = grub_get_datetime (&date);
+  if (err || !grub_datetime2unixtime (&date, &t))
+    {
+      grub_errno = GRUB_ERR_NONE;
+      t = 0;
+    }
+  pack->seconds = grub_cpu_to_be16 (t);
+  if (!iface->srv_id)
+    iface->xid = pack->ident = grub_cpu_to_be32 (t);
+  else
+    pack->ident = iface->xid;
+
+  grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, 6);
+
+  grub_netbuff_push (nb, sizeof (*udph));
+
+  udph = (struct udphdr *) nb->data;
+  udph->src = grub_cpu_to_be16_compile_time (68);
+  udph->dst = grub_cpu_to_be16_compile_time (67);
+  udph->chksum = 0;
+  udph->len = grub_cpu_to_be16 (nb->tail - nb->data);
+  target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+  target.ipv4 = 0xffffffff;
+  err = grub_net_link_layer_resolve (iface, &target, &ll_target);
+  if (err)
+    goto out;
+
+  udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP,
+						 &iface->address,
+						 &target);
+
+  err = grub_net_send_ip_packet (iface, &target, &ll_target, nb,
+				 GRUB_NET_IP_UDP);
+
+out:
+  grub_netbuff_free (nb);
+  return err;
+}
+
 void
 grub_net_process_dhcp (struct grub_net_buff *nb,
-		       struct grub_net_card *card)
+		       struct grub_net_network_level_interface *iface)
 {
   char *name;
   struct grub_net_network_level_interface *inf;
-
-  name = grub_xasprintf ("%s:dhcp", card->name);
-  if (!name)
+  struct grub_net_card *card = iface->card;
+  const struct grub_net_bootp_packet *bp = (const struct grub_net_bootp_packet *) nb->data;
+  grub_size_t size = nb->tail - nb->data;
+  const grub_uint8_t *opt;
+  grub_uint8_t optlen = 0, type;
+  grub_uint32_t srv_id = 0;
+
+  opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_MESSAGE_TYPE, &optlen);
+  if (opt && optlen == 1)
+    type = *opt;
+  else
+    type = GRUB_DHCP_MESSAGE_UNKNOWN;
+
+  opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_SERVER_IDENTIFIER, &optlen);
+  if (opt && optlen == sizeof (srv_id))
+    srv_id = grub_get_unaligned32 (opt);
+
+  /* If we received BOOTP reply or DHCPACK, proceed with configuration. Otherwise
+     store offered address and server id for later processing of DHCPACK */
+  if ((!iface->srv_id && type == GRUB_DHCP_MESSAGE_UNKNOWN)
+      || (iface->srv_id && type == GRUB_DHCP_MESSAGE_ACK
+	  && bp->ident == iface->xid
+	  && srv_id == iface->srv_id))
     {
-      grub_print_error ();
-      return;
+      name = grub_xasprintf ("%s:dhcp", card->name);
+      if (!name)
+	{
+	  grub_print_error ();
+	  return;
+	}
+      grub_net_configure_by_dhcp_ack (name, card, 0, bp, size, 0, 0, 0);
+      grub_free (name);
+      if (grub_errno)
+	grub_print_error ();
+      else
+	{
+	  FOR_NET_NETWORK_LEVEL_INTERFACES(inf)
+	    if (grub_memcmp (inf->name, card->name, grub_strlen (card->name)) == 0
+		&& grub_memcmp (inf->name + grub_strlen (card->name),
+				":dhcp_tmp", sizeof (":dhcp_tmp") - 1) == 0)
+	      {
+		grub_net_network_level_interface_unregister (inf);
+		break;
+	      }
+	}
     }
-  grub_net_configure_by_dhcp_ack (name, card,
-				  0, (const struct grub_net_bootp_packet *) nb->data,
-				  (nb->tail - nb->data), 0, 0, 0);
-  grub_free (name);
-  if (grub_errno)
-    grub_print_error ();
-  else
+  else if (!iface->srv_id && type == GRUB_DHCP_MESSAGE_OFFER)
     {
-      FOR_NET_NETWORK_LEVEL_INTERFACES(inf)
-	if (grub_memcmp (inf->name, card->name, grub_strlen (card->name)) == 0
-	    && grub_memcmp (inf->name + grub_strlen (card->name),
-			    ":dhcp_tmp", sizeof (":dhcp_tmp") - 1) == 0)
-	  {
-	    grub_net_network_level_interface_unregister (inf);
-	    break;
-	  }
+      iface->srv_id = srv_id;
+      iface->my_ip = bp->your_ip;
     }
+  else if (iface->srv_id && type == GRUB_DHCP_MESSAGE_NAK
+	   && bp->ident == iface->xid
+	   && srv_id == iface->srv_id)
+    iface->xid = iface->srv_id = iface->my_ip = 0;
 }
 
 static char
@@ -308,8 +604,8 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
 		  int argc, char **args)
 {
   struct grub_net_network_level_interface *inter;
-  int num;
-  grub_uint8_t *ptr;
+  unsigned num;
+  const grub_uint8_t *ptr;
   grub_uint8_t taglength;
 
   if (argc < 4)
@@ -327,44 +623,27 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
   if (!inter->dhcp_ack)
     return grub_error (GRUB_ERR_IO, N_("no DHCP info found"));
 
-  if (inter->dhcp_acklen <= OFFSET_OF (vendor, inter->dhcp_ack))
-    return grub_error (GRUB_ERR_IO, N_("no DHCP options found"));
-
-  num = grub_strtoul (args[2], 0, 0);
-  if (grub_errno)
-    return grub_errno;
-
   ptr = inter->dhcp_ack->vendor;
 
-  if (ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0
+  /* This duplicates check in find_dhcp_option to preserve previous error return */
+  if (inter->dhcp_acklen < OFFSET_OF (vendor, inter->dhcp_ack) + sizeof (grub_uint32_t)
+      || ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0
       || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1
       || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2
       || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3)
     return grub_error (GRUB_ERR_IO, N_("no DHCP options found"));
-  ptr = ptr + sizeof (grub_uint32_t);
-  while (1)
-    {
-      grub_uint8_t tagtype;
-
-      if (ptr >= ((grub_uint8_t *) inter->dhcp_ack) + inter->dhcp_acklen)
-	return grub_error (GRUB_ERR_IO, N_("no DHCP option %d found"), num);
 
-      tagtype = *ptr++;
+  num = grub_strtoul (args[2], 0, 0);
+  if (grub_errno)
+    return grub_errno;
 
-      /* Pad tag.  */
-      if (tagtype == 0)
-	continue;
+  /* Exclude PAD (0) and END (255) option codes */
+  if (num == 0 || num > 254)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid DHCP option code"));
 
-      /* End tag.  */
-      if (tagtype == 0xff)
-	return grub_error (GRUB_ERR_IO, N_("no DHCP option %d found"), num);
-
-      taglength = *ptr++;
-	
-      if (tagtype == num)
-	break;
-      ptr += taglength;
-    }
+  ptr = find_dhcp_option (inter->dhcp_ack, inter->dhcp_acklen, num, &taglength);
+  if (!ptr)
+    return grub_error (GRUB_ERR_IO, N_("no DHCP option %u found"), num);
 
   if (grub_strcmp (args[3], "string") == 0)
     {
@@ -481,71 +760,12 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)),
       int done = 0;
       for (j = 0; j < ncards; j++)
 	{
-	  struct grub_net_bootp_packet *pack;
-	  struct grub_datetime date;
-	  grub_int32_t t = 0;
-	  struct grub_net_buff *nb;
-	  struct udphdr *udph;
-	  grub_net_network_level_address_t target;
-	  grub_net_link_level_address_t ll_target;
-
 	  if (!ifaces[j].prev)
 	    continue;
-	  nb = grub_netbuff_alloc (sizeof (*pack) + 64 + 128);
-	  if (!nb)
-	    {
-	      grub_netbuff_free (nb);
-	      return grub_errno;
-	    }
-	  err = grub_netbuff_reserve (nb, sizeof (*pack) + 64 + 128);
-	  if (err)
-	    {
-	      grub_netbuff_free (nb);
-	      return err;
-	    }
-	  err = grub_netbuff_push (nb, sizeof (*pack) + 64);
-	  if (err)
-	    {
-	      grub_netbuff_free (nb);
-	      return err;
-	    }
-	  pack = (void *) nb->data;
-	  done = 1;
-	  grub_memset (pack, 0, sizeof (*pack) + 64);
-	  pack->opcode = 1;
-	  pack->hw_type = 1;
-	  pack->hw_len = 6;
-	  err = grub_get_datetime (&date);
-	  if (err || !grub_datetime2unixtime (&date, &t))
-	    {
-	      grub_errno = GRUB_ERR_NONE;
-	      t = 0;
-	    }
-	  pack->ident = grub_cpu_to_be32 (t);
-	  pack->seconds = grub_cpu_to_be16 (t);
-
-	  grub_memcpy (&pack->mac_addr, &ifaces[j].hwaddress.mac, 6); 
 
-	  grub_netbuff_push (nb, sizeof (*udph));
-
-	  udph = (struct udphdr *) nb->data;
-	  udph->src = grub_cpu_to_be16_compile_time (68);
-	  udph->dst = grub_cpu_to_be16_compile_time (67);
-	  udph->chksum = 0;
-	  udph->len = grub_cpu_to_be16 (nb->tail - nb->data);
-	  target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
-	  target.ipv4 = 0xffffffff;
-	  err = grub_net_link_layer_resolve (&ifaces[j], &target, &ll_target);
-	  if (err)
-	    return err;
-
-	  udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP,
-							 &ifaces[j].address,
-							 &target);
+	  done = 1;
 
-	  err = grub_net_send_ip_packet (&ifaces[j], &target, &ll_target, nb,
-					 GRUB_NET_IP_UDP);
-	  grub_netbuff_free (nb);
+	  err = send_dhcp_packet (&ifaces[j]);
 	  if (err)
 	    return err;
 	}
diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
index 8c56baa..162c70d 100644
--- a/grub-core/net/ip.c
+++ b/grub-core/net/ip.c
@@ -278,7 +278,7 @@ handle_dgram (struct grub_net_buff *nb,
 	      && grub_memcmp (inf->hwaddress.mac, &bootp->mac_addr,
 			      sizeof (inf->hwaddress.mac)) == 0)
 	    {
-	      grub_net_process_dhcp (nb, inf->card);
+	      grub_net_process_dhcp (nb, inf);
 	      grub_netbuff_free (nb);
 	      return GRUB_ERR_NONE;
 	    }
diff --git a/include/grub/net.h b/include/grub/net.h
index 538baa3..073a33b 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -279,6 +279,9 @@ struct grub_net_network_level_interface
   grub_net_interface_flags_t flags;
   struct grub_net_bootp_packet *dhcp_ack;
   grub_size_t dhcp_acklen;
+  grub_uint32_t xid;    /* DHCPv4 transation id */
+  grub_uint32_t srv_id; /* DHCPv4 server_identifier */
+  grub_uint32_t my_ip;  /* DHCPv4 offered IP address */
   void *data;
 };
 
@@ -433,6 +436,13 @@ enum
     GRUB_NET_BOOTP_DOMAIN = 0x0f,
     GRUB_NET_BOOTP_ROOT_PATH = 0x11,
     GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12,
+    GRUB_NET_DHCP_REQUESTED_IP_ADDRESS = 50,
+    GRUB_NET_DHCP_OVERLOAD = 52,
+    GRUB_NET_DHCP_MESSAGE_TYPE = 53,
+    GRUB_NET_DHCP_SERVER_IDENTIFIER = 54,
+    GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55,
+    GRUB_NET_DHCP_TFTP_SERVER_NAME = 66,
+    GRUB_NET_DHCP_BOOTFILE_NAME = 67,
     GRUB_NET_BOOTP_END = 0xff
   };
 
@@ -450,7 +460,7 @@ grub_net_add_ipv4_local (struct grub_net_network_level_interface *inf,
 
 void
 grub_net_process_dhcp (struct grub_net_buff *nb,
-		       struct grub_net_card *card);
+		       struct grub_net_network_level_interface *iface);
 
 int
 grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a,

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH][WiP] native DHCPv4 support in net_bootp
  2016-01-17 15:41               ` [PATCH][WiP] native DHCPv4 support in net_bootp Andrei Borzenkov
@ 2016-01-21 18:37                 ` Mark Rutland
  2016-03-19  1:03                 ` Rivard, Matthew T
  1 sibling, 0 replies; 12+ messages in thread
From: Mark Rutland @ 2016-01-21 18:37 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: Rivard, Matthew T

Hi,

Thank you for putting this together!

On Sun, Jan 17, 2016 at 06:41:53PM +0300, Andrei Borzenkov wrote:
> 14.10.2015 23:09, Andrei Borzenkov пишет:
> > 14.10.2015 21:09, Rivard, Matthew T пишет:
> >> Just going by these definitions of bootp and dhcp here:
> >> https://technet.microsoft.com/en-us/library/cc781243%28v=ws.10%29.aspx
> >>
> >> The net_bootp only works with a bootp enabled scope on the dhcp server
> >> after chaining from iPXE to grub2.   Without a "bootp" scope setup on
> >> the dhcp, calling net_bootp on the adapter fails to get an IP address.
> >>
> >> So, I guess I could more clearly word that the bootp protocol works
> >> when calling net_bootp, but standard dhcp isn't.
> >>
> > 
> > Hmm ... you are right; we are actually doing BOOTP here, not DHCP.
> > 
> 
> This patch adds support for native DHCPv4 and removes requirement for
> BOOTP compatibility support in DHCP server.
> 
> This is work in progress, but this works for me in test environment.

I haven't delved into the code, but FWIW, this also works for me in my
BOOTP-free work environment on an AArch64 host:

grub> insmod efinet
grub> net_ls_cards
efinet1 00:00:1a:1b:9d:9a
efinet0 00:00:1a:1b:9d:99
grub> net_bootp efinet0
grub> insmod tftp
grub> set net_default_server=10.1.205.151
grub> linux (tftp)/Image
grub> boot
EFI stub: Booting Linux Kernel...
EFI stub: Using DTB from configuration table
EFI stub: Exiting boot services and installing virtual address map...
Booting Linux on physical CPU 0x0
Initializing cgroup subsys cpu
Linux version 4.4.0-rc3+ (mark@leverpostej) (gcc version 5.1.1 20150608 (Linaro GCC 5.1-2015.08) ) #63 SMP PREEMPT Mon Jan 18 10:20:30 GMT 2016
....

I have not tested BOOTP as I do not have a BOOTP server to hand.

I'd like to be able to net-boot a number of development machines that I am in
charge of. However, as I'm not in charge of the network I cannot use PXE, and
our DHCP servers do not implement BOOTP.

Having DHCP support would be incredibly useful for being able to net-boot
boards in a standard manner while not having full control over the network.

> Patch changes net_bootp to implement full DHCP transaction. it still
> /should/ work with BOOTP pure server (untested, I do not have one). It
> also re-implements option processing to support overloaded fields and
> consolidates it in one place.
> 
> What is currently not implemented
> 
> - per interface, per transaction stage retransmit timer. Will be done.
> 
> - DHCP server selection. We take first DHCPOFFER or BOOTPREPLY. No plans
> to implement.
> 
> - DHCP option concatenation (RFC3396). I do not expect to hit it in real
> life; could be implemented relatively easy if needed.
> 
> - client identifier (RFC6842). I do not expect to hit it in real life;
> could be added easily if needed.

The above sounds fine for my purposes.

Thanks,
Mark.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: [PATCH][WiP] native DHCPv4 support in net_bootp
  2016-01-17 15:41               ` [PATCH][WiP] native DHCPv4 support in net_bootp Andrei Borzenkov
  2016-01-21 18:37                 ` Mark Rutland
@ 2016-03-19  1:03                 ` Rivard, Matthew T
  2016-03-19  4:51                   ` Andrei Borzenkov
  1 sibling, 1 reply; 12+ messages in thread
From: Rivard, Matthew T @ 2016-03-19  1:03 UTC (permalink / raw)
  To: Andrei Borzenkov, The development of GNU GRUB

Thanks for the patch, finally had an opportunity to apply it and test it.   It did require disabling -Werror in order for the diff that was originally supplied to compile, as there's a couple of variables that were throwing uninitialized warnings.  


-----Original Message-----
From: Andrei Borzenkov [mailto:arvidjaar@gmail.com] 
Sent: Sunday, January 17, 2016 7:42 AM
To: Rivard, Matthew T <matthew.t.rivard@intel.com>; The development of GNU GRUB <grub-devel@gnu.org>
Subject: [PATCH][WiP] native DHCPv4 support in net_bootp

14.10.2015 23:09, Andrei Borzenkov пишет:
> 14.10.2015 21:09, Rivard, Matthew T пишет:
>> Just going by these definitions of bootp and dhcp here:
>> https://technet.microsoft.com/en-us/library/cc781243%28v=ws.10%29.asp
>> x
>>
>> The net_bootp only works with a bootp enabled scope on the dhcp server
>> after chaining from iPXE to grub2.   Without a "bootp" scope setup on
>> the dhcp, calling net_bootp on the adapter fails to get an IP address.
>>
>> So, I guess I could more clearly word that the bootp protocol works 
>> when calling net_bootp, but standard dhcp isn't.
>>
> 
> Hmm ... you are right; we are actually doing BOOTP here, not DHCP.
> 

This patch adds support for native DHCPv4 and removes requirement for BOOTP compatibility support in DHCP server.

This is work in progress, but this works for me in test environment.

Patch changes net_bootp to implement full DHCP transaction. it still /should/ work with BOOTP pure server (untested, I do not have one). It also re-implements option processing to support overloaded fields and consolidates it in one place.

What is currently not implemented

- per interface, per transaction stage retransmit timer. Will be done.

- DHCP server selection. We take first DHCPOFFER or BOOTPREPLY. No plans to implement.

- DHCP option concatenation (RFC3396). I do not expect to hit it in real life; could be implemented relatively easy if needed.

- client identifier (RFC6842). I do not expect to hit it in real life; could be added easily if needed.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH][WiP] native DHCPv4 support in net_bootp
  2016-03-19  1:03                 ` Rivard, Matthew T
@ 2016-03-19  4:51                   ` Andrei Borzenkov
  0 siblings, 0 replies; 12+ messages in thread
From: Andrei Borzenkov @ 2016-03-19  4:51 UTC (permalink / raw)
  To: Rivard, Matthew T, The development of GNU GRUB

19.03.2016 04:03, Rivard, Matthew T пишет:
> Thanks for the patch, finally had an opportunity to apply it and test
> it.   It did require disabling -Werror in order for the diff that was
> originally supplied to compile, as there's a couple of variables that
> were throwing uninitialized warnings.
> 

Build log would be helpful.

> 
> -----Original Message----- From: Andrei Borzenkov
> [mailto:arvidjaar@gmail.com] Sent: Sunday, January 17, 2016 7:42 AM 
> To: Rivard, Matthew T <matthew.t.rivard@intel.com>; The development
> of GNU GRUB <grub-devel@gnu.org> Subject: [PATCH][WiP] native DHCPv4
> support in net_bootp
> 
> 14.10.2015 23:09, Andrei Borzenkov пишет:
>> 14.10.2015 21:09, Rivard, Matthew T пишет:
>>> Just going by these definitions of bootp and dhcp here: 
>>> https://technet.microsoft.com/en-us/library/cc781243%28v=ws.10%29.asp
>>>
>>> 
x
>>> 
>>> The net_bootp only works with a bootp enabled scope on the dhcp
>>> server after chaining from iPXE to grub2.   Without a "bootp"
>>> scope setup on the dhcp, calling net_bootp on the adapter fails
>>> to get an IP address.
>>> 
>>> So, I guess I could more clearly word that the bootp protocol
>>> works when calling net_bootp, but standard dhcp isn't.
>>> 
>> 
>> Hmm ... you are right; we are actually doing BOOTP here, not DHCP.
>> 
> 
> This patch adds support for native DHCPv4 and removes requirement for
> BOOTP compatibility support in DHCP server.
> 
> This is work in progress, but this works for me in test environment.
> 
> Patch changes net_bootp to implement full DHCP transaction. it still
> /should/ work with BOOTP pure server (untested, I do not have one).
> It also re-implements option processing to support overloaded fields
> and consolidates it in one place.
> 
> What is currently not implemented
> 
> - per interface, per transaction stage retransmit timer. Will be
> done.
> 
> - DHCP server selection. We take first DHCPOFFER or BOOTPREPLY. No
> plans to implement.
> 
> - DHCP option concatenation (RFC3396). I do not expect to hit it in
> real life; could be implemented relatively easy if needed.
> 
> - client identifier (RFC6842). I do not expect to hit it in real
> life; could be added easily if needed.
> 



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2016-03-19  4:52 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <EEEB59C9688B214382E250B0063276B96CEE43@ORSMSX102.amr.corp.intel.com>
     [not found] ` <55FB8A5F.6040404@gmail.com>
     [not found]   ` <EEEB59C9688B214382E250B0063276B96CF050@ORSMSX102.amr.corp.intel.com>
2015-10-14  6:13     ` iPXE efi chainloading grub2 pxe efi file Andrei Borzenkov
2015-10-14 16:56       ` Rivard, Matthew T
2015-10-14 18:03         ` Andrei Borzenkov
2015-10-14 18:09           ` Rivard, Matthew T
2015-10-14 18:23             ` Andrei Borzenkov
2015-10-14 21:12               ` Rivard, Matthew T
2015-10-14 20:09             ` Andrei Borzenkov
2016-01-17 15:41               ` [PATCH][WiP] native DHCPv4 support in net_bootp Andrei Borzenkov
2016-01-21 18:37                 ` Mark Rutland
2016-03-19  1:03                 ` Rivard, Matthew T
2016-03-19  4:51                   ` Andrei Borzenkov
2015-10-15 17:46       ` [ipxe-devel] iPXE efi chainloading grub2 pxe efi file Michael Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.