Skip to content

Commit

Permalink
Backport (simple cherry-pick) d33019030c1f0cddca557f9659e3c471bde0e6a9
Browse files Browse the repository at this point in the history
to gingerbread.

Implement RFC3484 policy table changes from draft-ietf-6man-rfc3484-revise-01.

The changes in a nutshell:

 - Handle v4-mapped as different from v4-compat (this was probably
   an existing bug in our code).
 - Add policy entries for ULA, above most everything else.
 - Put v4-compat, old-style IPv6 site-local and 6bone addresses
   way down in the preference table.

The rest is just shuffling numbers around (no actual changes to
priority).
  • Loading branch information
sesse committed Jan 14, 2011
1 parent f4dca7b commit 2e23e29
Showing 1 changed file with 31 additions and 13 deletions.
44 changes: 31 additions & 13 deletions libc/netbsd/net/getaddrinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -1327,29 1327,41 @@ _get_scope(const struct sockaddr *addr)
#define IN6_IS_ADDR_6TO4(a) \
(((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02))

/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */
#define IN6_IS_ADDR_6BONE(a) \
(((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe))

/*
* Get the label for a given IPv4/IPv6 address.
* RFC 3484, section 2.1, plus Teredo added in with label 5.
* RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01.
*/

/*ARGSUSED*/
static int
_get_label(const struct sockaddr *addr)
{
if (addr->sa_family == AF_INET) {
return 4;
return 3;
} else if (addr->sa_family == AF_INET6) {
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
return 0;
} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
} else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
return 1;
} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
return 3;
} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
return 4;
} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
return 5;
} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
return 2;
} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
return 10;
} else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) {
return 11;
} else if (IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
return 12;
} else {
return 1;
return 2;
}
} else {
/*
Expand All @@ -1362,30 1374,36 @@ _get_label(const struct sockaddr *addr)

/*
* Get the precedence for a given IPv4/IPv6 address.
* RFC 3484, section 2.1, plus Teredo added in with precedence 25.
* RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01.
*/

/*ARGSUSED*/
static int
_get_precedence(const struct sockaddr *addr)
{
if (addr->sa_family == AF_INET) {
return 10;
return 30;
} else if (addr->sa_family == AF_INET6) {
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
return 60;
} else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
return 50;
} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
return 30;
} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
return 20;
} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
return 25;
} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
return 30;
return 10;
} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
return 1;
} else {
return 40;
}
} else {
return 5;
return 1;
}
}

Expand Down

0 comments on commit 2e23e29

Please sign in to comment.