Beispiel #1
0
/*
 * Performs IPv4 route table lookup on @dst. Returns 0 on success.
 * Stores nexthop info provided @pnh4 structure.
 * Note that
 * - nh_ifp cannot be safely dereferenced
 * - nh_ifp represents logical transmit interface (rt_ifp) (e.g. if
 *   looking up address on interface "ix0" pointer to "lo0" interface
 *   will be returned instead of "ix0")
 * - nh_ifp represents "address" interface if NHR_IFAIF flag is passed
 * - howewer mtu from "transmit" interface will be returned.
 */
int
fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flags,
    uint32_t flowid, struct nhop4_basic *pnh4)
{
	struct radix_node_head *rh;
	struct radix_node *rn;
	struct sockaddr_in sin;
	struct rtentry *rte;

	KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_basic: bad fibnum"));
	rh = rt_tables_get_rnh(fibnum, AF_INET);
	if (rh == NULL)
		return (ENOENT);

	/* Prepare lookup key */
	memset(&sin, 0, sizeof(sin));
	sin.sin_len = sizeof(struct sockaddr_in);
	sin.sin_addr = dst;

	RADIX_NODE_HEAD_RLOCK(rh);
	rn = rh->rnh_matchaddr((void *)&sin, rh);
	if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
		rte = RNTORT(rn);
		/* Ensure route & ifp is UP */
		if (RT_LINK_IS_UP(rte->rt_ifp)) {
			fib4_rte_to_nh_basic(rte, dst, flags, pnh4);
			RADIX_NODE_HEAD_RUNLOCK(rh);

			return (0);
		}
	}
	RADIX_NODE_HEAD_RUNLOCK(rh);

	return (ENOENT);
}
Beispiel #2
0
void
bootpboot_p_rtlist(void)
{
	struct radix_node_head *rnh;

	printf("Routing table:\n");
	rnh = rt_tables_get_rnh(0, AF_INET);
	if (rnh == NULL)
		return;
	RADIX_NODE_HEAD_RLOCK(rnh);	/* could sleep XXX */
	bootpboot_p_tree(rnh->rnh_treetop);
	RADIX_NODE_HEAD_RUNLOCK(rnh);
}
Beispiel #3
0
/*
 * Performs IPv6 route table lookup on @dst. Returns 0 on success.
 * Stores extended nexthop info into provided @pnh6 structure.
 * Note that
 * - nh_ifp cannot be safely dereferenced unless NHR_REF is specified.
 * - in that case you need to call fib6_free_nh_ext()
 * - nh_ifp represents logical transmit interface (rt_ifp) by default
 * - nh_ifp represents "address" interface if NHR_IFAIF flag is passed
 * - mtu from logical transmit interface will be returned.
 * - scope will be embedded in nh_addr
 */
int
fib6_lookup_nh_ext(uint32_t fibnum, const struct in6_addr *dst,uint32_t scopeid,
    uint32_t flags, uint32_t flowid, struct nhop6_extended *pnh6)
{
	struct radix_node_head *rh;
	struct radix_node *rn;
	struct sockaddr_in6 sin6;
	struct rtentry *rte;

	KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh_ext: bad fibnum"));
	rh = rt_tables_get_rnh(fibnum, AF_INET6);
	if (rh == NULL)
		return (ENOENT);

	/* Prepare lookup key */
	memset(&sin6, 0, sizeof(sin6));
	sin6.sin6_len = sizeof(struct sockaddr_in6);
	sin6.sin6_addr = *dst;
	/* Assume scopeid is valid and embed it directly */
	if (IN6_IS_SCOPE_LINKLOCAL(dst))
		sin6.sin6_addr.s6_addr16[1] = htons(scopeid & 0xffff);

	RADIX_NODE_HEAD_RLOCK(rh);
	rn = rh->rnh_matchaddr((void *)&sin6, rh);
	if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
		rte = RNTORT(rn);
		/* Ensure route & ifp is UP */
		if (RT_LINK_IS_UP(rte->rt_ifp)) {
			fib6_rte_to_nh_extended(rte, &sin6.sin6_addr, flags,
			    pnh6);
			if ((flags & NHR_REF) != 0) {
				/* TODO: Do lwref on egress ifp's */
			}
			RADIX_NODE_HEAD_RUNLOCK(rh);

			return (0);
		}
	}
	RADIX_NODE_HEAD_RUNLOCK(rh);

	return (ENOENT);
}
Beispiel #4
0
/*
 * Used by the filesystems to determine if a given network address
 * (passed in 'nam') is present in their exports list, returns a pointer
 * to struct netcred so that the filesystem can examine it for
 * access rights (read/write/etc).
 */
static struct netcred *
vfs_export_lookup(struct mount *mp, struct sockaddr *nam)
{
	struct netexport *nep;
	register struct netcred *np;
	register struct radix_node_head *rnh;
	struct sockaddr *saddr;

	nep = mp->mnt_export;
	if (nep == NULL)
		return (NULL);
	np = NULL;
	if (mp->mnt_flag & MNT_EXPORTED) {
		/*
		 * Lookup in the export list first.
		 */
		if (nam != NULL) {
			saddr = nam;
			rnh = nep->ne_rtable[saddr->sa_family];
			if (rnh != NULL) {
				RADIX_NODE_HEAD_RLOCK(rnh);
				np = (struct netcred *)
				    (*rnh->rnh_matchaddr)(saddr, rnh);
				RADIX_NODE_HEAD_RUNLOCK(rnh);
				if (np && np->netc_rnodes->rn_flags & RNF_ROOT)
					np = NULL;
			}
		}
		/*
		 * If no address match, use the default if it exists.
		 */
		if (np == NULL && mp->mnt_flag & MNT_DEFEXPORTED)
			np = &nep->ne_defexported;
	}
	return (np);
}