IPv6 Zones
APIs » "raw" APIs » IP » IPv6

## 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(addr1, addr2) ip6_addr_zone_eq(ip6addr1, ip6addr2)
#define | ip6_addr_zone_eq(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 }

## Detailed Description

## Macro Definition Documentation

## ip6_addr_assign_zone

#define ip6_addr_assign_zone | ( |  | ip6addr,
|  |  | type,
|  |  | netif
| ) |  |

Value:
(ip6_addr_set_zone((ip6addr), \
ip6_addr_has_scope((ip6addr), (type)) ? netif_get_index(netif) : 0))

Assign a zone index to an IPv6 address, based on a network interface. If the given address has a scope, the assigned zone index is that scope's zone of the given netif; otherwise, the assigned zone index is "no zone".

This default implementation follows the default model of RFC 4007, where only interface-local and link-local scopes are defined, and the zone index of both of those scopes always equals the index of the network interface. As such, this default implementation need not distinguish between different constrained scopes when assigning the zone.

Parameters

  ip6addr | the IPv6 address; its address part is examined, and its zone index is assigned.
  type | address type; see lwip_ipv6_scope_type.
  netif | the network interface (const).

## ip6_addr_clear_zone

#define ip6_addr_clear_zone | ( |  | ip6addr | ) | ((ip6addr)->zone = IP6_NO_ZONE)

Clear the zone field of an IPv6 address, setting it to "no zone".

## ip6_addr_cmp_zone

#define ip6_addr_cmp_zone | ( |  | addr1,
|  |  | addr2
| ) |  | ip6_addr_zone_eq(ip6addr1, ip6addr2)

Deprecated:
  Renamed to ip6_addr_zone_eq

## ip6_addr_copy_zone

#define ip6_addr_copy_zone | ( |  | ip6addr1,
|  |  | ip6addr2
| ) |  | ((ip6addr1).zone = (ip6addr2).zone)

Copy the zone field from the second IPv6 address to the first one.

## ip6_addr_equals_zone

#define ip6_addr_equals_zone | ( |  | ip6addr,
|  |  | zone_idx
| ) |  | ((ip6addr)->zone == (zone_idx))

Is the zone field of the given IPv6 address equal to the given zone index? (0/1)

## ip6_addr_has_scope

#define ip6_addr_has_scope | ( |  | ip6addr,
|  |  | type
| ) |  |

Value:
(ip6_addr_islinklocal(ip6addr) || (((type) != IP6_UNICAST) && \
(ip6_addr_ismulticast_iflocal(ip6addr) || \
ip6_addr_ismulticast_linklocal(ip6addr))))

Determine whether an IPv6 address has a constrained scope, and as such is meaningful only if accompanied by a zone index to identify the scope's zone. The given address type may be used to eliminate at compile time certain checks that will evaluate to false at run time anyway.

This default implementation follows the default model of RFC 4007, where only interface-local and link-local scopes are defined.

Even though the unicast loopback address does have an implied link-local scope, in this implementation it does not have an explicitly assigned zone index. As such it should not be tested for in this macro.

Parameters

  ip6addr | the IPv6 address (const); only its address part is examined.
  type | address type; see lwip_ipv6_scope_type.

Returns
  1 if the address has a constrained scope, 0 if it does not.

## ip6_addr_has_zone

#define ip6_addr_has_zone | ( |  | ip6addr | ) | (ip6_addr_zone(ip6addr) != IP6_NO_ZONE)

Does the given IPv6 address have a zone set? (0/1)

## ip6_addr_lacks_zone

#define ip6_addr_lacks_zone | ( |  | ip6addr,
|  |  | type
| ) |  | (!ip6_addr_has_zone(ip6addr) && ip6_addr_has_scope((ip6addr), (type)))

Does the given IPv6 address have a scope, and as such should also have a zone to be meaningful, but does not actually have a zone? (0/1)

## ip6_addr_select_zone

#define ip6_addr_select_zone | ( |  | dest,
|  |  | src
| ) |  |

Value:
do { struct netif *selected_netif; \
selected_netif = ip6_route((src), (dest)); \
if (selected_netif != NULL) { \
ip6_addr_assign_zone((dest), IP6_UNKNOWN, selected_netif); \
} } while (0)

