iPXE
Etherboot PXE implementation notes

IP routing

Several PXE API calls (e.g. pxenv_tftp_open() and pxenv_udp_write()) allow for the caller to specify a "relay agent IP address", often in a field called "gateway" or similar. The PXE specification states that "The IP layer should provide space for a minimum of four routing entries obtained from the default router and static route DHCP option tags in the DHCPACK message, plus any non-zero giaddr field from the DHCPOFFER message(s) accepted by the client".

The DHCP static route option ("option static-routes" in dhcpd.conf) works only for classed IP routing (i.e. it provides no way to specify a subnet mask). Since virtually everything now uses classless IP routing, the DHCP static route option is almost totally useless, and is (according to the dhcp-options man page) not implemented by any of the popular DHCP clients.

This leaves the caller-specified "relay agent IP address", the giaddr field from the DHCPOFFER message(s) and the default gateway(s) provided via the routers option ("option routers" in dhcpd.conf) in the DHCPACK message. Each of these is a default gateway address. It's a fair bet that the routers option should take priority over the giaddr field, since the routers option has to be explicitly specified by the DHCP server operator. Similarly, it's fair to assume that the caller-specified "relay agent IP address", if present, should take priority over any other routing table entries.

Bug:
Etherboot currently ignores all potential sources of routing information other than the first router provided to it by a DHCP routers option.

x86 processor mode restrictions

On the x86 platform, different PXE API calls have different restrictions on the processor modes (real or protected) that can be used. See the individual API call descriptions for the restrictions that apply to any particular call.

Real mode, or protected-mode with 16-bit stack

The PXE specification states that the API function can be called in protected mode only if the s_PXE::StatusCallout field is set to a non-zero value, and that the API function cannot be called with a 32-bit stack segment.

Etherboot does not enforce either of these restrictions; they seem (as with so much of the PXE specification) to be artifacts of the Intel implementation.