|  | @@ -41,6 +41,38 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
		
	
		
			
			| 41 | 41 |  /** Define inline IPv6 address */
 | 
		
	
		
			
			| 42 | 42 |  #define IPV6(...) { __VA_ARGS__ }
 | 
		
	
		
			
			| 43 | 43 |  
 | 
		
	
		
			
			|  | 44 | +/** An IPv6 test routing table entry */
 | 
		
	
		
			
			|  | 45 | +struct ipv6_test_route {
 | 
		
	
		
			
			|  | 46 | +	/** Local address */
 | 
		
	
		
			
			|  | 47 | +	const char *address;
 | 
		
	
		
			
			|  | 48 | +	/** Prefix length */
 | 
		
	
		
			
			|  | 49 | +	unsigned int prefix_len;
 | 
		
	
		
			
			|  | 50 | +	/** Router address (if any) */
 | 
		
	
		
			
			|  | 51 | +	const char *router;
 | 
		
	
		
			
			|  | 52 | +};
 | 
		
	
		
			
			|  | 53 | +
 | 
		
	
		
			
			|  | 54 | +/** An IPv6 test routing table */
 | 
		
	
		
			
			|  | 55 | +struct ipv6_test_table {
 | 
		
	
		
			
			|  | 56 | +	/** Test routing table entries */
 | 
		
	
		
			
			|  | 57 | +	const struct ipv6_test_route *routes;
 | 
		
	
		
			
			|  | 58 | +	/** Number of table entries */
 | 
		
	
		
			
			|  | 59 | +	unsigned int count;
 | 
		
	
		
			
			|  | 60 | +	/** Constructed routing table */
 | 
		
	
		
			
			|  | 61 | +	struct list_head list;
 | 
		
	
		
			
			|  | 62 | +};
 | 
		
	
		
			
			|  | 63 | +
 | 
		
	
		
			
			|  | 64 | +/** Define a test routing table */
 | 
		
	
		
			
			|  | 65 | +#define TABLE( name, ... )						\
 | 
		
	
		
			
			|  | 66 | +	static const struct ipv6_test_route name ## _routes[] = {	\
 | 
		
	
		
			
			|  | 67 | +		__VA_ARGS__						\
 | 
		
	
		
			
			|  | 68 | +	};								\
 | 
		
	
		
			
			|  | 69 | +	static struct ipv6_test_table name = {				\
 | 
		
	
		
			
			|  | 70 | +		.routes = name ## _routes,				\
 | 
		
	
		
			
			|  | 71 | +		.count = ( sizeof ( name ## _routes ) /			\
 | 
		
	
		
			
			|  | 72 | +			   sizeof ( name ## _routes[0] ) ),		\
 | 
		
	
		
			
			|  | 73 | +		.list = LIST_HEAD_INIT ( name.list ),			\
 | 
		
	
		
			
			|  | 74 | +	};
 | 
		
	
		
			
			|  | 75 | +
 | 
		
	
		
			
			| 44 | 76 |  /** The unspecified IPv6 address */
 | 
		
	
		
			
			| 45 | 77 |  static const struct in6_addr sample_unspecified = {
 | 
		
	
		
			
			| 46 | 78 |  	.s6_addr = IPV6 ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
		
	
	
		
			
			|  | @@ -53,6 +85,18 @@ static const struct in6_addr sample_link_local = {
 | 
		
	
		
			
			| 53 | 85 |  			  0x00, 0x00, 0x69, 0xff, 0xfe, 0x50, 0x58, 0x45 ),
 | 
		
	
		
			
			| 54 | 86 |  };
 | 
		
	
		
			
			| 55 | 87 |  
 | 
		
	
		
			
			|  | 88 | +/** A sample site-local IPv6 address */
 | 
		
	
		
			
			|  | 89 | +static const struct in6_addr sample_site_local = {
 | 
		
	
		
			
			|  | 90 | +	.s6_addr = IPV6 ( 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
		
	
		
			
			|  | 91 | +			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 ),
 | 
		
	
		
			
			|  | 92 | +};
 | 
		
	
		
			
			|  | 93 | +
 | 
		
	
		
			
			|  | 94 | +/** A sample ULA IPv6 address */
 | 
		
	
		
			
			|  | 95 | +static const struct in6_addr sample_ula = {
 | 
		
	
		
			
			|  | 96 | +	.s6_addr = IPV6 ( 0xfd, 0x44, 0x91, 0x12, 0x64, 0x42, 0x00, 0x00,
 | 
		
	
		
			
			|  | 97 | +			  0x00, 0x00, 0x69, 0xff, 0xfe, 0x50, 0x58, 0x45 ),
 | 
		
	
		
			
			|  | 98 | +};
 | 
		
	
		
			
			|  | 99 | +
 | 
		
	
		
			
			| 56 | 100 |  /** A sample global IPv6 address */
 | 
		
	
		
			
			| 57 | 101 |  static const struct in6_addr sample_global = {
 | 
		
	
		
			
			| 58 | 102 |  	.s6_addr = IPV6 ( 0x20, 0x01, 0x0b, 0xa8, 0x00, 0x00, 0x01, 0xd4,
 | 
		
	
	
		
			
			|  | @@ -65,6 +109,31 @@ static const struct in6_addr sample_multicast = {
 | 
		
	
		
			
			| 65 | 109 |  			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ),
 | 
		
	
		
			
			| 66 | 110 |  };
 | 
		
	
		
			
			| 67 | 111 |  
 | 
		
	
		
			
			|  | 112 | +/** Dummy network device used for routing tests */
 | 
		
	
		
			
			|  | 113 | +static struct net_device ipv6_test_netdev = {
 | 
		
	
		
			
			|  | 114 | +	.refcnt = REF_INIT ( ref_no_free ),
 | 
		
	
		
			
			|  | 115 | +	.index = 42,
 | 
		
	
		
			
			|  | 116 | +	.state = NETDEV_OPEN,
 | 
		
	
		
			
			|  | 117 | +};
 | 
		
	
		
			
			|  | 118 | +
 | 
		
	
		
			
			|  | 119 | +/** Routing table with only a link-local address */
 | 
		
	
		
			
			|  | 120 | +TABLE ( table_link_local,
 | 
		
	
		
			
			|  | 121 | +	{ "fe80::69ff:fe50:5845", 64, NULL } );
 | 
		
	
		
			
			|  | 122 | +
 | 
		
	
		
			
			|  | 123 | +/** Routing table with a global address */
 | 
		
	
		
			
			|  | 124 | +TABLE ( table_normal,
 | 
		
	
		
			
			|  | 125 | +	{ "fe80::69ff:fe50:5845", 64, NULL },
 | 
		
	
		
			
			|  | 126 | +	{ "2001:db8:3::1", 64, "fe80::1" } );
 | 
		
	
		
			
			|  | 127 | +
 | 
		
	
		
			
			|  | 128 | +/** Routing table with multiple addresses and routers */
 | 
		
	
		
			
			|  | 129 | +TABLE ( table_multi,
 | 
		
	
		
			
			|  | 130 | +	{ "fe80::69ff:fe50:5845", 64, NULL },
 | 
		
	
		
			
			|  | 131 | +	{ "2001:db8:3::1", 64, "fe80::1" },
 | 
		
	
		
			
			|  | 132 | +	{ "2001:db8:5::1", 64, NULL },
 | 
		
	
		
			
			|  | 133 | +	{ "2001:db8:42::1", 64, "fe80::2" },
 | 
		
	
		
			
			|  | 134 | +	{ "fd44:9112:6442::69ff:fe50:5845", 64, "fe80::1" },
 | 
		
	
		
			
			|  | 135 | +	{ "fd70:6ba9:50ae::69ff:fe50:5845", 64, "fe80::3" } );
 | 
		
	
		
			
			|  | 136 | +
 | 
		
	
		
			
			| 68 | 137 |  /**
 | 
		
	
		
			
			| 69 | 138 |   * Report an inet6_ntoa() test result
 | 
		
	
		
			
			| 70 | 139 |   *
 | 
		
	
	
		
			
			|  | @@ -133,6 +202,148 @@ static void inet6_aton_fail_okx ( const char *text, const char *file,
 | 
		
	
		
			
			| 133 | 202 |  #define inet6_aton_fail_ok( text )					\
 | 
		
	
		
			
			| 134 | 203 |  	inet6_aton_fail_okx ( text, __FILE__, __LINE__ )
 | 
		
	
		
			
			| 135 | 204 |  
 | 
		
	
		
			
			|  | 205 | +/**
 | 
		
	
		
			
			|  | 206 | + * Create test routing table
 | 
		
	
		
			
			|  | 207 | + *
 | 
		
	
		
			
			|  | 208 | + * @v table		Test routing table
 | 
		
	
		
			
			|  | 209 | + * @v file		Test code file
 | 
		
	
		
			
			|  | 210 | + * @v line		Test code line
 | 
		
	
		
			
			|  | 211 | + */
 | 
		
	
		
			
			|  | 212 | +static void ipv6_table_okx ( struct ipv6_test_table *table, const char *file,
 | 
		
	
		
			
			|  | 213 | +			     unsigned int line ) {
 | 
		
	
		
			
			|  | 214 | +	const struct ipv6_test_route *route;
 | 
		
	
		
			
			|  | 215 | +	struct in6_addr address;
 | 
		
	
		
			
			|  | 216 | +	struct in6_addr router;
 | 
		
	
		
			
			|  | 217 | +	struct list_head saved;
 | 
		
	
		
			
			|  | 218 | +	unsigned int i;
 | 
		
	
		
			
			|  | 219 | +
 | 
		
	
		
			
			|  | 220 | +	/* Sanity check */
 | 
		
	
		
			
			|  | 221 | +	okx ( list_empty ( &table->list ), file, line );
 | 
		
	
		
			
			|  | 222 | +
 | 
		
	
		
			
			|  | 223 | +	/* Save existing routing table */
 | 
		
	
		
			
			|  | 224 | +	INIT_LIST_HEAD ( &saved );
 | 
		
	
		
			
			|  | 225 | +	list_splice_init ( &ipv6_miniroutes, &saved );
 | 
		
	
		
			
			|  | 226 | +
 | 
		
	
		
			
			|  | 227 | +	/* Construct routing table */
 | 
		
	
		
			
			|  | 228 | +	for ( i = 0 ; i < table->count ; i++ ) {
 | 
		
	
		
			
			|  | 229 | +
 | 
		
	
		
			
			|  | 230 | +		/* Parse address and router (if applicable) */
 | 
		
	
		
			
			|  | 231 | +		route = &table->routes[i];
 | 
		
	
		
			
			|  | 232 | +		okx ( inet6_aton ( route->address, &address ) == 0,
 | 
		
	
		
			
			|  | 233 | +		      file, line );
 | 
		
	
		
			
			|  | 234 | +		if ( route->router ) {
 | 
		
	
		
			
			|  | 235 | +			okx ( inet6_aton ( route->router, &router ) == 0,
 | 
		
	
		
			
			|  | 236 | +			      file, line );
 | 
		
	
		
			
			|  | 237 | +		}
 | 
		
	
		
			
			|  | 238 | +
 | 
		
	
		
			
			|  | 239 | +		/* Add routing table entry */
 | 
		
	
		
			
			|  | 240 | +		okx ( ipv6_add_miniroute ( &ipv6_test_netdev, &address,
 | 
		
	
		
			
			|  | 241 | +					   route->prefix_len,
 | 
		
	
		
			
			|  | 242 | +					   ( route->router ?
 | 
		
	
		
			
			|  | 243 | +					     &router : NULL ) ) == 0,
 | 
		
	
		
			
			|  | 244 | +		      file, line );
 | 
		
	
		
			
			|  | 245 | +	}
 | 
		
	
		
			
			|  | 246 | +
 | 
		
	
		
			
			|  | 247 | +	/* Save constructed routing table */
 | 
		
	
		
			
			|  | 248 | +	list_splice_init ( &ipv6_miniroutes, &table->list );
 | 
		
	
		
			
			|  | 249 | +
 | 
		
	
		
			
			|  | 250 | +	/* Restore original routing table */
 | 
		
	
		
			
			|  | 251 | +	list_splice ( &saved, &ipv6_miniroutes );
 | 
		
	
		
			
			|  | 252 | +}
 | 
		
	
		
			
			|  | 253 | +#define ipv6_table_ok( table )						\
 | 
		
	
		
			
			|  | 254 | +	ipv6_table_okx ( table, __FILE__, __LINE__ )
 | 
		
	
		
			
			|  | 255 | +
 | 
		
	
		
			
			|  | 256 | +/**
 | 
		
	
		
			
			|  | 257 | + * Report an ipv6_route() test result
 | 
		
	
		
			
			|  | 258 | + *
 | 
		
	
		
			
			|  | 259 | + * @v table		Test routing table
 | 
		
	
		
			
			|  | 260 | + * @v dest		Destination address
 | 
		
	
		
			
			|  | 261 | + * @v src		Expected source address, or NULL to expect failure
 | 
		
	
		
			
			|  | 262 | + * @v next		Expected next hop address, or NULL to expect destination
 | 
		
	
		
			
			|  | 263 | + * @v file		Test code file
 | 
		
	
		
			
			|  | 264 | + * @v line		Test code line
 | 
		
	
		
			
			|  | 265 | + */
 | 
		
	
		
			
			|  | 266 | +static void ipv6_route_okx ( struct ipv6_test_table *table, const char *dest,
 | 
		
	
		
			
			|  | 267 | +			     const char *src, const char *next,
 | 
		
	
		
			
			|  | 268 | +			     const char *file, unsigned int line ) {
 | 
		
	
		
			
			|  | 269 | +	struct in6_addr in_dest;
 | 
		
	
		
			
			|  | 270 | +	struct in6_addr in_src;
 | 
		
	
		
			
			|  | 271 | +	struct in6_addr in_next;
 | 
		
	
		
			
			|  | 272 | +	struct in6_addr *actual;
 | 
		
	
		
			
			|  | 273 | +	struct ipv6_miniroute *miniroute;
 | 
		
	
		
			
			|  | 274 | +	struct list_head saved;
 | 
		
	
		
			
			|  | 275 | +
 | 
		
	
		
			
			|  | 276 | +	/* Switch to test routing table */
 | 
		
	
		
			
			|  | 277 | +	INIT_LIST_HEAD ( &saved );
 | 
		
	
		
			
			|  | 278 | +	list_splice_init ( &ipv6_miniroutes, &saved );
 | 
		
	
		
			
			|  | 279 | +	list_splice_init ( &table->list, &ipv6_miniroutes );
 | 
		
	
		
			
			|  | 280 | +
 | 
		
	
		
			
			|  | 281 | +	/* Parse addresses */
 | 
		
	
		
			
			|  | 282 | +	okx ( inet6_aton ( dest, &in_dest ) == 0, file, line );
 | 
		
	
		
			
			|  | 283 | +	if ( src )
 | 
		
	
		
			
			|  | 284 | +		okx ( inet6_aton ( src, &in_src ) == 0, file, line );
 | 
		
	
		
			
			|  | 285 | +	if ( next ) {
 | 
		
	
		
			
			|  | 286 | +		okx ( inet6_aton ( next, &in_next ) == 0, file, line );
 | 
		
	
		
			
			|  | 287 | +	} else {
 | 
		
	
		
			
			|  | 288 | +		memcpy ( &in_next, &in_dest, sizeof ( in_next ) );
 | 
		
	
		
			
			|  | 289 | +	}
 | 
		
	
		
			
			|  | 290 | +
 | 
		
	
		
			
			|  | 291 | +	/* Perform routing */
 | 
		
	
		
			
			|  | 292 | +	actual = &in_dest;
 | 
		
	
		
			
			|  | 293 | +	miniroute = ipv6_route ( ipv6_test_netdev.index, &actual );
 | 
		
	
		
			
			|  | 294 | +
 | 
		
	
		
			
			|  | 295 | +	/* Validate result */
 | 
		
	
		
			
			|  | 296 | +	if ( src ) {
 | 
		
	
		
			
			|  | 297 | +
 | 
		
	
		
			
			|  | 298 | +		/* Check that a route was found */
 | 
		
	
		
			
			|  | 299 | +		okx ( miniroute != NULL, file, line );
 | 
		
	
		
			
			|  | 300 | +		DBG ( "ipv6_route ( %s ) = %s", dest, inet6_ntoa ( actual ) );
 | 
		
	
		
			
			|  | 301 | +		DBG ( " from %s\n", inet6_ntoa ( &miniroute->address ) );
 | 
		
	
		
			
			|  | 302 | +
 | 
		
	
		
			
			|  | 303 | +		/* Check that expected source address was used */
 | 
		
	
		
			
			|  | 304 | +		okx ( memcmp ( &miniroute->address, &in_src,
 | 
		
	
		
			
			|  | 305 | +			       sizeof ( in_src ) ) == 0, file, line );
 | 
		
	
		
			
			|  | 306 | +
 | 
		
	
		
			
			|  | 307 | +		/* Check that expected next hop address was used */
 | 
		
	
		
			
			|  | 308 | +		okx ( memcmp ( actual, &in_next, sizeof ( *actual ) ) == 0,
 | 
		
	
		
			
			|  | 309 | +		      file, line );
 | 
		
	
		
			
			|  | 310 | +
 | 
		
	
		
			
			|  | 311 | +	} else {
 | 
		
	
		
			
			|  | 312 | +
 | 
		
	
		
			
			|  | 313 | +		/* Routing is expected to fail */
 | 
		
	
		
			
			|  | 314 | +		okx ( miniroute == NULL, file, line );
 | 
		
	
		
			
			|  | 315 | +	}
 | 
		
	
		
			
			|  | 316 | +
 | 
		
	
		
			
			|  | 317 | +	/* Restore original routing table */
 | 
		
	
		
			
			|  | 318 | +	list_splice_init ( &ipv6_miniroutes, &table->list );
 | 
		
	
		
			
			|  | 319 | +	list_splice ( &saved, &ipv6_miniroutes );
 | 
		
	
		
			
			|  | 320 | +}
 | 
		
	
		
			
			|  | 321 | +#define ipv6_route_ok( table, dest, src, next )				\
 | 
		
	
		
			
			|  | 322 | +	ipv6_route_okx ( table, dest, src, next, __FILE__, __LINE__ )
 | 
		
	
		
			
			|  | 323 | +
 | 
		
	
		
			
			|  | 324 | +/**
 | 
		
	
		
			
			|  | 325 | + * Destroy test routing table
 | 
		
	
		
			
			|  | 326 | + *
 | 
		
	
		
			
			|  | 327 | + * @v table		Test routing table
 | 
		
	
		
			
			|  | 328 | + */
 | 
		
	
		
			
			|  | 329 | +static void ipv6_table_del ( struct ipv6_test_table *table ) {
 | 
		
	
		
			
			|  | 330 | +	struct ipv6_miniroute *miniroute;
 | 
		
	
		
			
			|  | 331 | +	struct ipv6_miniroute *tmp;
 | 
		
	
		
			
			|  | 332 | +	struct list_head saved;
 | 
		
	
		
			
			|  | 333 | +
 | 
		
	
		
			
			|  | 334 | +	/* Switch to test routing table */
 | 
		
	
		
			
			|  | 335 | +	INIT_LIST_HEAD ( &saved );
 | 
		
	
		
			
			|  | 336 | +	list_splice_init ( &ipv6_miniroutes, &saved );
 | 
		
	
		
			
			|  | 337 | +	list_splice_init ( &table->list, &ipv6_miniroutes );
 | 
		
	
		
			
			|  | 338 | +
 | 
		
	
		
			
			|  | 339 | +	/* Delete all existing routes */
 | 
		
	
		
			
			|  | 340 | +	list_for_each_entry_safe ( miniroute, tmp, &ipv6_miniroutes, list )
 | 
		
	
		
			
			|  | 341 | +		ipv6_del_miniroute ( miniroute );
 | 
		
	
		
			
			|  | 342 | +
 | 
		
	
		
			
			|  | 343 | +	/* Restore original routing table */
 | 
		
	
		
			
			|  | 344 | +	list_splice ( &saved, &ipv6_miniroutes );
 | 
		
	
		
			
			|  | 345 | +}
 | 
		
	
		
			
			|  | 346 | +
 | 
		
	
		
			
			| 136 | 347 |  /**
 | 
		
	
		
			
			| 137 | 348 |   * Perform IPv6 self-tests
 | 
		
	
		
			
			| 138 | 349 |   *
 | 
		
	
	
		
			
			|  | @@ -142,16 +353,34 @@ static void ipv6_test_exec ( void ) {
 | 
		
	
		
			
			| 142 | 353 |  	/* Address testing macros */
 | 
		
	
		
			
			| 143 | 354 |  	ok (   IN6_IS_ADDR_UNSPECIFIED ( &sample_unspecified ) );
 | 
		
	
		
			
			| 144 | 355 |  	ok ( ! IN6_IS_ADDR_UNSPECIFIED ( &sample_link_local ) );
 | 
		
	
		
			
			|  | 356 | +	ok ( ! IN6_IS_ADDR_UNSPECIFIED ( &sample_site_local ) );
 | 
		
	
		
			
			|  | 357 | +	ok ( ! IN6_IS_ADDR_UNSPECIFIED ( &sample_ula ) );
 | 
		
	
		
			
			| 145 | 358 |  	ok ( ! IN6_IS_ADDR_UNSPECIFIED ( &sample_global ) );
 | 
		
	
		
			
			| 146 | 359 |  	ok ( ! IN6_IS_ADDR_UNSPECIFIED ( &sample_multicast ) );
 | 
		
	
		
			
			| 147 | 360 |  	ok ( ! IN6_IS_ADDR_MULTICAST ( &sample_unspecified ) );
 | 
		
	
		
			
			| 148 | 361 |  	ok ( ! IN6_IS_ADDR_MULTICAST ( &sample_link_local ) );
 | 
		
	
		
			
			|  | 362 | +	ok ( ! IN6_IS_ADDR_MULTICAST ( &sample_site_local ) );
 | 
		
	
		
			
			|  | 363 | +	ok ( ! IN6_IS_ADDR_MULTICAST ( &sample_ula ) );
 | 
		
	
		
			
			| 149 | 364 |  	ok ( ! IN6_IS_ADDR_MULTICAST ( &sample_global ) );
 | 
		
	
		
			
			| 150 | 365 |  	ok (   IN6_IS_ADDR_MULTICAST ( &sample_multicast ) );
 | 
		
	
		
			
			| 151 | 366 |  	ok ( ! IN6_IS_ADDR_LINKLOCAL ( &sample_unspecified ) );
 | 
		
	
		
			
			| 152 | 367 |  	ok (   IN6_IS_ADDR_LINKLOCAL ( &sample_link_local ) );
 | 
		
	
		
			
			|  | 368 | +	ok ( ! IN6_IS_ADDR_LINKLOCAL ( &sample_site_local ) );
 | 
		
	
		
			
			|  | 369 | +	ok ( ! IN6_IS_ADDR_LINKLOCAL ( &sample_ula ) );
 | 
		
	
		
			
			| 153 | 370 |  	ok ( ! IN6_IS_ADDR_LINKLOCAL ( &sample_global ) );
 | 
		
	
		
			
			| 154 | 371 |  	ok ( ! IN6_IS_ADDR_LINKLOCAL ( &sample_multicast ) );
 | 
		
	
		
			
			|  | 372 | +	ok ( ! IN6_IS_ADDR_SITELOCAL ( &sample_unspecified ) );
 | 
		
	
		
			
			|  | 373 | +	ok ( ! IN6_IS_ADDR_SITELOCAL ( &sample_link_local ) );
 | 
		
	
		
			
			|  | 374 | +	ok (   IN6_IS_ADDR_SITELOCAL ( &sample_site_local ) );
 | 
		
	
		
			
			|  | 375 | +	ok ( ! IN6_IS_ADDR_SITELOCAL ( &sample_ula ) );
 | 
		
	
		
			
			|  | 376 | +	ok ( ! IN6_IS_ADDR_SITELOCAL ( &sample_global ) );
 | 
		
	
		
			
			|  | 377 | +	ok ( ! IN6_IS_ADDR_SITELOCAL ( &sample_multicast ) );
 | 
		
	
		
			
			|  | 378 | +	ok ( ! IN6_IS_ADDR_ULA ( &sample_unspecified ) );
 | 
		
	
		
			
			|  | 379 | +	ok ( ! IN6_IS_ADDR_ULA ( &sample_link_local ) );
 | 
		
	
		
			
			|  | 380 | +	ok ( ! IN6_IS_ADDR_ULA ( &sample_site_local ) );
 | 
		
	
		
			
			|  | 381 | +	ok (   IN6_IS_ADDR_ULA ( &sample_ula ) );
 | 
		
	
		
			
			|  | 382 | +	ok ( ! IN6_IS_ADDR_ULA ( &sample_global ) );
 | 
		
	
		
			
			|  | 383 | +	ok ( ! IN6_IS_ADDR_ULA ( &sample_multicast ) );
 | 
		
	
		
			
			| 155 | 384 |  
 | 
		
	
		
			
			| 156 | 385 |  	/* inet6_ntoa() tests */
 | 
		
	
		
			
			| 157 | 386 |  	inet6_ntoa_ok ( IPV6 ( 0x20, 0x01, 0x0b, 0xa8, 0x00, 0x00, 0x01, 0xd4,
 | 
		
	
	
		
			
			|  | @@ -228,6 +457,58 @@ static void ipv6_test_exec ( void ) {
 | 
		
	
		
			
			| 228 | 457 |  	inet6_aton_fail_ok ( "2001:db8::1::2" );
 | 
		
	
		
			
			| 229 | 458 |  	inet6_aton_fail_ok ( "2001:ba8:0:1d4:::6950:5845" );
 | 
		
	
		
			
			| 230 | 459 |  	inet6_aton_fail_ok ( ":::" );
 | 
		
	
		
			
			|  | 460 | +
 | 
		
	
		
			
			|  | 461 | +	/* Create test routing tables */
 | 
		
	
		
			
			|  | 462 | +	ipv6_table_ok ( &table_link_local );
 | 
		
	
		
			
			|  | 463 | +	ipv6_table_ok ( &table_normal );
 | 
		
	
		
			
			|  | 464 | +	ipv6_table_ok ( &table_multi );
 | 
		
	
		
			
			|  | 465 | +
 | 
		
	
		
			
			|  | 466 | +	/* Routing table with only a link-local address */
 | 
		
	
		
			
			|  | 467 | +	ipv6_route_ok ( &table_link_local, "fe80::1",
 | 
		
	
		
			
			|  | 468 | +			"fe80::69ff:fe50:5845", NULL );
 | 
		
	
		
			
			|  | 469 | +	ipv6_route_ok ( &table_link_local, "2001:db8:1::1",
 | 
		
	
		
			
			|  | 470 | +			NULL, NULL );
 | 
		
	
		
			
			|  | 471 | +	ipv6_route_ok ( &table_link_local, "ff02::1",
 | 
		
	
		
			
			|  | 472 | +			"fe80::69ff:fe50:5845", NULL );
 | 
		
	
		
			
			|  | 473 | +
 | 
		
	
		
			
			|  | 474 | +	/** Routing table with a global address */
 | 
		
	
		
			
			|  | 475 | +	ipv6_route_ok ( &table_normal, "fe80::1",
 | 
		
	
		
			
			|  | 476 | +			"fe80::69ff:fe50:5845", NULL );
 | 
		
	
		
			
			|  | 477 | +	ipv6_route_ok ( &table_normal, "2001:db8:3::42",
 | 
		
	
		
			
			|  | 478 | +			"2001:db8:3::1", NULL );
 | 
		
	
		
			
			|  | 479 | +	ipv6_route_ok ( &table_normal, "2001:ba8:0:1d4::6950:5845",
 | 
		
	
		
			
			|  | 480 | +			"2001:db8:3::1", "fe80::1" );
 | 
		
	
		
			
			|  | 481 | +	ipv6_route_ok ( &table_normal, "ff02::1",
 | 
		
	
		
			
			|  | 482 | +			"fe80::69ff:fe50:5845", NULL );
 | 
		
	
		
			
			|  | 483 | +	ipv6_route_ok ( &table_normal, "ff0e::1",
 | 
		
	
		
			
			|  | 484 | +			"2001:db8:3::1", NULL );
 | 
		
	
		
			
			|  | 485 | +
 | 
		
	
		
			
			|  | 486 | +	/** Routing table with multiple addresses and routers */
 | 
		
	
		
			
			|  | 487 | +	ipv6_route_ok ( &table_multi, "fe80::1",
 | 
		
	
		
			
			|  | 488 | +			"fe80::69ff:fe50:5845", NULL );
 | 
		
	
		
			
			|  | 489 | +	ipv6_route_ok ( &table_multi, "2001:db8:3::17",
 | 
		
	
		
			
			|  | 490 | +			"2001:db8:3::1", NULL );
 | 
		
	
		
			
			|  | 491 | +	ipv6_route_ok ( &table_multi, "2001:db8:5::92",
 | 
		
	
		
			
			|  | 492 | +			"2001:db8:5::1", NULL );
 | 
		
	
		
			
			|  | 493 | +	ipv6_route_ok ( &table_multi, "2001:db8:42::17",
 | 
		
	
		
			
			|  | 494 | +			"2001:db8:42::1", NULL );
 | 
		
	
		
			
			|  | 495 | +	ipv6_route_ok ( &table_multi, "2001:db8:5:1::17",
 | 
		
	
		
			
			|  | 496 | +			"2001:db8:3::1", "fe80::1" );
 | 
		
	
		
			
			|  | 497 | +	ipv6_route_ok ( &table_multi, "fd44:9112:6442::1",
 | 
		
	
		
			
			|  | 498 | +			"fd44:9112:6442::69ff:fe50:5845", NULL );
 | 
		
	
		
			
			|  | 499 | +	ipv6_route_ok ( &table_multi, "fd70:6ba9:50ae::1",
 | 
		
	
		
			
			|  | 500 | +			"fd70:6ba9:50ae::69ff:fe50:5845", NULL );
 | 
		
	
		
			
			|  | 501 | +	ipv6_route_ok ( &table_multi, "fd40::3",
 | 
		
	
		
			
			|  | 502 | +			"fd44:9112:6442::69ff:fe50:5845", "fe80::1" );
 | 
		
	
		
			
			|  | 503 | +	ipv6_route_ok ( &table_multi, "fd70::2",
 | 
		
	
		
			
			|  | 504 | +			"fd70:6ba9:50ae::69ff:fe50:5845", "fe80::3" );
 | 
		
	
		
			
			|  | 505 | +	ipv6_route_ok ( &table_multi, "ff02::1",
 | 
		
	
		
			
			|  | 506 | +			"fe80::69ff:fe50:5845", NULL );
 | 
		
	
		
			
			|  | 507 | +
 | 
		
	
		
			
			|  | 508 | +	/* Destroy test routing tables */
 | 
		
	
		
			
			|  | 509 | +	ipv6_table_del ( &table_link_local );
 | 
		
	
		
			
			|  | 510 | +	ipv6_table_del ( &table_normal );
 | 
		
	
		
			
			|  | 511 | +	ipv6_table_del ( &table_multi );
 | 
		
	
		
			
			| 231 | 512 |  }
 | 
		
	
		
			
			| 232 | 513 |  
 | 
		
	
		
			
			| 233 | 514 |  /** IPv6 self-test */
 |