Try to select a zone for a scoped address that does not yet have a zone. Called from PCB bind and connect routines, for two reasons: 1) to save on this (relatively expensive) selection for every individual packet route operation and 2) to allow the application to obtain the selected zone from the PCB as is customary for e.g. getsockname/getpeername BSD socket calls.

Ideally, callers would always supply a properly zoned address, in which case this function would not be needed. It exists both for compatibility with the BSD socket API (which accepts zoneless destination addresses) and for backward compatibility with pre-scoping lwIP code.

It may be impossible to select a zone, e.g. if there are no netifs. In that case, the address's zone field will be left as is.

Parameters

  dest | the IPv6 address for which to select and set a zone.
  src | source IPv6 address (const); may be equal to dest.

## ip6_addr_set_zone

#define ip6_addr_set_zone | ( |  | ip6addr,
|  |  | zone_idx
| ) |  | ((ip6addr)->zone = (zone_idx))

Set the zone field of an IPv6 address to a particular value.

## ip6_addr_test_zone

#define ip6_addr_test_zone | ( |  | ip6addr,
|  |  | netif
| ) |  | (ip6_addr_equals_zone((ip6addr), netif_get_index(netif)))

Test whether an IPv6 address is "zone-compatible" with a network interface. That is, test whether the network interface is part of the zone associated with the address. For efficiency, this macro is only ever called if the given address is either scoped or zoned, and thus, it need not test this. If an address is scoped but not zoned, or zoned and not scoped, it is considered not zone-compatible with any netif.

This default implementation follows the default model of RFC 4007, where only interface-local and link-local scopes are defined, and the zone index of both of those scopes always equals the index of the network interface. As such, there is always only one matching netif for a specific zone index, but all call sites of this macro currently support multiple matching netifs as well (at no additional expense in the common case).

Parameters

  ip6addr | the IPv6 address (const).
  netif | the network interface (const).

Returns
  1 if the address is scope-compatible with the netif, 0 if not.

## ip6_addr_zone

#define ip6_addr_zone | ( |  | ip6addr | ) | ((ip6addr)->zone)

Return the zone index of the given IPv6 address; possibly "no zone".

## ip6_addr_zone_eq

#define ip6_addr_zone_eq | ( |  | ip6addr1,
|  |  | ip6addr2
| ) |  | ((ip6addr1)->zone == (ip6addr2)->zone)

Are the zone fields of the given IPv6 addresses equal? (0/1) This macro must only be used on IPv6 addresses of the same scope.

## IP6_NO_ZONE

#define IP6_NO_ZONE 0

Identifier for "no zone".

## IPADDR6_ZONE_INIT

#define IPADDR6_ZONE_INIT , IP6_NO_ZONE

Zone initializer for static IPv6 address initialization, including comma.

## IPV6_CUSTOM_SCOPES

#define IPV6_CUSTOM_SCOPES 0

IPV6_CUSTOM_SCOPES: together, the following three macro definitions, ip6_addr_has_scope, ip6_addr_assign_zone, and ip6_addr_test_zone, completely define the lwIP scoping policy. The definitions below implement the default policy from RFC 4007 Sec. 6. Should an implementation desire to implement a different policy, it can define IPV6_CUSTOM_SCOPES to 1 and supply its own definitions for the three macros instead.

## Enumeration Type Documentation

## lwip_ipv6_scope_type

enum lwip_ipv6_scope_type

Symbolic constants for the 'type' parameters in some of the macros. These exist for efficiency only, allowing the macros to avoid certain tests when the address is known not to be of a certain type. Dead code elimination will do the rest. IP6_MULTICAST is supported but currently not optimized.

See also
  ip6_addr_has_scope, ip6_addr_assign_zone, ip6_addr_lacks_zone.

Enumerator
IP6_UNKNOWN | Unknown
IP6_UNICAST | Unicast
IP6_MULTICAST | Multicast

IP6_UNICAST
@ IP6_UNICAST
Definition: ip6_zone.h:143
ip6_addr_set_zone
#define ip6_addr_set_zone(ip6addr, zone_idx)
Definition: ip6_zone.h:115
netif
Definition: netif.h:269
ip6_route
struct netif * ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
Definition: ip6.c:86
IP6_UNKNOWN
@ IP6_UNKNOWN
Definition: ip6_zone.h:141
ip6_addr_has_scope
#define ip6_addr_has_scope(ip6addr, type)
Definition: ip6_zone.h:179