FreeBSD/sys/netinet/in.c
/*
 * Check if we have a route for the given prefix already or add one accordingly.
 */
Check if we have a route for the given prefix already or add one accordingly.
Check if we have a route for the given prefix already or add one accordingly .
int
in_addprefix(struct in_ifaddr *target, int flags)
{
	struct rm_priotracker in_ifa_tracker;
	struct in_ifaddr *ia;
	struct in_addr prefix, mask, p, m;
	int error;
	if ((flags & RTF_HOST) != 0) {
		prefix = target->ia_dstaddr.sin_addr;
		mask.s_addr = 0;
	} else {
		prefix = target->ia_addr.sin_addr;
		mask = target->ia_sockmask.sin_addr;
		prefix.s_addr &= mask.s_addr;
	}
	IN_IFADDR_RLOCK(&in_ifa_tracker);
	TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
		if (rtinitflags(ia)) {
			p = ia->ia_dstaddr.sin_addr;
			if (prefix.s_addr != p.s_addr)
				continue;
		} else {
			p = ia->ia_addr.sin_addr;
			m = ia->ia_sockmask.sin_addr;
			p.s_addr &= m.s_addr;
			if (prefix.s_addr != p.s_addr ||
			    mask.s_addr != m.s_addr)
				continue;
		}
		if (target->ia_ifp->if_fib != ia->ia_ifp->if_fib)
			continue;
		if (ia->ia_flags & IFA_ROUTE) {
#ifdef RADIX_MPATH
			if (ia->ia_addr.sin_addr.s_addr ==
			    target->ia_addr.sin_addr.s_addr) {
				IN_IFADDR_RUNLOCK(&in_ifa_tracker);
				return (EEXIST);
			} else
				break;
#endif
			if (V_nosameprefix) {
				IN_IFADDR_RUNLOCK(&in_ifa_tracker);
				return (EEXIST);
			} else {
				int fibnum;
				fibnum = V_rt_add_addr_allfibs ? RT_ALL_FIBS :
					target->ia_ifp->if_fib;
				rt_addrmsg(RTM_ADD, &target->ia_ifa, fibnum);
				IN_IFADDR_RUNLOCK(&in_ifa_tracker);
				return (0);
			}
		}
	}
	IN_IFADDR_RUNLOCK(&in_ifa_tracker);
	error = rtinit(&target->ia_ifa, (int)RTM_ADD, flags);
	if (!error)
		target->ia_flags |= IFA_ROUTE;
	return (error);
}
int in_addprefix ( struct in_ifaddr * target , int flags ) { struct rm_priotracker in_ifa_tracker ; struct in_ifaddr * ia ; struct in_addr prefix , mask , p , m ; int error ; if ( ( flags & RTF_HOST ) != 0 ) { prefix = target -> ia_dstaddr . sin_addr ; mask . s_addr = 0 ; } else { prefix = target -> ia_addr . sin_addr ; mask = target -> ia_sockmask . sin_addr ; prefix . s_addr &= mask . s_addr ; } IN_IFADDR_RLOCK ( & in_ifa_tracker ) ; TAILQ_FOREACH ( ia , & V_in_ifaddrhead , ia_link ) { if ( rtinitflags ( ia ) ) { p = ia -> ia_dstaddr . sin_addr ; if ( prefix . s_addr != p . s_addr ) continue ; } else { p = ia -> ia_addr . sin_addr ; m = ia -> ia_sockmask . sin_addr ; p . s_addr &= m . s_addr ; if ( prefix . s_addr != p . s_addr || mask . s_addr != m . s_addr ) continue ; } if ( target -> ia_ifp -> if_fib != ia -> ia_ifp -> if_fib ) continue ; if ( ia -> ia_flags & IFA_ROUTE ) { #ifdef RADIX_MPATH if ( ia -> ia_addr . sin_addr . s_addr == target -> ia_addr . sin_addr . s_addr ) { IN_IFADDR_RUNLOCK ( & in_ifa_tracker ) ; return ( EEXIST ) ; } else break ; #endif if ( V_nosameprefix ) { IN_IFADDR_RUNLOCK ( & in_ifa_tracker ) ; return ( EEXIST ) ; } else { int fibnum ; fibnum = V_rt_add_addr_allfibs ? RT_ALL_FIBS : target -> ia_ifp -> if_fib ; rt_addrmsg ( RTM_ADD , & target -> ia_ifa , fibnum ) ; IN_IFADDR_RUNLOCK ( & in_ifa_tracker ) ; return ( 0 ) ; } } } IN_IFADDR_RUNLOCK ( & in_ifa_tracker ) ; error = rtinit ( & target -> ia_ifa , ( int ) RTM_ADD , flags ) ; if ( ! error ) target -> ia_flags |= IFA_ROUTE ; return ( error ) ; }
Check if we have a route for the given prefix already or add one accordingly.
Check if we have a route for the given prefix already or add one accordingly .
/* Look for an existing address with the same prefix, mask, and fib */ /*
		 * If we got a matching prefix route inserted by other
		 * interface address, we are done here.
		 */ /*
	 * No-one seem to have this prefix route, so we try to insert it.
	 */