version 1.34, 2007/01/04 19:07:04 |
version 1.35, 2007/02/17 22:34:13 |
Line 133 struct in6_addrpolicy defaultaddrpolicy; |
|
Line 133 struct in6_addrpolicy defaultaddrpolicy; |
|
int ip6_prefer_tempaddr = 0; |
int ip6_prefer_tempaddr = 0; |
#endif |
#endif |
|
|
static int selectroute __P((struct sockaddr_in6 *, struct ip6_pktopts *, |
static int selectroute(struct sockaddr_in6 *, struct ip6_pktopts *, |
struct ip6_moptions *, struct route_in6 *, struct ifnet **, |
struct ip6_moptions *, struct route *, struct ifnet **, |
struct rtentry **, int, int)); |
struct rtentry **, int, int); |
static int in6_selectif __P((struct sockaddr_in6 *, struct ip6_pktopts *, |
static int in6_selectif(struct sockaddr_in6 *, struct ip6_pktopts *, |
struct ip6_moptions *, struct route_in6 *, struct ifnet **)); |
struct ip6_moptions *, struct route *, struct ifnet **); |
|
|
static struct in6_addrpolicy *lookup_addrsel_policy __P((struct sockaddr_in6 *)); |
static struct in6_addrpolicy *lookup_addrsel_policy(struct sockaddr_in6 *); |
|
|
static void init_policy_queue __P((void)); |
static void init_policy_queue(void); |
static int add_addrsel_policyent __P((struct in6_addrpolicy *)); |
static int add_addrsel_policyent(struct in6_addrpolicy *); |
static int delete_addrsel_policyent __P((struct in6_addrpolicy *)); |
static int delete_addrsel_policyent(struct in6_addrpolicy *); |
static int walk_addrsel_policy __P((int (*)(struct in6_addrpolicy *, void *), |
static int walk_addrsel_policy(int (*)(struct in6_addrpolicy *, void *), |
void *)); |
void *); |
static int dump_addrsel_policyent __P((struct in6_addrpolicy *, void *)); |
static int dump_addrsel_policyent(struct in6_addrpolicy *, void *); |
static struct in6_addrpolicy *match_addrsel_policy __P((struct sockaddr_in6 *)); |
static struct in6_addrpolicy *match_addrsel_policy(struct sockaddr_in6 *); |
|
|
/* |
/* |
* Return an IPv6 address, which is the most appropriate for a given |
* Return an IPv6 address, which is the most appropriate for a given |
Line 187 in6_selectsrc(dstsock, opts, mopts, ro, |
|
Line 187 in6_selectsrc(dstsock, opts, mopts, ro, |
|
struct sockaddr_in6 *dstsock; |
struct sockaddr_in6 *dstsock; |
struct ip6_pktopts *opts; |
struct ip6_pktopts *opts; |
struct ip6_moptions *mopts; |
struct ip6_moptions *mopts; |
struct route_in6 *ro; |
struct route *ro; |
struct in6_addr *laddr; |
struct in6_addr *laddr; |
struct ifnet **ifpp; |
struct ifnet **ifpp; |
int *errorp; |
int *errorp; |
Line 582 selectroute(dstsock, opts, mopts, ro, re |
|
Line 582 selectroute(dstsock, opts, mopts, ro, re |
|
struct sockaddr_in6 *dstsock; |
struct sockaddr_in6 *dstsock; |
struct ip6_pktopts *opts; |
struct ip6_pktopts *opts; |
struct ip6_moptions *mopts; |
struct ip6_moptions *mopts; |
#ifdef NEW_STRUCT_ROUTE |
|
struct route *ro; |
struct route *ro; |
#else |
|
struct route_in6 *ro; |
|
#endif |
|
struct ifnet **retifp; |
struct ifnet **retifp; |
struct rtentry **retrt; |
struct rtentry **retrt; |
int clone; |
int clone; |
Line 649 selectroute(dstsock, opts, mopts, ro, re |
|
Line 645 selectroute(dstsock, opts, mopts, ro, re |
|
* use it as the gateway. |
* use it as the gateway. |
*/ |
*/ |
if (opts && opts->ip6po_nexthop) { |
if (opts && opts->ip6po_nexthop) { |
struct route_in6 *ron; |
struct route *ron; |
|
|
sin6_next = satosin6(opts->ip6po_nexthop); |
sin6_next = satosin6(opts->ip6po_nexthop); |
|
|
Line 663 selectroute(dstsock, opts, mopts, ro, re |
|
Line 659 selectroute(dstsock, opts, mopts, ro, re |
|
* If the next hop is an IPv6 address, then the node identified |
* If the next hop is an IPv6 address, then the node identified |
* by that address must be a neighbor of the sending host. |
* by that address must be a neighbor of the sending host. |
*/ |
*/ |
ron = &opts->ip6po_nextroute; |
ron = (struct route *)&opts->ip6po_nextroute; |
if (!IN6_ARE_ADDR_EQUAL(&satosin6(&ron->ro_dst)->sin6_addr, |
if (!IN6_ARE_ADDR_EQUAL( |
&sin6_next->sin6_addr)) |
&satocsin6(rtcache_getdst(ron))->sin6_addr, |
rtcache_free((struct route *)ron); |
&sin6_next->sin6_addr)) |
|
rtcache_free(ron); |
else |
else |
rtcache_check((struct route *)ron); |
rtcache_check(ron); |
if (ron->ro_rt == NULL) { |
if (ron->ro_rt == NULL) { |
*satosin6(&ron->ro_dst) = *sin6_next; |
*satosin6(&ron->ro_dst) = *sin6_next; |
rtcache_init((struct route *)ron); |
rtcache_init(ron); |
} |
} |
if (ron->ro_rt == NULL || |
if (ron->ro_rt == NULL || |
(ron->ro_rt->rt_flags & RTF_GATEWAY) != 0 || |
(ron->ro_rt->rt_flags & RTF_GATEWAY) != 0 || |
!nd6_is_addr_neighbor(sin6_next, ron->ro_rt->rt_ifp)) { |
!nd6_is_addr_neighbor(sin6_next, ron->ro_rt->rt_ifp)) { |
rtcache_free((struct route *)ron); |
rtcache_free(ron); |
error = EHOSTUNREACH; |
error = EHOSTUNREACH; |
goto done; |
goto done; |
} |
} |
Line 698 selectroute(dstsock, opts, mopts, ro, re |
|
Line 695 selectroute(dstsock, opts, mopts, ro, re |
|
* cached destination, in case of sharing the cache with IPv4. |
* cached destination, in case of sharing the cache with IPv4. |
*/ |
*/ |
if (ro != NULL) { |
if (ro != NULL) { |
if (((struct sockaddr *)(&ro->ro_dst))->sa_family != AF_INET6 || |
if (rtcache_getdst(ro)->sa_family != AF_INET6 || |
!IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, dst)) |
!IN6_ARE_ADDR_EQUAL(&satocsin6(rtcache_getdst(ro))->sin6_addr, dst)) |
rtcache_free((struct route *)ro); |
rtcache_free(ro); |
else |
else |
rtcache_check((struct route *)ro); |
rtcache_check(ro); |
if (ro->ro_rt == NULL) { |
if (ro->ro_rt == NULL) { |
struct sockaddr_in6 *sa6; |
struct sockaddr_in6 *sa6; |
|
|
/* No route yet, so try to acquire one */ |
/* No route yet, so try to acquire one */ |
bzero(&ro->ro_dst, sizeof(struct sockaddr_in6)); |
sa6 = satosin6(&ro->ro_dst); |
sa6 = (struct sockaddr_in6 *)&ro->ro_dst; |
|
*sa6 = *dstsock; |
*sa6 = *dstsock; |
sa6->sin6_scope_id = 0; |
sa6->sin6_scope_id = 0; |
if (clone) |
if (clone) |
rtcache_init((struct route *)ro); |
rtcache_init(ro); |
else |
else |
rtcache_init_noclone((struct route *)ro); |
rtcache_init_noclone(ro); |
} |
} |
|
|
/* |
/* |
Line 772 in6_selectif(dstsock, opts, mopts, ro, r |
|
Line 768 in6_selectif(dstsock, opts, mopts, ro, r |
|
struct sockaddr_in6 *dstsock; |
struct sockaddr_in6 *dstsock; |
struct ip6_pktopts *opts; |
struct ip6_pktopts *opts; |
struct ip6_moptions *mopts; |
struct ip6_moptions *mopts; |
struct route_in6 *ro; |
struct route *ro; |
struct ifnet **retifp; |
struct ifnet **retifp; |
{ |
{ |
int error, clone; |
int error, clone; |
Line 822 in6_selectroute(dstsock, opts, mopts, ro |
|
Line 818 in6_selectroute(dstsock, opts, mopts, ro |
|
struct sockaddr_in6 *dstsock; |
struct sockaddr_in6 *dstsock; |
struct ip6_pktopts *opts; |
struct ip6_pktopts *opts; |
struct ip6_moptions *mopts; |
struct ip6_moptions *mopts; |
struct route_in6 *ro; |
struct route *ro; |
struct ifnet **retifp; |
struct ifnet **retifp; |
struct rtentry **retrt; |
struct rtentry **retrt; |
int clone; /* meaningful only for bsdi and freebsd. */ |
int clone; /* meaningful only for bsdi and freebsd. */ |
{ |
{ |
return (selectroute(dstsock, opts, mopts, ro, retifp, |
return selectroute(dstsock, opts, mopts, ro, retifp, |
retrt, clone, 0)); |
retrt, clone, 0); |
} |
} |
|
|
/* |
/* |
Line 1111 delete_addrsel_policyent(key) |
|
Line 1107 delete_addrsel_policyent(key) |
|
} |
} |
|
|
static int |
static int |
walk_addrsel_policy(callback, w) |
walk_addrsel_policy(int (*callback)(struct in6_addrpolicy *, void *), void *w) |
int (*callback) __P((struct in6_addrpolicy *, void *)); |
|
void *w; |
|
{ |
{ |
struct addrsel_policyent *pol; |
struct addrsel_policyent *pol; |
int error = 0; |
int error = 0; |
|
|
for (pol = TAILQ_FIRST(&addrsel_policytab); pol; |
TAILQ_FOREACH(pol, &addrsel_policytab, ape_entry) { |
pol = TAILQ_NEXT(pol, ape_entry)) { |
if ((error = (*callback)(&pol->ape_policy, w)) != 0) |
if ((error = (*callback)(&pol->ape_policy, w)) != 0) { |
return error; |
return (error); |
|
} |
|
} |
} |
|
|
return (error); |
return error; |
} |
} |
|
|
static int |
static int |
dump_addrsel_policyent(pol, arg) |
dump_addrsel_policyent(struct in6_addrpolicy *pol, void *arg) |
struct in6_addrpolicy *pol; |
|
void *arg; |
|
{ |
{ |
int error = 0; |
int error = 0; |
struct walkarg *w = arg; |
struct walkarg *w = arg; |
|
|
if (w->w_where && w->w_where + sizeof(*pol) <= w->w_limit) { |
if (w->w_where && w->w_where + sizeof(*pol) <= w->w_limit) { |
if ((error = copyout(pol, w->w_where, sizeof(*pol))) != 0) |
if ((error = copyout(pol, w->w_where, sizeof(*pol))) != 0) |
return (error); |
return error; |
w->w_where += sizeof(*pol); |
w->w_where += sizeof(*pol); |
} |
} |
w->w_total += sizeof(*pol); |
w->w_total += sizeof(*pol); |
|
|
return (error); |
return error; |
} |
} |
|
|
static struct in6_addrpolicy * |
static struct in6_addrpolicy * |