Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/nd6_nbr.c
Show First 20 Lines • Show All 459 Lines • ▼ Show 20 Lines | else { | ||||
ip6->ip6_dst.s6_addr32[1] = 0; | ip6->ip6_dst.s6_addr32[1] = 0; | ||||
ip6->ip6_dst.s6_addr32[2] = IPV6_ADDR_INT32_ONE; | ip6->ip6_dst.s6_addr32[2] = IPV6_ADDR_INT32_ONE; | ||||
ip6->ip6_dst.s6_addr32[3] = taddr6->s6_addr32[3]; | ip6->ip6_dst.s6_addr32[3] = taddr6->s6_addr32[3]; | ||||
ip6->ip6_dst.s6_addr8[12] = 0xff; | ip6->ip6_dst.s6_addr8[12] = 0xff; | ||||
if (in6_setscope(&ip6->ip6_dst, ifp, NULL) != 0) | if (in6_setscope(&ip6->ip6_dst, ifp, NULL) != 0) | ||||
goto bad; | goto bad; | ||||
} | } | ||||
if (nonce == NULL) { | if (nonce == NULL) { | ||||
char ip6buf[INET6_ADDRSTRLEN]; | |||||
struct ifaddr *ifa = NULL; | struct ifaddr *ifa = NULL; | ||||
/* | /* | ||||
* RFC2461 7.2.2: | * RFC2461 7.2.2: | ||||
* "If the source address of the packet prompting the | * "If the source address of the packet prompting the | ||||
* solicitation is the same as one of the addresses assigned | * solicitation is the same as one of the addresses assigned | ||||
* to the outgoing interface, that address SHOULD be placed | * to the outgoing interface, that address SHOULD be placed | ||||
* in the IP Source Address of the outgoing solicitation. | * in the IP Source Address of the outgoing solicitation. | ||||
* Otherwise, any one of the addresses assigned to the | * Otherwise, any one of the addresses assigned to the | ||||
* interface should be used." | * interface should be used." | ||||
* | * | ||||
* We use the source address for the prompting packet | * We use the source address for the prompting packet | ||||
* (saddr6), if saddr6 belongs to the outgoing interface. | * (saddr6), if saddr6 belongs to the outgoing interface. | ||||
* Otherwise, we perform the source address selection as usual. | * Otherwise, we perform the source address selection as usual. | ||||
*/ | */ | ||||
if (saddr6 != NULL) | if (saddr6 != NULL) | ||||
ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, saddr6); | ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, saddr6); | ||||
if (ifa != NULL) { | if (ifa == NULL) { | ||||
/* ip6_src set already. */ | |||||
ip6->ip6_src = *saddr6; | |||||
ifa_free(ifa); | |||||
} else { | |||||
int error; | int error; | ||||
struct in6_addr dst6, src6; | struct in6_addr dst6, src6; | ||||
uint32_t scopeid; | uint32_t scopeid; | ||||
in6_splitscope(&ip6->ip6_dst, &dst6, &scopeid); | in6_splitscope(&ip6->ip6_dst, &dst6, &scopeid); | ||||
error = in6_selectsrc_addr(fibnum, &dst6, | error = in6_selectsrc_addr(fibnum, &dst6, | ||||
scopeid, ifp, &src6, NULL); | scopeid, ifp, &src6, NULL); | ||||
if (error) { | if (error) { | ||||
char ip6buf[INET6_ADDRSTRLEN]; | |||||
nd6log((LOG_DEBUG, "%s: source can't be " | nd6log((LOG_DEBUG, "%s: source can't be " | ||||
"determined: dst=%s, error=%d\n", __func__, | "determined: dst=%s, error=%d\n", __func__, | ||||
ip6_sprintf(ip6buf, &dst6), | ip6_sprintf(ip6buf, &dst6), | ||||
error)); | error)); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
ip6->ip6_src = src6; | ip6->ip6_src = src6; | ||||
} else | |||||
ip6->ip6_src = *saddr6; | |||||
if (ifp->if_carp != NULL) { | |||||
/* | |||||
* Check that selected source address belongs to | |||||
* CARP addresses. | |||||
*/ | |||||
if (ifa == NULL) | |||||
ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, | |||||
&ip6->ip6_src); | |||||
/* | |||||
* Do not send NS for CARP address if we are not | |||||
* the CARP master. | |||||
*/ | |||||
if (ifa != NULL && !(*carp_master_p)(ifa)) { | |||||
log(LOG_DEBUG, | |||||
"nd6_ns_output: NS from BACKUP CARP address %s\n", | |||||
ip6_sprintf(ip6buf, &ip6->ip6_src)); | |||||
ifa_free(ifa); | |||||
goto bad; | |||||
} | } | ||||
} | |||||
if (ifa != NULL) | |||||
ifa_free(ifa); | |||||
} else { | } else { | ||||
/* | /* | ||||
* Source address for DAD packet must always be IPv6 | * Source address for DAD packet must always be IPv6 | ||||
* unspecified address. (0::0) | * unspecified address. (0::0) | ||||
* We actually don't have to 0-clear the address (we did it | * We actually don't have to 0-clear the address (we did it | ||||
* above), but we do so here explicitly to make the intention | * above), but we do so here explicitly to make the intention | ||||
* clearer. | * clearer. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | nd6_na_input(struct mbuf *m, int off, int icmp6len) | ||||
lladdr = NULL; | lladdr = NULL; | ||||
lladdrlen = 0; | lladdrlen = 0; | ||||
if (ndopts.nd_opts_tgt_lladdr) { | if (ndopts.nd_opts_tgt_lladdr) { | ||||
lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1); | lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1); | ||||
lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3; | lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3; | ||||
} | } | ||||
ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6); | |||||
if (ifa != NULL && ifa->ifa_carp != NULL) { | |||||
/* | /* | ||||
* This effectively disables the DAD check on a non-master CARP | * Silently ignore NAs for CARP addresses if we are not | ||||
* address. | * the CARP master. | ||||
*/ | */ | ||||
if (ifp->if_carp) | if (!(*carp_master_p)(ifa)) { | ||||
ifa = (*carp_iamatch6_p)(ifp, &taddr6); | log(LOG_DEBUG, | ||||
else | "nd6_na_input: NA for BACKUP CARP address %s\n", | ||||
ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6); | ip6_sprintf(ip6bufs, &taddr6)); | ||||
ifa_free(ifa); | |||||
goto freeit; | |||||
} | |||||
} | |||||
/* | /* | ||||
* Target address matches one of my interface address. | * Target address matches one of my interface address. | ||||
* | * | ||||
* If my address is tentative, this means that there's somebody | * If my address is tentative, this means that there's somebody | ||||
* already using the same address as mine. This indicates DAD failure. | * already using the same address as mine. This indicates DAD failure. | ||||
* This is defined in RFC 2462. | * This is defined in RFC 2462. | ||||
* | * | ||||
* Otherwise, process as defined in RFC 2461. | * Otherwise, process as defined in RFC 2461. | ||||
▲ Show 20 Lines • Show All 855 Lines • Show Last 20 Lines |