[syslinux] [PATCH 0/1] EFI PXE DHCP/proxyDHCP issues fix

jeff_sloan at selinc.com
Thu, 18 Jun 2015 12:24:46 -0000

Patrick,

 I wanted to follow up with your earlier questions.

>>>
 >>>
  The real DHCP server supplies client ip address only.
  Everything else comes from proxyDHCP.
  The proxyDHCP server supplies boot file name, boot file (syslinux.efi),
  boot loader (ldlinux.e64), config file, tinycore and OS image files.
 <<<

 This is not completely correct:
 your DHCP server provides an IP and your proxyDHCP server only processes
 a complementary DHCP transaction providing the "NBP name" and
"TFTP
server IP".
 Actual files are really offered by a "TFTP Server" that in your case
surely is running
 with your proxyDHCP under the same OS instance.
<<<

I was thinking in terms of the physical devices/systems but should be
describing my setup in terms of the applications. The actual hardware is
not germaine. With that frame of reference, my setup is exactly as you
describe: DHCP, proxyDHCP and TFTP servers.

DHCP supplies client IP address in a DHCPOffer packet
proxyDHCP provides TFTP server IP in DHCPOffer packet with NULL client IP
as well as NBP filename
TFTP server provides all files requested

Sorry for the confusion.

>>>
 >>>
  Problem 1:
  The first problem is an issue in TianoCore BIOS that has been there
since
  the beginning. When responding to a proxyDHCP and attempting
  to grab the  boot filename, BIOS specifies an incorrect
sending/listening
  (source/destination) port pair. It should be 68/4011 but sends
4011/4011.
  I updated this for IPv4 but noticed that the problem has
  been carried over to IPv6 code in our code base.
 <<<

 RFC2131 says:
    "DHCP uses UDP as its transport protocol.  DHCP messages from a client
    to a server are sent to the 'DHCP server' port (67), and DHCP
    messages from a server to a client are sent to the 'DHCP client'
port
    (68)."

 but RFC2131 does not define a proxyDHCP service; the PXE v2.1 standard
does it
 PXE v2.1 says:


    "Step 6. The Boot Server unicasts a DHCPACK packet back to the client
      on the client source port."

 Then it's not really specified that the DHCPREQUEST to a proxyDHCP server
must use
 68 as source port...

 As I can see this "issue" (if there's one here) is all about the
agreement between
 the client FW and the proxyDHCP server; syslinux has nothing to do here.
<<<

As you correctly point out, d.o.r.a. with the DHCP server must use port 68
since there is no client IP at that point. After that, any valid port is
acceptable since none are defined by the pxe or uefi specs.

Good call! Digging deeper into this issue, we have a problem with our
proxyDHCP server. It is not handling any client listening port except for
68 by ignoring the packet so the BIOS fix was actually a band-aid. I have
verified that the Boot Request UDP packets are identical using port 68 and
4011 other than the checksums so BIOS is sending correct packets.

I originally mentioned this issue here to help anyone who might be seeing
the same problem. It is not a syslinux problem in any way.


>>>
   >>>
   Failing scenario/behavior for problem 1:
   You can determine if you have this issue by setting up a WireShark
system
   and snooping. The failing scenario is in the UDP request for boot
filename
   to the proxyDHCP server, both ports are 4011 so the proxy server
ignores
   the packet and does not reply.
   <<<

  This depends on the proxyDHCP; if you use i.e Serva you will have no
problem at all,
  the proxyDHCP ACK will be send to the source port used by the client on
its
  previous DHCPREQUEST. That's it.
  What failing proxyDHCP are you using?
<<<

Our customer was not able to give me details on proxy and tftp server
software. He is currently on vacation but I will work with him when he
returns to figure out what exactly he is using. As soon I know the answer
I will post it here so everyone knows which proxyserver is failing and I
will work on a fix.

>>>
  >>>
   Resolution for problem 1:
   If you have access to your BIOS source code, change boot request source

   port to 68. If you don?t have access to the source, contact
   your BIOS  provider. I will alert TianoCore to this issue but it may
   also be present in some OEM BIOS provider?s code.
   <<<

  I think you should probably delve deeper in the standards before trying
to change this.
  just my 2 cents.
<<<

Good advice and done. It is not a BIOS problem so I will not do anything
as far as TianoCore.

>>>
  >>>
   Problem 2:
   The next problem is packet parsing and incomplete ip address sets on
the
   syslinux side. The basic issue is that the packets are incomplete or
not
   used in a proxyDHCP environment. The real DHCP Offer/Ack
   contains the  client ip. The proxy Offer contains the server ip. We
also
   have to grab  the gateway and subnet mask. There is no single packet or
   location where  all the addresses are contained. The most complete
struct
   that I found is  the IPInfo but even there the server ip is incorrect.
So we
   need to either build and populate a complete struct for proxy or pull
from
   several  different packets when needed.
  <<<

  The DHCP transaction has several stages; in EFI firmware every stage
  populates a different packet. the packets are:
  DhcpAck,ProxyOffer,PxeReply.

  DhcpAck: usually includes only the DHCP parameters
  ProxyOffer: includes redirection parameters (PXE stuff)
  PxeReply: is populated after receiving an answer when using PXE menu
capabilities.

  Tianocore copies PxeReply to ProxyOffer because many NBPs do not parse
PxeReply
  This is not really new stuff BIOS based PXE was also having several
packets cached...
<<<

I definitely did not make myself clear here. You are correct in the
contents of each of the cached packets so no one packet contains all of
the necessary data. I was thinking that we should pull it all together
into some struct but in the actual patch that I posted instead of updating
any of the packets, I pulled the TFTP server ip address into pkt4_v4, a
temporary packet in function net_parse_dhcp, before parsing.

However, if there is a better way of handling this, I would be happy to
implement it.

>>>
 Failing scenario/behavior for problem 2:
 After syslinux.efi is downloaded and execution begins, no further
Ethernet
 communication occurs. This is caused by incomplete packets
 that are  dropped in the client instead of being sent. The return code
 is  EFI_UNSUPPORTED but the error is ignored after the return
 from the UDP  send command in BIOS. Should this be handled differently?
 <<<


>>>
 Have you applied the patch mentioned on this thread???
<<<

I cleaned up the patch and packaged it in a different thread with the
subject: [PATCH 0/1] Network UEFI PXE DHCP/proxyDHCP fix. Now that zytor
is back up, I will push it.

Thanks again for the feedback!

Jeff