lwIP
2.1.0
Lightweight IP stack
|
Macros | |
#define | IP6_NO_ZONE 0 |
#define | IPADDR6_ZONE_INIT , IP6_NO_ZONE |
#define | ip6_addr_zone(ip6addr) ((ip6addr)->zone) |
#define | ip6_addr_has_zone(ip6addr) (ip6_addr_zone(ip6addr) != IP6_NO_ZONE) |
#define | ip6_addr_set_zone(ip6addr, zone_idx) ((ip6addr)->zone = (zone_idx)) |
#define | ip6_addr_clear_zone(ip6addr) ((ip6addr)->zone = IP6_NO_ZONE) |
#define | ip6_addr_copy_zone(ip6addr1, ip6addr2) ((ip6addr1).zone = (ip6addr2).zone) |
#define | ip6_addr_equals_zone(ip6addr, zone_idx) ((ip6addr)->zone == (zone_idx)) |
#define | ip6_addr_cmp_zone(ip6addr1, ip6addr2) ((ip6addr1)->zone == (ip6addr2)->zone) |
#define | IPV6_CUSTOM_SCOPES 0 |
#define | ip6_addr_has_scope(ip6addr, type) |
#define | ip6_addr_assign_zone(ip6addr, type, netif) |
#define | ip6_addr_test_zone(ip6addr, netif) (ip6_addr_equals_zone((ip6addr), netif_get_index(netif))) |
#define | ip6_addr_lacks_zone(ip6addr, type) (!ip6_addr_has_zone(ip6addr) && ip6_addr_has_scope((ip6addr), (type))) |
#define | ip6_addr_select_zone(dest, src) |
Enumerations | |
enum | lwip_ipv6_scope_type { IP6_UNKNOWN = 0, IP6_UNICAST = 1, IP6_MULTICAST = 2 } |
IPv6 address scopes, zones, and scoping policy.
This header provides the means to implement support for IPv6 address scopes, as per RFC 4007. An address scope can be either global or more constrained. In lwIP, we say that an address "has a scope" or "is scoped" when its scope is constrained, in which case the address is meaningful only in a specific "zone." For unicast addresses, only link-local addresses have a scope; in that case, the scope is the link. For multicast addresses, there are various scopes defined by RFC 4007 and others. For any constrained scope, a system must establish a (potentially one-to-many) mapping between zones and local interfaces. For example, a link-local address is valid on only one link (its zone). That link may be attached to one or more local interfaces. The decisions on which scopes are constrained and the mapping between zones and interfaces is together what we refer to as the "scoping policy" - more on this in a bit.
In lwIP, each IPv6 address has an associated zone index. This zone index may be set to "no zone" (IP6_NO_ZONE, 0) or an actual zone. We say that an address "has a zone" or "is zoned" when its zone index is not set to "no zone." In lwIP, in principle, each address should be "properly zoned," which means that if the address has a zone if and only if has a scope. As such, it is a rule that an unscoped (e.g., global) address must never have a zone. Even though one could argue that there is always one zone even for global scopes, this rule exists for implementation simplicity. Violation of the rule will trigger assertions or otherwise result in undesired behavior.
Backward compatibility prevents us from requiring that applications always provide properly zoned addresses. We do enforce the rule that the in the lwIP link layer (everything below netif->output_ip6() and in particular ND6) all addresses are properly zoned. Thus, on the output paths down the stack, various places deal with the case of addresses that lack a zone. Some of them are best-effort for efficiency (e.g. the PCB bind and connect API calls' attempts to add missing zones); ultimately the IPv6 output handler (ip6_output_if_src) will set a zone if necessary.
Aside from dealing with scoped addresses lacking a zone, a proper IPv6 implementation must also ensure that a packet with a scoped source and/or destination address does not leave its zone. This is currently implemented in the input and forward functions. However, for output, these checks are deliberately omitted in order to keep the implementation lightweight. The routing algorithm in ip6_route will take decisions such that it will not cause zone violations unless the application sets bad addresses, though.
In terms of scoping policy, lwIP implements the default policy from RFC 4007 using macros in this file. This policy considers link-local unicast addresses and (only) interface-local and link-local multicast addresses as having a scope. For all these addresses, the zone is equal to the interface. As shown below in this file, it is possible to implement a custom policy.