Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/in6_ifattach.c
Show First 20 Lines • Show All 416 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* altifp - secondary EUI64 source | * altifp - secondary EUI64 source | ||||
*/ | */ | ||||
static int | static int | ||||
in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp) | in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp) | ||||
{ | { | ||||
struct in6_ifaddr *ia; | struct in6_ifaddr *ia; | ||||
struct in6_aliasreq ifra; | struct in6_aliasreq ifra; | ||||
struct nd_prefixctl pr0; | |||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
struct nd_prefix *pr; | |||||
int error; | int error; | ||||
/* | /* | ||||
* configure link-local address. | * configure link-local address. | ||||
*/ | */ | ||||
in6_prepare_ifra(&ifra, NULL, &in6mask64); | in6_prepare_ifra(&ifra, NULL, &in6mask64); | ||||
ifra.ifra_addr.sin6_addr.s6_addr32[0] = htonl(0xfe800000); | ifra.ifra_addr.sin6_addr.s6_addr32[0] = htonl(0xfe800000); | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | if (ia == NULL) { | ||||
* This should be rare, but it happens. | * This should be rare, but it happens. | ||||
*/ | */ | ||||
nd6log((LOG_NOTICE, "%s: %s: new link-local address " | nd6log((LOG_NOTICE, "%s: %s: new link-local address " | ||||
"disappeared\n", __func__, if_name(ifp))); | "disappeared\n", __func__, if_name(ifp))); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
ifa_free(&ia->ia_ifa); | ifa_free(&ia->ia_ifa); | ||||
/* | error = in6_prefix_rtrequest(RTM_ADD, ia); | ||||
* Make the link-local prefix (fe80::%link/64) as on-link. | if (error == 0) | ||||
* Since we'd like to manage prefixes separately from addresses, | ia->ia_flags |= IFA_ROUTE; | ||||
* we make an ND6 prefix structure for the link-local prefix, | else if (error == EEXIST) | ||||
* and add it to the prefix list as a never-expire prefix. | error = 0; | ||||
* XXX: this change might affect some existing code base... | |||||
*/ | |||||
bzero(&pr0, sizeof(pr0)); | |||||
pr0.ndpr_ifp = ifp; | |||||
/* this should be 64 at this moment. */ | |||||
pr0.ndpr_plen = in6_mask2len(&ifra.ifra_prefixmask.sin6_addr, NULL); | |||||
pr0.ndpr_prefix = ifra.ifra_addr; | |||||
/* apply the mask for safety. (nd6_prelist_add will apply it again) */ | |||||
IN6_MASK_ADDR(&pr0.ndpr_prefix.sin6_addr, &in6mask64); | |||||
/* | |||||
* Initialize parameters. The link-local prefix must always be | |||||
* on-link, and its lifetimes never expire. | |||||
*/ | |||||
pr0.ndpr_raf_onlink = 1; | |||||
pr0.ndpr_raf_auto = 1; /* probably meaningless */ | |||||
pr0.ndpr_vltime = ND6_INFINITE_LIFETIME; | |||||
pr0.ndpr_pltime = ND6_INFINITE_LIFETIME; | |||||
/* | |||||
* Since there is no other link-local addresses, nd6_prefix_lookup() | |||||
* probably returns NULL. However, we cannot always expect the result. | |||||
* For example, if we first remove the (only) existing link-local | |||||
* address, and then reconfigure another one, the prefix is still | |||||
* valid with referring to the old link-local address. | |||||
*/ | |||||
if ((pr = nd6_prefix_lookup(&pr0)) == NULL) { | |||||
if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0) | |||||
return (error); | |||||
/* Reference prefix */ | |||||
ia->ia6_ndpr = pr; | |||||
pr->ndpr_addrcnt++; | |||||
} else | |||||
nd6_prefix_rele(pr); | |||||
return 0; | return error; | ||||
} | } | ||||
/* | /* | ||||
* ifp - must be IFT_LOOP | * ifp - must be IFT_LOOP | ||||
*/ | */ | ||||
static int | static int | ||||
in6_ifattach_loopback(struct ifnet *ifp) | in6_ifattach_loopback(struct ifnet *ifp) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 365 Lines • Show Last 20 Lines |