FreeBSD/sys/netinet6/in6.c
/*
 * Do link-level ifa job:
 * 1) Add lle entry for added address
 * 2) Notifies routing socket users about new address
 * 3) join appropriate multicast group
 * 4) start DAD if enabled
 */
Do link-level ifa job:
1) Add lle entry for added address
2) Notifies routing socket users about new address
3) join appropriate multicast group
4) start DAD if enabled
Do link - level ifa job : 1 ) Add lle entry for added address 2 ) Notifies routing socket users about new address 3 ) join appropriate multicast group 4 ) start DAD if enabled
static int
in6_broadcast_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
    struct in6_ifaddr *ia, int flags)
{
	struct in6_multi *in6m_sol;
	int error = 0;
	if ((error = nd6_add_ifa_lle(ia)) != 0) {
		in6_purgeaddr(&ia->ia_ifa);
		ifa_free(&ia->ia_ifa);
		return (error);
	}
	in6m_sol = NULL;
	if ((ifp->if_flags & IFF_MULTICAST) != 0) {
		error = in6_update_ifa_join_mc(ifp, ifra, ia, flags, &in6m_sol);
		if (error != 0) {
			in6_purgeaddr(&ia->ia_ifa);
			ifa_free(&ia->ia_ifa);
			return (error);
		}
	}
	if ((ia->ia6_flags & IN6_IFF_TENTATIVE)) {
		int delay, mindelay, maxdelay;
		delay = 0;
		if ((flags & IN6_IFAUPDATE_DADDELAY)) {
			mindelay = 0;
			if (in6m_sol != NULL &&
			    in6m_sol->in6m_state == MLD_REPORTING_MEMBER) {
				mindelay = in6m_sol->in6m_timer;
			}
			maxdelay = MAX_RTR_SOLICITATION_DELAY * hz;
			if (maxdelay - mindelay == 0)
				delay = 0;
			else {
				delay =
				    (arc4random() % (maxdelay - mindelay)) +
				    mindelay;
			}
		}
		nd6_dad_start((struct ifaddr *)ia, delay);
	}
	in6_newaddrmsg(ia, RTM_ADD);
	ifa_free(&ia->ia_ifa);
	return (error);
}
static int in6_broadcast_ifa ( struct ifnet * ifp , struct in6_aliasreq * ifra , struct in6_ifaddr * ia , int flags ) { struct in6_multi * in6m_sol ; int error = 0 ; if ( ( error = nd6_add_ifa_lle ( ia ) ) != 0 ) { in6_purgeaddr ( & ia -> ia_ifa ) ; ifa_free ( & ia -> ia_ifa ) ; return ( error ) ; } in6m_sol = NULL ; if ( ( ifp -> if_flags & IFF_MULTICAST ) != 0 ) { error = in6_update_ifa_join_mc ( ifp , ifra , ia , flags , & in6m_sol ) ; if ( error != 0 ) { in6_purgeaddr ( & ia -> ia_ifa ) ; ifa_free ( & ia -> ia_ifa ) ; return ( error ) ; } } if ( ( ia -> ia6_flags & IN6_IFF_TENTATIVE ) ) { int delay , mindelay , maxdelay ; delay = 0 ; if ( ( flags & IN6_IFAUPDATE_DADDELAY ) ) { mindelay = 0 ; if ( in6m_sol != NULL && in6m_sol -> in6m_state == MLD_REPORTING_MEMBER ) { mindelay = in6m_sol -> in6m_timer ; } maxdelay = MAX_RTR_SOLICITATION_DELAY * hz ; if ( maxdelay - mindelay == 0 ) delay = 0 ; else { delay = ( arc4random ( ) % ( maxdelay - mindelay ) ) + mindelay ; } } nd6_dad_start ( ( struct ifaddr * ) ia , delay ) ; } in6_newaddrmsg ( ia , RTM_ADD ) ; ifa_free ( & ia -> ia_ifa ) ; return ( error ) ; }
Do link-level ifa job:
 1) Add lle entry for added address
 2) Notifies routing socket users about new address
 3) join appropriate multicast group
 4) start DAD if enabled
Do link - level ifa job : 1 ) Add lle entry for added address 2 ) Notifies routing socket users about new address 3 ) join appropriate multicast group 4 ) start DAD if enabled
/* Add local address to lltable, if necessary (ex. on p2p link). */ /* Join necessary multicast groups. */ /* Perform DAD, if the address is TENTATIVE. */ /*
			 * We need to impose a delay before sending an NS
			 * for DAD.  Check if we also needed a delay for the
			 * corresponding MLD message.  If we did, the delay
			 * should be larger than the MLD delay (this could be
			 * relaxed a bit, but this simple logic is at least
			 * safe).
			 * XXX: Break data hiding guidelines and look at
			 * state for the solicited multicast group.
			 */