Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/in6.c
Show First 20 Lines • Show All 1,288 Lines • ▼ Show 20 Lines | in6_handle_dstaddr_rtrequest(int cmd, struct in6_ifaddr *ia) | ||||
NET_EPOCH_ENTER(et); | NET_EPOCH_ENTER(et); | ||||
error = rib_handle_ifaddr_info(ifa->ifa_ifp->if_fib, cmd, &info); | error = rib_handle_ifaddr_info(ifa->ifa_ifp->if_fib, cmd, &info); | ||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
return (error); | return (error); | ||||
} | } | ||||
static bool | |||||
ifa_is_p2p(struct in6_ifaddr *ia) | |||||
{ | |||||
int plen; | |||||
plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */ | |||||
if ((plen == 128) && (ia->ia_dstaddr.sin6_family == AF_INET6) && | |||||
!IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, &ia->ia_dstaddr.sin6_addr)) | |||||
return (true); | |||||
return (false); | |||||
} | |||||
void | void | ||||
in6_purgeaddr(struct ifaddr *ifa) | in6_purgeaddr(struct ifaddr *ifa) | ||||
{ | { | ||||
struct ifnet *ifp = ifa->ifa_ifp; | struct ifnet *ifp = ifa->ifa_ifp; | ||||
struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa; | struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa; | ||||
struct in6_multi_mship *imm; | struct in6_multi_mship *imm; | ||||
int plen, error; | int error; | ||||
if (ifa->ifa_carp) | if (ifa->ifa_carp) | ||||
(*carp_detach_p)(ifa, false); | (*carp_detach_p)(ifa, false); | ||||
/* | /* | ||||
* Remove the loopback route to the interface address. | * Remove the loopback route to the interface address. | ||||
* The check for the current setting of "nd6_useloopback" | * The check for the current setting of "nd6_useloopback" | ||||
* is not needed. | * is not needed. | ||||
Show All 11 Lines | in6_purgeaddr(struct ifaddr *ifa) | ||||
/* Leave multicast groups. */ | /* Leave multicast groups. */ | ||||
while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) { | while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) { | ||||
LIST_REMOVE(imm, i6mm_chain); | LIST_REMOVE(imm, i6mm_chain); | ||||
if (imm->i6mm_maddr != NULL) | if (imm->i6mm_maddr != NULL) | ||||
in6_leavegroup(imm->i6mm_maddr, NULL); | in6_leavegroup(imm->i6mm_maddr, NULL); | ||||
free(imm, M_IP6MADDR); | free(imm, M_IP6MADDR); | ||||
} | } | ||||
/* Check if we need to remove p2p route */ | /* Check if we need to remove p2p route */ | ||||
plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */ | if ((ia->ia_flags & IFA_ROUTE) && ifa_is_p2p(ia)) { | ||||
if (ia->ia_dstaddr.sin6_family != AF_INET6) | |||||
plen = 0; | |||||
if ((ia->ia_flags & IFA_ROUTE) && plen == 128) { | |||||
error = in6_handle_dstaddr_rtrequest(RTM_DELETE, ia); | error = in6_handle_dstaddr_rtrequest(RTM_DELETE, ia); | ||||
if (error != 0) | if (error != 0) | ||||
log(LOG_INFO, "%s: err=%d, destination address delete " | log(LOG_INFO, "%s: err=%d, destination address delete " | ||||
"failed\n", __func__, error); | "failed\n", __func__, error); | ||||
ia->ia_flags &= ~IFA_ROUTE; | ia->ia_flags &= ~IFA_ROUTE; | ||||
} | } | ||||
in6_newaddrmsg(ia, RTM_DELETE); | in6_newaddrmsg(ia, RTM_DELETE); | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | |||||
* 1) Notifies device handler on the first IPv6 address assignment | * 1) Notifies device handler on the first IPv6 address assignment | ||||
* 2) Handle routing table changes for P2P links and route | * 2) Handle routing table changes for P2P links and route | ||||
* 3) Handle routing table changes for address host route | * 3) Handle routing table changes for address host route | ||||
*/ | */ | ||||
static int | static int | ||||
in6_notify_ifa(struct ifnet *ifp, struct in6_ifaddr *ia, | in6_notify_ifa(struct ifnet *ifp, struct in6_ifaddr *ia, | ||||
struct in6_aliasreq *ifra, int hostIsNew) | struct in6_aliasreq *ifra, int hostIsNew) | ||||
{ | { | ||||
int error = 0, plen, ifacount = 0; | int error = 0, ifacount = 0; | ||||
struct ifaddr *ifa; | struct ifaddr *ifa; | ||||
struct sockaddr_in6 *pdst; | struct sockaddr_in6 *pdst; | ||||
char ip6buf[INET6_ADDRSTRLEN]; | char ip6buf[INET6_ADDRSTRLEN]; | ||||
/* | /* | ||||
* Give the interface a chance to initialize | * Give the interface a chance to initialize | ||||
* if this is its first address, | * if this is its first address, | ||||
*/ | */ | ||||
Show All 36 Lines | in6_notify_ifa(struct ifnet *ifp, struct in6_ifaddr *ia, | ||||
/* | /* | ||||
* If a new destination address is specified for a point-to-point | * If a new destination address is specified for a point-to-point | ||||
* interface, install a route to the destination as an interface | * interface, install a route to the destination as an interface | ||||
* direct route. | * direct route. | ||||
* XXX: the logic below rejects assigning multiple addresses on a p2p | * XXX: the logic below rejects assigning multiple addresses on a p2p | ||||
* interface that share the same destination. | * interface that share the same destination. | ||||
*/ | */ | ||||
plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */ | if (!(ia->ia_flags & IFA_ROUTE) && ifa_is_p2p(ia)) { | ||||
if (!(ia->ia_flags & IFA_ROUTE) && plen == 128 && | |||||
ia->ia_dstaddr.sin6_family == AF_INET6) { | |||||
/* | |||||
* Handle the case for ::1 . | |||||
*/ | |||||
if (ifp->if_flags & IFF_LOOPBACK) | |||||
ia->ia_flags |= IFA_RTSELF; | |||||
error = in6_handle_dstaddr_rtrequest(RTM_ADD, ia); | error = in6_handle_dstaddr_rtrequest(RTM_ADD, ia); | ||||
if (error) | if (error) | ||||
goto done; | goto done; | ||||
ia->ia_flags |= IFA_ROUTE; | ia->ia_flags |= IFA_ROUTE; | ||||
} | } | ||||
/* | /* | ||||
* add a loopback route to self if not exists | * add a loopback route to self if not exists | ||||
▲ Show 20 Lines • Show All 1,088 Lines • Show Last 20 Lines |