Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/in6_src.c
Show First 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Return an IPv6 address, which is the most appropriate for a given | * Return an IPv6 address, which is the most appropriate for a given | ||||
* destination and user specified options. | * destination and user specified options. | ||||
* If necessary, this function lookups the routing table and returns | * If necessary, this function lookups the routing table and returns | ||||
* an entry to the caller for later use. | * an entry to the caller for later use. | ||||
*/ | */ | ||||
#define REPLACE(r) do {\ | #define REPLACE(r) do {\ | ||||
IP6STAT_INC(ip6s_sources_rule[(r)]); \ | IP6STAT_INC(ip6s_sources_rule[(r)]); \ | ||||
rule = (r); \ | |||||
ae: This look like the part of commented debugging code. | |||||
/* { \ | /* { \ | ||||
char ip6buf[INET6_ADDRSTRLEN], ip6b[INET6_ADDRSTRLEN]; \ | char ip6buf[INET6_ADDRSTRLEN], ip6b[INET6_ADDRSTRLEN]; \ | ||||
printf("in6_selectsrc: replace %s with %s by %d\n", ia_best ? ip6_sprintf(ip6buf, &ia_best->ia_addr.sin6_addr) : "none", ip6_sprintf(ip6b, &ia->ia_addr.sin6_addr), (r)); \ | printf("in6_selectsrc: replace %s with %s by %d\n", ia_best ? ip6_sprintf(ip6buf, &ia_best->ia_addr.sin6_addr) : "none", ip6_sprintf(ip6b, &ia->ia_addr.sin6_addr), (r)); \ | ||||
} */ \ | } */ \ | ||||
goto replace; \ | goto replace; \ | ||||
} while(0) | } while(0) | ||||
#define NEXT(r) do {\ | #define NEXT(r) do {\ | ||||
/* { \ | /* { \ | ||||
char ip6buf[INET6_ADDRSTRLEN], ip6b[INET6_ADDRSTRLEN]; \ | char ip6buf[INET6_ADDRSTRLEN], ip6b[INET6_ADDRSTRLEN]; \ | ||||
printf("in6_selectsrc: keep %s against %s by %d\n", ia_best ? ip6_sprintf(ip6buf, &ia_best->ia_addr.sin6_addr) : "none", ip6_sprintf(ip6b, &ia->ia_addr.sin6_addr), (r)); \ | printf("in6_selectsrc: keep %s against %s by %d\n", ia_best ? ip6_sprintf(ip6buf, &ia_best->ia_addr.sin6_addr) : "none", ip6_sprintf(ip6b, &ia->ia_addr.sin6_addr), (r)); \ | ||||
} */ \ | } */ \ | ||||
goto next; /* XXX: we can't use 'continue' here */ \ | goto next; /* XXX: we can't use 'continue' here */ \ | ||||
} while(0) | } while(0) | ||||
#define BREAK(r) do { \ | #define BREAK(r) do { \ | ||||
IP6STAT_INC(ip6s_sources_rule[(r)]); \ | IP6STAT_INC(ip6s_sources_rule[(r)]); \ | ||||
rule = (r); \ | |||||
goto out; /* XXX: we can't use 'break' here */ \ | goto out; /* XXX: we can't use 'break' here */ \ | ||||
} while(0) | } while(0) | ||||
static int | static int | ||||
in6_selectsrc(uint32_t fibnum, struct sockaddr_in6 *dstsock, | in6_selectsrc(uint32_t fibnum, struct sockaddr_in6 *dstsock, | ||||
struct ip6_pktopts *opts, struct inpcb *inp, struct ucred *cred, | struct ip6_pktopts *opts, struct inpcb *inp, struct ucred *cred, | ||||
struct ifnet **ifpp, struct in6_addr *srcp) | struct ifnet **ifpp, struct in6_addr *srcp) | ||||
{ | { | ||||
struct rm_priotracker in6_ifa_tracker; | struct rm_priotracker in6_ifa_tracker; | ||||
struct in6_addr dst, tmp; | struct in6_addr dst, tmp; | ||||
struct ifnet *ifp = NULL, *oifp = NULL; | struct ifnet *ifp = NULL, *oifp = NULL; | ||||
struct in6_ifaddr *ia = NULL, *ia_best = NULL; | struct in6_ifaddr *ia = NULL, *ia_best = NULL; | ||||
struct in6_pktinfo *pi = NULL; | struct in6_pktinfo *pi = NULL; | ||||
int dst_scope = -1, best_scope = -1, best_matchlen = -1; | int dst_scope = -1, best_scope = -1, best_matchlen = -1; | ||||
struct in6_addrpolicy *dst_policy = NULL, *best_policy = NULL; | struct in6_addrpolicy *dst_policy = NULL, *best_policy = NULL; | ||||
u_int32_t odstzone; | u_int32_t odstzone; | ||||
int prefer_tempaddr; | int prefer_tempaddr; | ||||
int error, rule; | int error; | ||||
struct ip6_moptions *mopts; | struct ip6_moptions *mopts; | ||||
KASSERT(srcp != NULL, ("%s: srcp is NULL", __func__)); | KASSERT(srcp != NULL, ("%s: srcp is NULL", __func__)); | ||||
dst = dstsock->sin6_addr; /* make a copy for local operation */ | dst = dstsock->sin6_addr; /* make a copy for local operation */ | ||||
if (ifpp) { | if (ifpp) { | ||||
/* | /* | ||||
* Save a possibly passed in ifp for in6_selectsrc. Only | * Save a possibly passed in ifp for in6_selectsrc. Only | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | |||||
#ifdef DIAGNOSTIC | #ifdef DIAGNOSTIC | ||||
if (ifp == NULL) /* this should not happen */ | if (ifp == NULL) /* this should not happen */ | ||||
panic("in6_selectsrc: NULL ifp"); | panic("in6_selectsrc: NULL ifp"); | ||||
#endif | #endif | ||||
error = in6_setscope(&dst, ifp, &odstzone); | error = in6_setscope(&dst, ifp, &odstzone); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
rule = 0; | |||||
IN6_IFADDR_RLOCK(&in6_ifa_tracker); | IN6_IFADDR_RLOCK(&in6_ifa_tracker); | ||||
TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) { | TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) { | ||||
int new_scope = -1, new_matchlen = -1; | int new_scope = -1, new_matchlen = -1; | ||||
struct in6_addrpolicy *new_policy = NULL; | struct in6_addrpolicy *new_policy = NULL; | ||||
u_int32_t srczone, osrczone, dstzone; | u_int32_t srczone, osrczone, dstzone; | ||||
struct in6_addr src; | struct in6_addr src; | ||||
struct ifnet *ifp1 = ia->ia_ifp; | struct ifnet *ifp1 = ia->ia_ifp; | ||||
▲ Show 20 Lines • Show All 925 Lines • Show Last 20 Lines |
This look like the part of commented debugging code.