Changeset View
Standalone View
sys/netinet6/in6_src.c
Show First 20 Lines • Show All 291 Lines • ▼ Show 20 Lines | if (cred != NULL && !prison_saddrsel_ip6(cred, srcp)) | ||||
return (0); | return (0); | ||||
/* | /* | ||||
* If the address is not specified, choose the best one based on | * If the address is not specified, choose the best one based on | ||||
* the outgoing interface and the destination address. | * the outgoing interface and the destination address. | ||||
*/ | */ | ||||
/* get the outgoing interface */ | /* get the outgoing interface */ | ||||
if ((error = in6_selectif(dstsock, opts, mopts, &ifp, oifp, | if ((error = in6_selectif(dstsock, opts, mopts, &ifp, oifp, | ||||
(inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB)) != 0) | (inp != NULL) ? inp->inp_inc.inc_fibnum : fibnum)) != 0) | ||||
return (error); | return (error); | ||||
#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) | ||||
▲ Show 20 Lines • Show All 249 Lines • ▼ Show 20 Lines | |||||
in6_selectsrc_socket(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, | in6_selectsrc_socket(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, | ||||
struct inpcb *inp, struct ucred *cred, int scope_ambiguous, | struct inpcb *inp, struct ucred *cred, int scope_ambiguous, | ||||
struct in6_addr *srcp, int *hlim) | struct in6_addr *srcp, int *hlim) | ||||
{ | { | ||||
struct ifnet *retifp; | struct ifnet *retifp; | ||||
uint32_t fibnum; | uint32_t fibnum; | ||||
int error; | int error; | ||||
fibnum = (inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB; | fibnum = (inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB; | ||||
asomers: I think this is a bug. If we have a socket, then the source address should be based on the… | |||||
jhujhiti_adjectivism.orgAuthorUnsubmitted Done Inline ActionsI must be misunderstanding the inpcb structure -- does this not represent the socket (and therefore inp->inp_inc.inc_fibnum represent the socket FIB)? Even if my understanding is correct, I do think there's a bug here: it seems like we should prefer the socket's FIB, then the interface's FIB, and only the default as a last resort. jhujhiti_adjectivism.org: I must be misunderstanding the inpcb structure -- does this not represent the socket (and… | |||||
asomersUnsubmitted Done Inline ActionsYou're correct; I was confused about inpcb. However, there is no need to consider the interface fib. The interface fib really only matters for forwarding packets and for automatically adding routes to routing tables. Also, I think that the inp != NULL check is superfluous. AFAICT, there's no way for inp to be NULL right here. asomers: You're correct; I was confused about inpcb. However, there is no need to consider the… | |||||
jhujhiti_adjectivism.orgAuthorUnsubmitted Done Inline ActionsI agree - all callers of in6_selectsrc_socket() unconditionally dereference inp prior to passing it, so this check for NULL is definitely redundant. I've removed it. jhujhiti_adjectivism.org: I agree - all callers of in6_selectsrc_socket() unconditionally dereference inp prior to… | |||||
retifp = NULL; | retifp = NULL; | ||||
error = in6_selectsrc(fibnum, dstsock, opts, inp, cred, &retifp, srcp); | error = in6_selectsrc(fibnum, dstsock, opts, inp, cred, &retifp, srcp); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
if (hlim != NULL) | if (hlim != NULL) | ||||
*hlim = in6_selecthlim(inp, retifp); | *hlim = in6_selecthlim(inp, retifp); | ||||
▲ Show 20 Lines • Show All 670 Lines • Show Last 20 Lines |
I think this is a bug. If we have a socket, then the source address should be based on the socket's FIB, not the interface's. Socket FIBs default to the FIB of the process, but can be manually changed.