summaryrefslogtreecommitdiffstats
path: root/src/arch
diff options
context:
space:
mode:
authorMichael Brown2016-03-22 18:33:21 +0100
committerMichael Brown2016-03-22 18:33:21 +0100
commit3df598849b53c8bf5e87b6c300fdee6d0c0480f1 (patch)
tree5a283e56bd9294d98003b008a2688b503ee5a101 /src/arch
parent[libc] Make sleep() interruptible (diff)
downloadipxe-3df598849b53c8bf5e87b6c300fdee6d0c0480f1.tar.gz
ipxe-3df598849b53c8bf5e87b6c300fdee6d0c0480f1.tar.xz
ipxe-3df598849b53c8bf5e87b6c300fdee6d0c0480f1.zip
[pxe] Implicitly open network device in PXENV_UDP_OPEN
Some end-user configurations have been observed in which the first NBP (such as GRUB2) uses the UNDI API and then transfers control to a second NBP (such as pxelinux) which uses the UDP API. The first NBP closes the network device using PXENV_UNDI_CLOSE, which renders the UDP API unable to transmit or receive packets. The correct behaviour under these circumstances is (as often) simply not documented by the PXE specification. Testing with the Intel PXE stack suggests that PXENV_UDP_OPEN will implicitly reopen the network device if necessary, so match this behaviour. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/interface/pxe/pxe_udp.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/arch/x86/interface/pxe/pxe_udp.c b/src/arch/x86/interface/pxe/pxe_udp.c
index 071cb59d..5a04f086 100644
--- a/src/arch/x86/interface/pxe/pxe_udp.c
+++ b/src/arch/x86/interface/pxe/pxe_udp.c
@@ -11,6 +11,7 @@
#include <ipxe/udp.h>
#include <ipxe/uaccess.h>
#include <ipxe/process.h>
+#include <ipxe/netdevice.h>
#include <realmode.h>
#include <pxe.h>
@@ -180,6 +181,15 @@ static PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *pxenv_udp_open ) {
pxe_udp.local.sin_addr.s_addr = pxenv_udp_open->src_ip;
DBG ( " %s\n", inet_ntoa ( pxe_udp.local.sin_addr ) );
+ /* Open network device, if necessary */
+ if ( pxe_netdev && ( ! netdev_is_open ( pxe_netdev ) ) &&
+ ( ( rc = netdev_open ( pxe_netdev ) ) != 0 ) ) {
+ DBG ( "PXENV_UDP_OPEN could not (implicitly) open %s: %s\n",
+ pxe_netdev->name, strerror ( rc ) );
+ pxenv_udp_open->Status = PXENV_STATUS ( rc );
+ return PXENV_EXIT_FAILURE;
+ }
+
/* Open promiscuous UDP connection */
intf_restart ( &pxe_udp.xfer, 0 );
if ( ( rc = udp_open_promisc ( &pxe_udp.xfer ) ) != 0 ) {