Both of the multicast checks should be skipped if the address type
is unicast. This bug accidentally caused only one of them to be
skipped, resulting in some unnecessary performance overhead.
Reported by Axel Lin.
Couple of more cleanups for task #14314 involving includes:
1) if.h name should match if_api.c due to LwIP convention and history.
Standard if.h include can be used with compatibility header in
posix/net/if.h
2) API header (if.h) should not be included in core code. This include
has been eliminated by moving the definition of IF_NAMESIZE to
netif.h as NETIF_NAMESIZE. This is now the canonical definition
and IF_NAMESIZE just maps to it to provide the standard type
Now that tcp_connect() always determines the outgoing netif with a
route lookup, we can compute the effective MSS without doing the same
route lookup again. The outgoing netif is already known from one
other location that computes the MSS, so we can eliminate a redundant
route lookup there too. Reduce some macro clutter as a side effect.
This patch adds full support for IPv6 address scopes, thereby aiming
to be compliant with IPv6 standards in general and RFC 4007 in
particular. The high-level summary is that link-local addresses are
now meaningful only in the context of their own link, guaranteeing
full isolation between links (and their addresses) in this respect.
This isolation even allows multiple interfaces to have the same
link-local addresses locally assigned.
The implementation achieves this by extending the lwIP IPv6 address
structure with a zone field that, for addresses that have a scope,
carries the scope's zone in which that address has meaning. The zone
maps to one or more interfaces. By default, lwIP uses a policy that
provides a 1:1 mapping between links and interfaces, and considers
all other addresses unscoped, corresponding to the default policy
sketched in RFC 4007 Sec. 6. The implementation allows for replacing
the default policy with a custom policy if desired, though.
The lwIP core implementation has been changed to provide somewhat of
a balance between correctness and efficiency on on side, and backward
compatibility on the other. In particular, while the application would
ideally always provide a zone for a scoped address, putting this in as
a requirement would likely break many applications. Instead, the API
accepts both "properly zoned" IPv6 addresses and addresses that, while
scoped, "lack" a zone. lwIP will try to add a zone as soon as possible
for efficiency reasons, in particular from TCP/UDP/RAW PCB bind and
connect calls, but this may fail, and sendto calls may bypass that
anyway. Ultimately, a zone is always added when an IP packet is sent
when needed, because the link-layer lwIP code (and ND6 in particualar)
requires that all addresses be properly zoned for correctness: for
example, to provide isolation between links in the ND6 destination
cache. All this applies to packet output only, because on packet
input, all scoped addresses will be given a zone automatically.
It is also worth remarking that on output, no attempt is made to stop
outgoing packets with addresses for a zone not matching the outgoing
interface. However, unless the application explicitly provides
addresses that will result in such zone violations, the core API
implementation (and the IPv6 routing algorithm in particular) itself
will never take decisions that result in zone violations itself.
This patch adds a new header file, ip6_zone.h, which contains comments
that explain several implementation aspects in a bit more detail.
For now, it is possible to disable scope support by changing the new
LWIP_IPV6_SCOPES configuration option. For users of the core API, it
is important to note that scoped addresses that are locally assigned
to a netif must always have a zone set; the standard netif address
assignment functions always do this on behalf of the caller, though.
Also, core API users will want to enable LWIP_IPV6_SCOPES_DEBUG at
least initially when upgrading, to ensure that all addresses are
properly initialized.
In file included from ../../../../lwip/src/include/lwip/sockets.h:49:0,
from ../../../../lwip/src/core/init.c:47:
../../../../lwip/src/include/lwip/errno.h:46:5: error:
"LWIP_PROVIDE_ERRNO" is not defined [-Werror=undef]
#if LWIP_PROVIDE_ERRNO
^~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
../Common.mk:93: recipe for target 'init.o' failed
make: *** [init.o] Error 1
This commit cleans up the remaining instance of global variable
"index" shadowing caused by using local variables and function
parameters named "index"
These were introduced in the recent interface index API commits
Eliminate ETHADDR32_COPY macro - it cannot be used in ETH_PAD_SIZE case. I could have kept it by defining it to ETHADDR16_COPY in case of ETH_PAD_SIZE, but I did not consider it worth another #ifdef mess.
This patch aims to fix three closely related issues.
o The implementation of IPV6_FRAG_COPYHEADER was fundamentally
incompatible with the presence of extension headers between the
IPv6 header and the Fragment Header. This patch changes the
implementation to support such extension headers as well, with
pretty much the same memory requirements. As a result, we can
remove the check that prevented such packets from being reassembled
in all cases, even with IPV6_FRAG_COPYHEADER off.
o Given that temporary data is stored in the Fragment Header of
packets saved for the purpose of reassembly, but ICMPv6 "Fragment
Reassembly Time Exceeded" packets contain part of the original
packet, such ICMPv6 packets could actually end up containing part
of the temporary data, which may even include a pointer value. The
ICMPv6 packet should contain the original, unchanged packet, so
save the original header data before overwriting it even if
IPV6_FRAG_COPYHEADER is disabled. This does add some extra memory
consumption.
o Previously, the reassembly would leave the fragment header in the
reassembled packet, which is not permitted by RFC 2460 and prevents
reassembly of particularly large packets (close to 65535 bytes
after reassembly). This patch gets rid of the fragment header. It
does require an implementation of memmove() for that purpose.
Note that this patch aims to improve correctness. Future changes
might restore some of the previous functionality in order to regain
optimal performance for certain cases (at the cost of more code).
- Move fsdata.h content to lwip/apps/fs.h -> no #include path needed any more to src/apps/httpd/
- Create a #define to specify fsdata file name. One can use path in there now, e.g. "../mywebserver/mkfsdata_output.c" -> no #include path needed any more to location of generated file
The current ND implementation does not yet implement the most basic
required ('MUST') checks for message validation and generation.
- implement some of the required checks for message validation;
- document the remaining missing message validation checks;
- hardcode the hop limit of Neighbor Discovery messages rather than
having it depend on lwIP configuration which, if changed, would
cause all of ND to cease working.
As laid out in RFC 5942, the assumption that a dynamically assigned
(SLAAC/DHCPv6) address implies an on-link subnet, is wrong. lwIP does
currently make that assumption, routing packets according to local
address subnets rather than the on-link prefix list. The result is
that packets may not make it to their destination due to incorrect
routing decisions.
This patch changes the routing algorithms to be (more) compliant with
RFC 5942, by implementing the following new routing policies:
- all routing decisions check the on-link prefix list first, and
select a default router for off-link routing only if there is no
matching entry in the on-link prefix list;
- dynamically assigned addresses (from address autoconfiguration) are
considered /128 assignments, and thus, no routing decisions are taken
based on matches against their (/64) subnet anymore;
- more generally, all addresses that have a lifetime are considered
dynamically assigned and thus of size /128, which is the required
behavior for externally implemented SLAAC clients and DHCPv6;
- statically assigned (i.e., manually configured) addresses are still
considered /64 assignments, and thus, their associated subnet is
considered for routing decisions, in order to behave as generally
expected by end users and to retain backward compatibility;
- the link-local address in IPv6 address slot #0 is considered static
and thus has no lifetime and an implied /64 subnet, although link-
local routing is currently always handled separately anyway.
IPv6 source address selection is kept as is, as the subnet tests in
the algorithm serve as poor man's longest-common-prefix equivalent
there (RFC 6724 Sec. 5, Rule 8).
In summary, this patch aims to resolve bugs #47923 and #48162, by
decoupling address autoconfiguration from the on-link prefix list,
since those are not related. Important necessary changes are needed
to meet this goal, ultimately bringing the lwIP ND6 implementation
closer to compliance with RFC 4862. The main changes are:
1. support for address lifetimes, and,
2. addition of a new DUPLICATED address state.
The decoupling implies that the prefix list can no longer be used to
maintain state for address autoconfiguration. Most importantly, the
lifetime of each address, which was previously derived from the
prefix slot's lifetime, must now be associated with the address
itself. This patch implements address lifetime tracking, maintaining
both a valid and a preferred lifetime for each address, along with
the corresponding address state changes (e.g., between PREFERRED and
DEPRECATED), all as required by RFC 4862.
The support for address lifetimes can be enabled with a new
LWIP_IPV6_ADDRESS_LIFETIMES setting in lwipopts.h. It is required for
autoconfiguration and enabled by default if autoconfiguration is
enabled as well, but it may also be enabled separately, so as to allow
application-controlled lifetime management (e.g., if autoconfiguration
is implemented in a separate application). A special valid-lifetime of
zero is used to denote a static address--that is, an address that was
configured manually, that does not have lifetimes, and that should be
left alone by the autoconfiguration functionality. Addresses assigned
without setting a lifetime are deemed static, thus preserving
compatibility with existing lwIP-based applications in this respect.
Similarly, the decoupling implies that the prefix list can no longer
be used to remember cases of address duplication. Previously, the
detection of a duplicated address would simply result in removal of
the address altogether. Instead, this patch introduces a new state
"DUPLICATED", indicating that the address, while technically still
present, has been found to conflict with other node addresses, and no
attempt should be made to produce an autoconfiguration address for
that prefix.
Manually added addresses, including the link-local address, once set
to DUPLICATED, will remain in that state until manual intervention.
Autoconfigured DUPLICATED addresses will expire according to their
valid-lifetime, essentially preserving the current behavior but
without the use of the prefix list. As a first attempt to approach
compliance with RFC 4862 Sec. 5.4.5, if the link-local address is
detected to be duplicated, all derived addresses are marked duplicated
as well, and no new addresses will be autoconfigured. More work is to
be done for full compliance with that section, however.
Together, those two main changes indeed do fully decouple address
autoconfiguration from the on-link prefix list. Changes to the latter
thus no longer affect the former, resolving bug #47923. Moreover, as a
result, autoconfiguration can, and does, now also take place on
advertised prefixes that do not have the on-link flag set, resolving
bug #48162. The routing changes mentioned in the discussion of that
bug are left to a separate patch, though.
This patch adds a new RAW_FLAGS_HDRINCL flag to the raw core
implementation. When this flag is set on a RAW PCB, the raw send
routines expect the caller to supply an IP header for the given
packet, and will use that IP header instead of prepending one to
the packet themselves.
This feature allows the IP_HDRINCL socket option to be implemented
in higher layers with no further effort. Even thoguh that option is
traditionally supported for IPv4 sockets only (e.g., see RFC 3542
Sec. 3), the RAW_FLAGS_HDRINCL flag supports both IPv4 and IPv6, as
much of the lower-level infrastructure was already in place anyway.
Similar to the core UDP API, the new function may be used to implement
IPV6_PKTINFO (RFC 3542 Sec. 4), for example. This patch makes no
further functional changes; it merely moves code around a bit.
The support for connecting raw sockets is extended to match the
support for UDP sockets, while keeping the current API unchanged:
- for connected sockets, filter incoming packets on source address;
- use a flag to indicate whether a socket is connected, at no extra
memory cost; the application may check this flag if needed;
- added raw_disconnect(), which so far existed in documentation only.