addr->s6_addr[15] = 2;
}
+/** IPv6 settings sibling order */
+enum ipv6_settings_order {
+ /** No address */
+ IPV6_ORDER_PREFIX_ONLY = -4,
+ /** Link-local address */
+ IPV6_ORDER_LINK_LOCAL = -3,
+ /** Address assigned via SLAAC */
+ IPV6_ORDER_SLAAC = -2,
+ /** Address assigned via DHCPv6 */
+ IPV6_ORDER_DHCPV6 = -1,
+};
+
/** IPv6 link-local address settings block name */
#define IPV6_SETTINGS_NAME "link"
ref_init ( &ipv6set->refcnt, NULL );
settings_init ( &ipv6set->settings, &ipv6_settings_operations,
&ipv6set->refcnt, &ipv6_scope );
+ ipv6set->settings.order = IPV6_ORDER_LINK_LOCAL;
/* Register settings */
if ( ( rc = register_settings ( &ipv6set->settings, parent,
size_t option_len;
unsigned int prefixes;
unsigned int instance;
+ int order;
int rc;
/* Count number of prefix options. We can assume that the
* options are well-formed, otherwise they would have been
* rejected prior to being stored.
*/
+ order = IPV6_ORDER_PREFIX_ONLY;
for ( prefixes = 0, offset = 0 ; offset < len ; offset += option_len ) {
+
+ /* Skip non-prefix options */
option = ( ( ( void * ) options ) + offset );
option_len = ( option->header.blocks * NDP_OPTION_BLKSZ );
- if ( option->header.type == NDP_OPT_PREFIX )
- prefixes++;
+ if ( option->header.type != NDP_OPT_PREFIX )
+ continue;
+
+ /* Count number of prefixes */
+ prefixes++;
+
+ /* Increase overall order if we have SLAAC addresses */
+ if ( option->prefix.flags & NDP_PREFIX_AUTONOMOUS )
+ order = IPV6_ORDER_SLAAC;
}
/* Allocate and initialise structure */
ref_init ( &ndpset->refcnt, NULL );
settings_init ( &ndpset->settings, &ndp_settings_operations,
&ndpset->refcnt, &ndp_settings_scope );
+ ndpset->settings.order = order;
memcpy ( &ndpset->router, router, sizeof ( ndpset->router ) );
ndpset->lifetime = lifetime;
ndpset->len = len;
settings_init ( &prefset->settings,
&ndp_prefix_settings_operations,
&ndpset->refcnt, &ndp_settings_scope );
+ prefset->settings.order =
+ ( ( option->prefix.flags & NDP_PREFIX_AUTONOMOUS ) ?
+ IPV6_ORDER_SLAAC : IPV6_ORDER_PREFIX_ONLY );
prefset->prefix = &option->prefix;
snprintf ( prefset->name, sizeof ( prefset->name ), "%d",
instance++ );
ref_init ( &dhcpv6set->refcnt, NULL );
settings_init ( &dhcpv6set->settings, &dhcpv6_settings_operations,
&dhcpv6set->refcnt, &dhcpv6_scope );
+ dhcpv6set->settings.order = IPV6_ORDER_DHCPV6;
data = ( ( ( void * ) dhcpv6set ) + sizeof ( *dhcpv6set ) );
len = options->len;
memcpy ( data, options->data, len );