iPXE
ipv6_test.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * IPv6 tests
29  *
30  */
31 
32 /* Forcibly enable assertions */
33 #undef NDEBUG
34 
35 #include <stdint.h>
36 #include <string.h>
37 #include <byteswap.h>
38 #include <ipxe/ipv6.h>
39 #include <ipxe/test.h>
40 
41 /** Define inline IPv6 address */
42 #define IPV6(...) { __VA_ARGS__ }
43 
44 /** An IPv6 test prefix */
46  /** Prefix length */
47  unsigned int len;
48  /** Prefix mask */
49  const char *mask;
50 };
51 
52 /** An IPv6 test routing table entry */
54  /** Local address */
55  const char *address;
56  /** Prefix */
57  const struct ipv6_test_prefix *prefix;
58  /** Router address (if any) */
59  const char *router;
60 };
61 
62 /** An IPv6 test routing table */
64  /** Test routing table entries */
65  const struct ipv6_test_route *routes;
66  /** Number of table entries */
67  unsigned int count;
68  /** Constructed routing table */
69  struct list_head list;
70 };
71 
72 /** Define a test prefix */
73 #define PREFIX( name, LEN, MASK ) \
74  static const struct ipv6_test_prefix name = { \
75  .len = LEN, \
76  .mask = MASK, \
77  };
78 
79 /** Define a test routing table */
80 #define TABLE( name, ... ) \
81  static const struct ipv6_test_route name ## _routes[] = { \
82  __VA_ARGS__ \
83  }; \
84  static struct ipv6_test_table name = { \
85  .routes = name ## _routes, \
86  .count = ( sizeof ( name ## _routes ) / \
87  sizeof ( name ## _routes[0] ) ), \
88  .list = LIST_HEAD_INIT ( name.list ), \
89  };
90 
91 /** The unspecified IPv6 address */
92 static const struct in6_addr sample_unspecified = {
93  .s6_addr = IPV6 ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
95 };
96 
97 /** A sample link-local IPv6 address */
98 static const struct in6_addr sample_link_local = {
99  .s6_addr = IPV6 ( 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100  0x00, 0x00, 0x69, 0xff, 0xfe, 0x50, 0x58, 0x45 ),
101 };
102 
103 /** A sample site-local IPv6 address */
104 static const struct in6_addr sample_site_local = {
105  .s6_addr = IPV6 ( 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 ),
107 };
108 
109 /** A sample ULA IPv6 address */
110 static const struct in6_addr sample_ula = {
111  .s6_addr = IPV6 ( 0xfd, 0x44, 0x91, 0x12, 0x64, 0x42, 0x00, 0x00,
112  0x00, 0x00, 0x69, 0xff, 0xfe, 0x50, 0x58, 0x45 ),
113 };
114 
115 /** A sample global IPv6 address */
116 static const struct in6_addr sample_global = {
117  .s6_addr = IPV6 ( 0x20, 0x01, 0x0b, 0xa8, 0x00, 0x00, 0x01, 0xd4,
118  0x00, 0x00, 0x00, 0x00, 0x69, 0x50, 0x58, 0x45 ),
119 };
120 
121 /** A sample multicast IPv6 address */
122 static const struct in6_addr sample_multicast = {
123  .s6_addr = IPV6 ( 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ),
125 };
126 
127 /** Dummy network device used for routing tests */
128 static struct net_device ipv6_test_netdev = {
129  .refcnt = REF_INIT ( ref_no_free ),
130  .scope_id = 42,
131  .state = NETDEV_OPEN,
132 };
133 
134 /** /48 prefix */
135 PREFIX ( prefix48, 48, "ffff:ffff:ffff::" );
136 
137 /** /64 prefix */
138 PREFIX ( prefix64, 64, "ffff:ffff:ffff:ffff::" );
139 
140 /** /126 prefix */
141 PREFIX ( prefix126, 126, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc" );
142 
143 /** /127 prefix */
144 PREFIX ( prefix127, 127, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe" );
145 
146 /** /128 prefix */
147 PREFIX ( prefix128, 128, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" );
148 
149 /** Routing table with only a link-local address */
150 TABLE ( table_link_local,
151  { "fe80::69ff:fe50:5845", &prefix64, NULL } );
152 
153 /** Routing table with a global address */
154 TABLE ( table_normal,
155  { "fe80::69ff:fe50:5845", &prefix64, NULL },
156  { "2001:db8:3::1", &prefix64, "fe80::1" } );
157 
158 /** Routing table with multiple addresses and routers */
159 TABLE ( table_multi,
160  { "fe80::69ff:fe50:5845", &prefix64, NULL },
161  { "2001:db8:3::1", &prefix64, "fe80::1" },
162  { "2001:db8:5::1", &prefix64, NULL },
163  { "2001:db8:42::1", &prefix64, "fe80::2" },
164  { "fd44:9112:6442::69ff:fe50:5845", &prefix64, "fe80::1" },
165  { "fd70:6ba9:50ae::69ff:fe50:5845", &prefix64, "fe80::3" } );
166 
167 /** Routing table with unusual prefix lengths */
168 TABLE ( table_unusual,
169  { "2001:db8:1::1", &prefix48, "fe80::1" },
170  { "2001:db8:2::1", &prefix126, NULL },
171  { "2001:db8:3::1", &prefix127, NULL },
172  { "2001:db8:4::1", &prefix128, NULL } );
173 
174 /**
175  * Report an inet6_ntoa() test result
176  *
177  * @v addr IPv6 address
178  * @v text Expected textual representation
179  * @v file Test code file
180  * @v line Test code line
181  */
182 static void inet6_ntoa_okx ( const struct in6_addr *addr, const char *text,
183  const char *file, unsigned int line ) {
184  char *actual;
185 
186  actual = inet6_ntoa ( addr );
187  DBG ( "inet6_ntoa ( %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ) "
188  "= %s\n", ntohs ( addr->s6_addr16[0] ),
189  ntohs ( addr->s6_addr16[1] ), ntohs ( addr->s6_addr16[2] ),
190  ntohs ( addr->s6_addr16[3] ), ntohs ( addr->s6_addr16[4] ),
191  ntohs ( addr->s6_addr16[5] ), ntohs ( addr->s6_addr16[6] ),
192  ntohs ( addr->s6_addr16[7] ), actual );
193  okx ( strcmp ( actual, text ) == 0, file, line );
194 }
195 #define inet6_ntoa_ok( addr, text ) do { \
196  static const struct in6_addr in = { \
197  .s6_addr = addr, \
198  }; \
199  inet6_ntoa_okx ( &in, text, __FILE__, __LINE__ ); \
200  } while ( 0 )
201 
202 /**
203  * Report an inet6_aton() test result
204  *
205  * @v text Textual representation
206  * @v addr Expected IPv6 address
207  * @v file Test code file
208  * @v line Test code line
209  */
210 static void inet6_aton_okx ( const char *text, const struct in6_addr *addr,
211  const char *file, unsigned int line ) {
212  struct in6_addr actual;
213 
214  okx ( inet6_aton ( text, &actual ) == 0, file, line );
215  DBG ( "inet6_aton ( \"%s\" ) = %s\n", text, inet6_ntoa ( &actual ) );
216  okx ( memcmp ( &actual, addr, sizeof ( actual ) ) == 0,
217  file, line );
218 }
219 #define inet6_aton_ok( text, addr ) do { \
220  static const struct in6_addr in = { \
221  .s6_addr = addr, \
222  }; \
223  inet6_aton_okx ( text, &in, __FILE__, __LINE__ ); \
224  } while ( 0 )
225 
226 /**
227  * Report an inet6_aton() failure test result
228  *
229  * @v text Textual representation
230  * @v file Test code file
231  * @v line Test code line
232  */
233 static void inet6_aton_fail_okx ( const char *text, const char *file,
234  unsigned int line ) {
235  struct in6_addr dummy;
236 
237  okx ( inet6_aton ( text, &dummy ) != 0, file, line );
238 }
239 #define inet6_aton_fail_ok( text ) \
240  inet6_aton_fail_okx ( text, __FILE__, __LINE__ )
241 
242 /**
243  * Create test routing table
244  *
245  * @v table Test routing table
246  * @v file Test code file
247  * @v line Test code line
248  */
249 static void ipv6_table_okx ( struct ipv6_test_table *table, const char *file,
250  unsigned int line ) {
251  const struct ipv6_test_route *route;
252  struct ipv6_miniroute *miniroute;
253  struct in6_addr address;
254  struct in6_addr router;
255  struct in6_addr mask;
256  struct list_head saved;
257  unsigned int i;
258 
259  /* Sanity check */
260  okx ( list_empty ( &table->list ), file, line );
261 
262  /* Save existing routing table */
263  INIT_LIST_HEAD ( &saved );
264  list_splice_init ( &ipv6_miniroutes, &saved );
265 
266  /* Construct routing table */
267  for ( i = 0 ; i < table->count ; i++ ) {
268 
269  /* Parse address and router (if applicable) */
270  route = &table->routes[i];
271  okx ( inet6_aton ( route->address, &address ) == 0,
272  file, line );
273  if ( route->router ) {
274  okx ( inet6_aton ( route->router, &router ) == 0,
275  file, line );
276  }
277  okx ( inet6_aton ( route->prefix->mask, &mask ) == 0,
278  file, line );
279 
280  /* Add routing table entry */
282  route->prefix->len,
283  ( route->router ?
284  &router : NULL ) ) == 0,
285  file, line );
286 
287  /* Check routing table entry */
288  miniroute = list_first_entry ( &ipv6_miniroutes,
289  struct ipv6_miniroute, list );
290  okx ( miniroute != NULL, file, line );
291  okx ( memcmp ( &miniroute->address, &address,
292  sizeof ( address ) ) == 0, file, line );
293  okx ( miniroute->prefix_len == route->prefix->len,
294  file, line );
295  okx ( memcmp ( &miniroute->prefix_mask, &mask,
296  sizeof ( mask ) ) == 0, file, line );
297  if ( route->router ) {
298  okx ( memcmp ( &miniroute->router, &router,
299  sizeof ( router ) ) == 0, file, line );
300  } else {
301  okx ( IN6_IS_ADDR_UNSPECIFIED ( &miniroute->router ),
302  file, line );
303  }
304  }
305 
306  /* Save constructed routing table */
307  list_splice_init ( &ipv6_miniroutes, &table->list );
308 
309  /* Restore original routing table */
310  list_splice ( &saved, &ipv6_miniroutes );
311 }
312 #define ipv6_table_ok( table ) \
313  ipv6_table_okx ( table, __FILE__, __LINE__ )
314 
315 /**
316  * Report an ipv6_route() test result
317  *
318  * @v table Test routing table
319  * @v dest Destination address
320  * @v src Expected source address, or NULL to expect failure
321  * @v next Expected next hop address, or NULL to expect destination
322  * @v file Test code file
323  * @v line Test code line
324  */
325 static void ipv6_route_okx ( struct ipv6_test_table *table, const char *dest,
326  const char *src, const char *next,
327  const char *file, unsigned int line ) {
328  struct in6_addr in_dest;
329  struct in6_addr in_src;
330  struct in6_addr in_next;
331  struct in6_addr *actual;
332  struct ipv6_miniroute *miniroute;
333  struct list_head saved;
334 
335  /* Switch to test routing table */
336  INIT_LIST_HEAD ( &saved );
337  list_splice_init ( &ipv6_miniroutes, &saved );
338  list_splice_init ( &table->list, &ipv6_miniroutes );
339 
340  /* Parse addresses */
341  okx ( inet6_aton ( dest, &in_dest ) == 0, file, line );
342  if ( src )
343  okx ( inet6_aton ( src, &in_src ) == 0, file, line );
344  if ( next ) {
345  okx ( inet6_aton ( next, &in_next ) == 0, file, line );
346  } else {
347  memcpy ( &in_next, &in_dest, sizeof ( in_next ) );
348  }
349 
350  /* Perform routing */
351  actual = &in_dest;
352  miniroute = ipv6_route ( ipv6_test_netdev.scope_id, &actual );
353 
354  /* Validate result */
355  if ( src ) {
356 
357  /* Check that a route was found */
358  okx ( miniroute != NULL, file, line );
359  DBG ( "ipv6_route ( %s ) = %s", dest, inet6_ntoa ( actual ) );
360  DBG ( " from %s\n", inet6_ntoa ( &miniroute->address ) );
361 
362  /* Check that expected source address was used */
363  okx ( memcmp ( &miniroute->address, &in_src,
364  sizeof ( in_src ) ) == 0, file, line );
365 
366  /* Check that expected next hop address was used */
367  okx ( memcmp ( actual, &in_next, sizeof ( *actual ) ) == 0,
368  file, line );
369 
370  } else {
371 
372  /* Routing is expected to fail */
373  okx ( miniroute == NULL, file, line );
374  }
375 
376  /* Restore original routing table */
377  list_splice_init ( &ipv6_miniroutes, &table->list );
378  list_splice ( &saved, &ipv6_miniroutes );
379 }
380 #define ipv6_route_ok( table, dest, src, next ) \
381  ipv6_route_okx ( table, dest, src, next, __FILE__, __LINE__ )
382 
383 /**
384  * Destroy test routing table
385  *
386  * @v table Test routing table
387  */
388 static void ipv6_table_del ( struct ipv6_test_table *table ) {
389  struct ipv6_miniroute *miniroute;
390  struct ipv6_miniroute *tmp;
391  struct list_head saved;
392 
393  /* Switch to test routing table */
394  INIT_LIST_HEAD ( &saved );
395  list_splice_init ( &ipv6_miniroutes, &saved );
396  list_splice_init ( &table->list, &ipv6_miniroutes );
397 
398  /* Delete all existing routes */
399  list_for_each_entry_safe ( miniroute, tmp, &ipv6_miniroutes, list )
400  ipv6_del_miniroute ( miniroute );
401 
402  /* Restore original routing table */
403  list_splice ( &saved, &ipv6_miniroutes );
404 }
405 
406 /**
407  * Perform IPv6 self-tests
408  *
409  */
410 static void ipv6_test_exec ( void ) {
411 
412  /* Address testing macros */
440  ok ( IN6_IS_ADDR_ULA ( &sample_ula ) );
441  ok ( ! IN6_IS_ADDR_ULA ( &sample_global ) );
443 
444  /* inet6_ntoa() tests */
445  inet6_ntoa_ok ( IPV6 ( 0x20, 0x01, 0x0b, 0xa8, 0x00, 0x00, 0x01, 0xd4,
446  0x00, 0x00, 0x00, 0x00, 0x69, 0x50, 0x58, 0x45 ),
447  "2001:ba8:0:1d4::6950:5845" );
448  /* No zeros */
449  inet6_ntoa_ok ( IPV6 ( 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x01,
450  0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 ),
451  "2001:db8:1:1:1:1:1:1" );
452  /* Run of zeros */
453  inet6_ntoa_ok ( IPV6 ( 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
454  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ),
455  "2001:db8::1" );
456  /* No "::" for single zero */
457  inet6_ntoa_ok ( IPV6 ( 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x01,
458  0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 ),
459  "2001:db8:0:1:1:1:1:1" );
460  /* Use "::" for longest run of zeros */
461  inet6_ntoa_ok ( IPV6 ( 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
462  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ),
463  "2001:0:0:1::1" );
464  /* Use "::" for leftmost equal-length run of zeros */
465  inet6_ntoa_ok ( IPV6 ( 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
466  0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ),
467  "2001:db8::1:0:0:1" );
468  /* Trailing run of zeros */
469  inet6_ntoa_ok ( IPV6 ( 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
471  "fe80::" );
472  /* Leading run of zeros */
473  inet6_ntoa_ok ( IPV6 ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ),
475  "::1" );
476  /* All zeros */
477  inet6_ntoa_ok ( IPV6 ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
479  "::" );
480  /* Maximum length */
481  inet6_ntoa_ok ( IPV6 ( 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
482  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ),
483  "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" );
484 
485  /* inet6_aton() tests */
486  inet6_aton_ok ( "2001:ba8:0:1d4::6950:5845",
487  IPV6 ( 0x20, 0x01, 0x0b, 0xa8, 0x00, 0x00, 0x01, 0xd4,
488  0x00, 0x00, 0x00, 0x00, 0x69, 0x50, 0x58, 0x45));
489  /* No zeros */
490  inet6_aton_ok ( "2001:db8:1:1:1:1:1:1",
491  IPV6 ( 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x01,
492  0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01));
493  /* All intervening zeros */
494  inet6_aton_ok ( "fe80::1",
495  IPV6 ( 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01));
497  /* Trailing run of zeros */
498  inet6_aton_ok ( "fe80::",
499  IPV6 ( 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
500  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
501  /* Leading run of zeros */
502  inet6_aton_ok ( "::1",
503  IPV6 ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01));
505  /* All zeros */
506  inet6_aton_ok ( "::",
507  IPV6 ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
509 
510  /* inet6_aton() failure tests */
511  inet6_aton_fail_ok ( "20012:ba8:0:1d4::6950:5845" );
512  inet6_aton_fail_ok ( "200z:ba8:0:1d4::6950:5845" );
513  inet6_aton_fail_ok ( "2001.ba8:0:1d4::6950:5845" );
514  inet6_aton_fail_ok ( "2001:db8:1:1:1:1:1" );
515  inet6_aton_fail_ok ( "2001:db8:1:1:1:1:1:1:2" );
516  inet6_aton_fail_ok ( "2001:db8::1::2" );
517  inet6_aton_fail_ok ( "2001:ba8:0:1d4:::6950:5845" );
518  inet6_aton_fail_ok ( ":::" );
519 
520  /* Create test routing tables */
521  ipv6_table_ok ( &table_link_local );
522  ipv6_table_ok ( &table_normal );
523  ipv6_table_ok ( &table_multi );
524  ipv6_table_ok ( &table_unusual );
525 
526  /* Routing table with only a link-local address */
527  ipv6_route_ok ( &table_link_local, "fe80::1",
528  "fe80::69ff:fe50:5845", NULL );
529  ipv6_route_ok ( &table_link_local, "2001:db8:1::1",
530  NULL, NULL );
531  ipv6_route_ok ( &table_link_local, "ff02::1",
532  "fe80::69ff:fe50:5845", NULL );
533 
534  /** Routing table with a global address */
535  ipv6_route_ok ( &table_normal, "fe80::1",
536  "fe80::69ff:fe50:5845", NULL );
537  ipv6_route_ok ( &table_normal, "2001:db8:3::42",
538  "2001:db8:3::1", NULL );
539  ipv6_route_ok ( &table_normal, "2001:ba8:0:1d4::6950:5845",
540  "2001:db8:3::1", "fe80::1" );
541  ipv6_route_ok ( &table_normal, "ff02::1",
542  "fe80::69ff:fe50:5845", NULL );
543  ipv6_route_ok ( &table_normal, "ff0e::1",
544  "2001:db8:3::1", NULL );
545 
546  /** Routing table with multiple addresses and routers */
547  ipv6_route_ok ( &table_multi, "fe80::1",
548  "fe80::69ff:fe50:5845", NULL );
549  ipv6_route_ok ( &table_multi, "2001:db8:3::17",
550  "2001:db8:3::1", NULL );
551  ipv6_route_ok ( &table_multi, "2001:db8:5::92",
552  "2001:db8:5::1", NULL );
553  ipv6_route_ok ( &table_multi, "2001:db8:42::17",
554  "2001:db8:42::1", NULL );
555  ipv6_route_ok ( &table_multi, "2001:db8:5:1::17",
556  "2001:db8:3::1", "fe80::1" );
557  ipv6_route_ok ( &table_multi, "fd44:9112:6442::1",
558  "fd44:9112:6442::69ff:fe50:5845", NULL );
559  ipv6_route_ok ( &table_multi, "fd70:6ba9:50ae::1",
560  "fd70:6ba9:50ae::69ff:fe50:5845", NULL );
561  ipv6_route_ok ( &table_multi, "fd40::3",
562  "fd44:9112:6442::69ff:fe50:5845", "fe80::1" );
563  ipv6_route_ok ( &table_multi, "fd70::2",
564  "fd70:6ba9:50ae::69ff:fe50:5845", "fe80::3" );
565  ipv6_route_ok ( &table_multi, "ff02::1",
566  "fe80::69ff:fe50:5845", NULL );
567 
568  /* Routing table with unusual prefix lengths */
569  ipv6_route_ok ( &table_unusual, "2001:db8:2::1",
570  "2001:db8:2::1", NULL );
571  ipv6_route_ok ( &table_unusual, "2001:db8:2::3",
572  "2001:db8:2::1", NULL );
573  ipv6_route_ok ( &table_unusual, "2001:db8:3::1",
574  "2001:db8:3::1", NULL );
575  ipv6_route_ok ( &table_unusual, "2001:db8:3::2",
576  "2001:db8:1::1", "fe80::1" );
577  ipv6_route_ok ( &table_unusual, "2001:db8:4::1",
578  "2001:db8:4::1", NULL );
579  ipv6_route_ok ( &table_unusual, "2001:db8:4::0",
580  "2001:db8:1::1", "fe80::1" );
581  ipv6_route_ok ( &table_unusual, "2001:db8:4::2",
582  "2001:db8:1::1", "fe80::1" );
583 
584  /* Destroy test routing tables */
585  ipv6_table_del ( &table_link_local );
586  ipv6_table_del ( &table_normal );
587  ipv6_table_del ( &table_multi );
588  ipv6_table_del ( &table_unusual );
589 }
590 
591 /** IPv6 self-test */
592 struct self_test ipv6_test __self_test = {
593  .name = "ipv6",
594  .exec = ipv6_test_exec,
595 };
const struct ipv6_test_route * routes
Test routing table entries.
Definition: ipv6_test.c:65
static const void * src
Definition: string.h:47
#define IPV6(...)
Define inline IPv6 address.
Definition: ipv6_test.c:42
char * inet6_ntoa(const struct in6_addr *in)
Convert IPv6 address to standard notation.
Definition: ipv6.c:894
#define inet6_aton_fail_ok(text)
Definition: ipv6_test.c:239
uint32_t next
Next descriptor address.
Definition: myson.h:18
static const struct in6_addr sample_link_local
A sample link-local IPv6 address.
Definition: ipv6_test.c:98
#define NETDEV_OPEN
Network device is open.
Definition: netdevice.h:438
struct ipv6_miniroute * ipv6_route(unsigned int scope_id, struct in6_addr **dest)
Perform IPv6 routing.
Definition: ipv6.c:307
uint64_t address
Base address.
Definition: ena.h:24
#define IN6_IS_ADDR_SITELOCAL(addr)
Definition: in.h:74
static const struct in6_addr sample_ula
A sample ULA IPv6 address.
Definition: ipv6_test.c:110
const struct ipv6_test_prefix * prefix
Prefix.
Definition: ipv6_test.c:57
static void inet6_ntoa_okx(const struct in6_addr *addr, const char *text, const char *file, unsigned int line)
Report an inet6_ntoa() test result.
Definition: ipv6_test.c:182
static void inet6_aton_fail_okx(const char *text, const char *file, unsigned int line)
Report an inet6_aton() failure test result.
Definition: ipv6_test.c:233
int ipv6_add_miniroute(struct net_device *netdev, struct in6_addr *address, unsigned int prefix_len, struct in6_addr *router)
Add IPv6 routing table entry.
Definition: ipv6.c:217
static const struct in6_addr sample_unspecified
The unspecified IPv6 address.
Definition: ipv6_test.c:92
Self-test infrastructure.
const char * name
Test set name.
Definition: test.h:17
#define ntohs(value)
Definition: byteswap.h:136
static void ipv6_table_okx(struct ipv6_test_table *table, const char *file, unsigned int line)
Create test routing table.
Definition: ipv6_test.c:249
A self-test set.
Definition: test.h:15
unsigned int scope_id
Scope ID.
Definition: netdevice.h:360
int inet6_aton(const char *string, struct in6_addr *in)
Parse IPv6 address.
Definition: ipv6.c:824
struct self_test ipv6_test __self_test
IPv6 self-test.
Definition: ipv6_test.c:592
A doubly-linked list entry (or list head)
Definition: list.h:18
An IPv6 address/routing table entry.
Definition: ipv6.h:180
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
struct in6_addr router
Router address.
Definition: ipv6.h:194
unsigned long tmp
Definition: linux_pci.h:63
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
static void ipv6_table_del(struct ipv6_test_table *table)
Destroy test routing table.
Definition: ipv6_test.c:388
void ipv6_del_miniroute(struct ipv6_miniroute *miniroute)
Delete IPv6 minirouting table entry.
Definition: ipv6.c:292
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static const struct in6_addr sample_multicast
A sample multicast IPv6 address.
Definition: ipv6_test.c:122
#define okx(success, file, line)
Report test result.
Definition: test.h:44
static void inet6_aton_okx(const char *text, const struct in6_addr *addr, const char *file, unsigned int line)
Report an inet6_aton() test result.
Definition: ipv6_test.c:210
#define PREFIX(name, LEN, MASK)
Define a test prefix.
Definition: ipv6_test.c:73
void route(void)
Print routing table.
Definition: route.c:39
unsigned int count
Number of table entries.
Definition: ipv6_test.c:67
#define list_splice_init(list, entry)
Move all entries from one list into another list and reinitialise empty list.
Definition: list.h:278
static void ipv6_test_exec(void)
Perform IPv6 self-tests.
Definition: ipv6_test.c:410
IP6 address structure.
Definition: in.h:50
#define TABLE(name,...)
Define a test routing table.
Definition: ipv6_test.c:80
#define IN6_IS_ADDR_LINKLOCAL(addr)
Definition: in.h:70
#define IN6_IS_ADDR_UNSPECIFIED(addr)
Definition: in.h:61
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:458
struct refcnt refcnt
Reference counter.
Definition: netdevice.h:354
static void ipv6_route_okx(struct ipv6_test_table *table, const char *dest, const char *src, const char *next, const char *file, unsigned int line)
Report an ipv6_route() test result.
Definition: ipv6_test.c:325
A network device.
Definition: netdevice.h:352
struct list_head ipv6_miniroutes
List of IPv6 miniroutes.
Definition: ipv6.c:60
IPv6 protocol.
struct list_head list
Constructed routing table.
Definition: ipv6_test.c:69
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
#define ipv6_route_ok(table, dest, src, next)
Definition: ipv6_test.c:380
unsigned int len
Prefix length.
Definition: ipv6_test.c:47
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
#define inet6_aton_ok(text, addr)
Definition: ipv6_test.c:219
u32 addr
Definition: sky2.h:8
static struct net_device ipv6_test_netdev
Dummy network device used for routing tests.
Definition: ipv6_test.c:128
#define list_splice(list, entry)
Move all entries from one list into another list.
Definition: list.h:220
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" return dest
Definition: string.h:150
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
const char * address
Local address.
Definition: ipv6_test.c:55
#define REF_INIT(free_fn)
Initialise a static reference counter.
Definition: refcnt.h:77
#define IN6_IS_ADDR_MULTICAST(addr)
Definition: in.h:67
#define ipv6_table_ok(table)
Definition: ipv6_test.c:312
#define IN6_IS_ADDR_ULA(addr)
Definition: in.h:78
unsigned int prefix_len
Prefix length.
Definition: ipv6.h:190
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static const struct in6_addr sample_site_local
A sample site-local IPv6 address.
Definition: ipv6_test.c:104
#define ok(success)
Definition: test.h:46
const char * mask
Prefix mask.
Definition: ipv6_test.c:49
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
void ref_no_free(struct refcnt *refcnt __unused)
Do not free reference-counted object.
Definition: refcnt.c:101
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
#define inet6_ntoa_ok(addr, text)
Definition: ipv6_test.c:195
struct in6_addr address
IPv6 address (or prefix if no address is defined)
Definition: ipv6.h:188
static const struct in6_addr sample_global
A sample global IPv6 address.
Definition: ipv6_test.c:116
const char * router
Router address (if any)
Definition: ipv6_test.c:59
struct in6_addr prefix_mask
IPv6 prefix mask (derived from prefix length)
Definition: ipv6.h:192
An IPv6 test routing table.
Definition: ipv6_test.c:63
An IPv6 test routing table entry.
Definition: ipv6_test.c:53
An IPv6 test prefix.
Definition: ipv6_test.c:45