The iBFT is Ethernet-centric in providing only six bytes for a MAC
address. This is most probably an indirect consequence of a similar
design flaw in the Windows NDIS stack. (The WinOF IPoIB stack
performs all sorts of contortions in order to pretend to the NDIS
layer that it is dealing with six-byte MAC addresses.)
There is no sensible way in which to extend the iBFT without breaking
compatibility with programs that expect to parse it. Add the notion
of an "Ethernet-compatible" MAC address to our link layer abstraction,
so that link layers can provide their own workarounds for this
limitation.
Some devices can only be reset via a mechanism that also resets the
card's PCI core, thus necessitating a backup and restore of all or
part of the PCI configuration space across a reset.
802.11 multicast hashing is the same as standard Ethernet hashing, so
just expose and use eth_mc_hash().
Signed-off-by: Joshua Oreman <oremanj@rwcr.net>
For IPoIB, the chaddr field is too small (16 bytes) to contain the
20-byte IPoIB link-layer address. RFC4390 mandates that we should
pass an empty chaddr field and rely on the DHCP client identifier
instead. This has many problems, not least of which is that a client
identifier containing an IPoIB link-layer address is not very useful
from the point of view of creating DHCP reservations, since the QPN
component is assigned at runtime and may vary between boots.
Leave the DHCP client identifier as-is, to avoid breaking existing
setups as far as possible, but expose the real hardware address (the
port GUID) via the DHCP chaddr field, using the broadcast flag to
instruct the DHCP server not to use this chaddr value as a link-layer
address.
This makes it possible (at least with ISC dhcpd) to create DHCP
reservations using host declarations such as:
host duckling {
fixed-address 10.252.252.99;
hardware unknown-32 00:02:c9:02:00:25:a1:b5;
}
IPoIB has a 20-byte link-layer address, of which only eight bytes
represent anything relating to a "hardware address".
The PXE and EFI SNP APIs expect the permanent address to be the same
size as the link-layer address, so fill in the "permanent address"
field with the initial link layer address (as generated by
register_netdev() based upon the real hardware address).
The hardware address is an intrinsic property of the hardware, while
the link-layer address can be changed at runtime. This separation is
exposed via APIs such as PXE and EFI, but is currently elided by gPXE.
Expose the hardware and link-layer addresses as separate properties
within a net device. Drivers should now fill in hw_addr, which will
be used to initialise ll_addr at the time of calling
register_netdev().
There is diagnostic value in being able to disambiguate between the
various reasons why an IB CM has rejected a connection attempt. In
particular, reason 8 "invalid service ID" can be used to identify an
incorrect SRP service_id root-path component, and reason 28 "consumer
reject" corresponds to a genuine SRP login rejection IU, which can be
passed up to the SRP layer.
For rejection reasons other than "consumer reject", we should not pass
through the private data, since it is most likely generated by the CM
without any protocol-specific knowledge.
With iSCSI, connection attempts are expensive; it may take many
seconds to determine that a connection will fail. SRP connection
attempts are much less expensive, so we may as well avoid the
"optimisation" of declaring a state of permanent failure after a
certain number of attempts. This allows a gPXE SRP initiator to
resume operations after an arbitrary amount of SRP target downtime.
SRP is the SCSI RDMA Protocol. It allows for a method of SAN booting
whereby the target is responsible for reading and writing data using
Remote DMA directly to the initiator's memory. The software initiator
merely sends and receives SCSI commands; it never has to touch the
actual data.
The minimal-surprise behaviour, when no explicit SRP initiator device
is specified, will probably be to use the most recently opened
Infiniband device. This matches our behaviour with using the most
recently opened net device for PXE, iSCSI, AoE, NBI, etc.
SRP over Infiniband uses a protocol whereby data is sent via a
combination of the CM private data fields and the RC queue pair
itself. This seems sufficiently generic that it's worth having
available as a separate protocol.
We will terminate our transaction as soon as we receive the first CM
REP, since that provides all the state that we need. However, the
peer may resend the REP if it didn't see our RTU, and if we don't
respond with another RTU we risk being disconnected. (This protocol
appears not to handle retries gracefully.)
Fix by adding a management agent that will listen for these duplicate
REPs and send back an RTU.
Previously the maximum packet length was computed using an erroneous
understanding of the role of the MIC field in TKIP-encrypted packets.
The field is actually considered to be part of the MSDU (encrypted and
fragmented data), not the MPDU (container for each encrypted
fragment). As such its size does not contribute to cryptographic
overhead outside the data field's size limitations. The net result is
that the previous maximum packet length value was 4 bytes too long;
fix it to the correct value of 2352.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
The prior net80211 model of physical-layer behavior for drivers was
overly simplistic and limited the drivers that could be written. To
be more flexible, split the driver-provided list of supported rates by
band, and add a means for specifying a list of supported channels.
Allow drivers to specify a hardware channel value that will be tied to
uses of the channel.
Expose net80211_duration() to drivers, and make the rate it uses in
its computations configurable, so that it can be used in calculating
durations that must be set in hardware for ACK and CTS packets. Add
net80211_cts_duration() for the common case of calculating the
duration for a CTS packet.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
A management interface is the component through which both local and
remote management agents are accessed.
This new implementation of a management interface allows for the user
to react to timed-out transactions, and also allows for cancellation
of in-progress transactions.
The IBA specification refers to management "interfaces" and "agents".
The interface is the component that connects to the queue pair and
sends and receives MADs; the agent is the component that constructs
the reply to the MAD.
Rename the IB_{QPN,QKEY,QPT} constants as a first step towards making
this separation in gPXE.
This is required for all modern 802.11 devices, and allows drivers
to be written for them with minimally more effort than is required
for a wired NIC.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
Modified-by: Michael Brown <mcb30@etherboot.org>
Queue pairs are now assumed to be created in the INIT state, with a
call to ib_modify_qp() required to bring the queue pair to the RTS
state.
ib_modify_qp() no longer takes a modification list; callers should
modify the relevant queue pair parameters (e.g. qkey) directly and
then call ib_modify_qp() to synchronise the changes to the hardware.
The packet sequence number is now a property of the queue pair, rather
than of the device.
Each queue pair may have an associated address vector. For RC queue
pairs, this is the address vector that will be programmed in to the
hardware as the remote address. For UD queue pairs, it will be used
as the default address vector if none is supplied to ib_post_send().
Now that MAD handlers no longer return a status code, we can allow
them to return a pointer to a MAD structure if and only if they want
to send a response. This provides a more natural and flexible
approach than using a "response method" field within the handler's
descriptor.
MAD handlers have to set the status fields within the MAD itself
anyway, in order to provide a meaningful response MAD; the additional
gPXE return status code is just noise.
Note that we probably don't need to ever explicitly set the status to
IB_MGMT_STATUS_OK, since it should already have this value from the
request. (By not explicitly setting the status in this way, we can
safely have ib_sma_set_xxx() call ib_sma_get_xxx() in order to
generate the GetResponse MAD without worrying that ib_sma_get_xxx()
will clear any error status set by ib_sma_set_xxx().)
Most IB hardware seems not to allow allocation of the genuine QPNs 0
and 1, so allow for the externally-visible QPN (as constructed and
parsed by ib_packet, where used) to differ from the real
hardware-allocated QPN.
Generalise the subnet management agent into a general management agent
capable of sending and responding to MADs, including support for
retransmissions as necessary.
Currently, all Infiniband users must create a process for polling
their completion queues (or rely on a regular hook such as
netdev_poll() in ipoib.c).
Move instead to a model whereby the Infiniband core maintains a single
process calling ib_poll_eq(), and polling the event queue triggers
polls of the applicable completion queues. (At present, the
Infiniband core simply polls all of the device's completion queues.)
Polling a completion queue will now implicitly refill all attached
receive work queues; this is analogous to the way that netdev_poll()
implicitly refills the RX ring.
Infiniband users no longer need to create a process just to poll their
completion queues and refill their receive rings.
IPoIB and the SMA have separate constants for the packet size to be
used to I/O buffer allocations. Merge these into the single
IB_MAX_PAYLOAD_SIZE constant.
(Various other points in the Infiniband stack have hard-coded
assumptions of a 2048-byte payload; we don't currently support
variable MTUs.)
IPoIB has a link-layer broadcast address that varies according to the
partition key. We currently go through several contortions to pretend
that the link-layer address is a fixed constant; by making the
broadcast address a property of the network device rather than the
link-layer protocol it will be possible to simplify IPoIB's broadcast
handling.
Move the icky call to step() from aoe.c to ata.c; this takes it at
least one step further away from where it really doesn't belong.
Unfortunately, AoE has the ugly aoe_discover() mechanism which means
that we still have a step() loop in aoe.c for now; this needs to be
replaced at some future point.
The PXE debugging messages have remained pretty much unaltered since
Etherboot 5.4, and are now difficult to read in comparison to most of
the rest of gPXE.
Bring the pxe_undi debug messages up to normal gPXE standards.
Expand the NETDEV_LINK_UP bit into a link_rc status code field,
allowing specific reasons for link failure to be reported via
"ifstat".
Originally-authored-by: Joshua Oreman <oremanj@rwcr.net>
In order to construct outgoing link-layer frames or parse incoming
ones properly, some protocols (such as 802.11) need more state than is
available in the existing variables passed to the link-layer protocol
handlers. To remedy this, add struct net_device *netdev as the first
argument to each of these functions, so that more information can be
fetched from the link layer-private part of the network device.
Updated all three call sites (netdevice.c, efi_snp.c, pxe_undi.c) and
both implementations (ethernet.c, ipoib.c) of ll_protocol to use the
new argument.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
The 93C66 is identical to the 93C56 in programming interface and
addressing, but twice as large in data storage (4096 bits). It's
used in some RTL8185 wireless cards.
Signed-off-by: Michael Brown <mcb30@etherboot.org>
gPXE responds to duplicated ACKs with an immediate retransmission,
which can lead to a sorceror's apprentice syndrome. It also responds
to out-of-range (or old duplicate) ACKs with a RST, which can cause
valid connections to be dropped.
Fix the sorceror's apprentice syndrome by leaving the retransmission
timer running (and so inhibiting the immediate retransmission) when we
receive a potential duplicate ACK. This seems to match the behaviour
of Linux observed via wireshark traces.
Fix the RST issue by sending RST only on out-of-range ACKs that occur
before the connection is fully established, as per RFC 793.
These problems were exposed during development of the 802.11 wireless
link layer; the 802.11 protocol has a failure mode that can easily
cause duplicated packets. The fixes were tested in a controlled way
by faking large numbers of duplicated packets in the rtl8139 driver.
Originally-fixed-by: Joshua Oreman <oremanj@rwcr.net>
MAX_LL_HEADER_LEN is erroneously set to 6 rather than 14, resulting
in possible data corruption whenever we send an ARP packet.
Fix value and add a comment explaining why MAX_LL_ADDR_LEN is greater
than MAX_LL_HEADER_LEN.
Reported-by: Joshua Oreman <oremanj@rwcr.net>
Windows text editors such as Notepad tend to use CRLF line endings,
which breaks gPXE's signature detection for script images. Since
scripts are usually very small, they end up falling back to being
detected as valid PXE executable images (since there are no signature
checks for PXE executables). Executing text files as x86 machine code
tends not to work well.
Fix by allowing for any isspace() character to terminate the "#!gpxe"
signature, and by ensuring that CR characters get stripped during
command line parsing.
Suggested-by: Shao Miller <Shao.Miller@yrdsb.edu.on.ca>
Several SPI chips will respond to an SPI read command with a dummy
zero bit immediately prior to the first real data bit. This can be
used to autodetect the address length, provided that the command
length and data length are already known, and that the MISO data line
is tied high.
Tested-by: Thomas Miletich <thomas.miletich@gmail.com>
Debugged-by: Thomas Miletich <thomas.miletich@gmail.com>
For partly historical reasons, various files in the gPXE source tree
are licensed under different, though compatible, terms. Most of the
code is licensed under GPLv2 with the "or later" clause, but there are
exceptions such as:
The string.h file, which derives from Linux and is licensed as
Public Domain.
The EFI header files, which are taken from the EDK2 source tree and
are licensed under BSD.
The 3c90x driver, which has a custom GPL-like licence text.
Introduce a FILE_LICENCE() macro to make licensing more explicit.
This macro should be applied exactly once to each source (.c, .S or
.h) file. It will cause a corresponding zero-sized common symbol to
be added to any .o files generated from that source file (and hence to
any final gPXE binaries generated from that source file). Determining
the applicable licences to generated files can then be done using e.g.
$ objdump -t bin/process.o | grep __licence
00000000 O *COM* 00000001 .hidden __licence_gpl2_or_later
indicating that bin/process.o is covered entirely by the GPLv2
with the "or later" clause, or
$ objdump -t bin/rtl8139.dsk.tmp | grep __licence
00033e8c g O .bss.textdata 00000000 .hidden __licence_gpl2_only
00033e8c g O .bss.textdata 00000000 .hidden __licence_gpl2_or_later
00033e8c g O .bss.textdata 00000000 .hidden __licence_public_domain
indicating that bin/rtl8139.dsk includes both code licensed under
GPLv2 (both with and without the "or later" clause) and code licensed
as Public Domain.
Determining the result of licence combinations is currently left as an
exercise for the reader.
The Mac compiler treats "#pragma pack()" as gcc's "#pragma pack(pop)",
and so dies if the pragma pack stack is empty. Adding a "#pragma
pack(1)" immediately beforehand is enough to keep the Mac compiler
happy.
The combination of "#pragma pack(1)", "#pragma pack()" won't actually
achieve anything on a Mac, but it will at least build. (With gcc, the
"#pragma pack()" overrides any previous pragmas, so is still useful.)
Suggested-by: Joshua Oreman <oremanj@rwcr.net>
Eliminate the potential for mismatches between table names and the
table entry data type by incorporating the data type into the
definition of the table, rather than specifying it explicitly in each
table accessor method.
Intel's C compiler (icc) chokes on the zero-length arrays that we
currently use as part of the mechanism for accessing linker table
entries. Abstract away the zero-length arrays, to make a port to icc
easier.
Introduce macros such as for_each_table_entry() to simplify the common
case of iterating over all entries in a linker table.
Represent table names as #defined string constants rather than
unquoted literals; this avoids visual confusion between table names
and C variable or type names, and also allows us to force a
compilation error in the event of incorrect table names.
Allow for settings blocks to be created on demand. This allows for
constructions such as
set defaults/filename http://bootserver/bootfile
set defaults/priority 0xff
dhcp net0
chain ${filename}
which will boot from the DHCP-provided filename, or from
"http://bootserver/bootfile" if the DHCP server does not provide a
filename.
(Note that "priority" gets interpreted as a signed integer, so setting
"defaults/priority" to 0xff will cause the "defaults" settings block
to have an effective priority of -1.)
Having a default script containing
#!gpxe
autoboot
can cause problems when entering commands to load and start a kernel
manually; the default script image will still be present when the
kernel is started and so will be treated as an initrd. It is possible
to work around this by typing "imgfree" before any other commands, but
this is counter-intuitive.
Fix by allowing the embedded image list to be empty (in which case we
just call autoboot()), and making this the default.
Reported by alkisg@gmail.com.
Avoid passing credentials in the iBFT that were available but not
required for login. This works around a problem in the Microsoft
iSCSI initiator, which will refuse to initiate sessions if the CHAP
password is fewer than 12 characters, even if the target ends up not
asking for CHAP authentication.
It is a programming error, not a runtime error, if we attempt to use
block ciphers with an incorrect blocksize, so use an assert() rather
than an error status return.
The various types of cryptographic algorithm are fundamentally
different, and it was probably a mistake to try to handle them via a
single common type.
pubkey_algorithm is a placeholder type for now.
Certain combinations of PXE stack and BIOS result in a broken INT 18
call, which will leave the system displaying a "PRESS ANY KEY TO
REBOOT" message instead of proceeding to the next boot device. On
these systems, returning via the PXE stack is the only way to continue
to the next boot device. Returning via the PXE stack works only if we
haven't already blown away the PXE base code in pxeprefix.S.
In most circumstances, we do want to blow away the PXE base code.
Base memory is a limited resource, and it is desirable to reclaim as
much as possible. When we perform an iSCSI boot, we need to place the
iBFT above the 512kB mark, because otherwise it may not be detected by
the loaded OS; this may not be possible if the PXE base code is still
occupying that memory.
Introduce a new prefix type .kkpxe which will preserve both the PXE
base code and the UNDI driver (as compared to .kpxe, which preserves
the UNDI driver but uninstalls the PXE base code). This prefix type
can be used on systems that are known to experience the specific
problem of INT 18 being broken, or in builds (such as gpxelinux.0) for
which it is particularly important to know that returning to the BIOS
will work.
Written by H. Peter Anvin <hpa@zytor.com> and Stefan Hajnoczi
<stefanha@gmail.com>, minor structural alterations by Michael Brown
<mcb30@etherboot.org>.
Multi-level menus via COMBOOT rely on the COMBOOT program being able
to exit and invoke a new COMBOOT program (the next menu). This works,
but rapidly (within about five iterations) runs out of space in gPXE's
internal stack, since each new image is executed in a new function
context.
Fix by allowing tail recursion between images; an image can now
specify a replacement image for itself, and image_exec() will perform
the necessary tail recursion.