Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Aug 2015 18:27:29 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r287065 - in projects/routing/sys: net netinet netinet6
Message-ID:  <201508231827.t7NIRTkk047337@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Sun Aug 23 18:27:28 2015
New Revision: 287065
URL: https://svnweb.freebsd.org/changeset/base/287065

Log:
  Convert lle rtchecks to use new routing API. For inet/ case, this involves
    reverting r225947 which seem to be pretty strange commit and should be
    reverted in HEAD ad well.

Modified:
  projects/routing/sys/net/rt_nhops.c
  projects/routing/sys/net/rt_nhops.h
  projects/routing/sys/netinet/in.c
  projects/routing/sys/netinet6/in6.c

Modified: projects/routing/sys/net/rt_nhops.c
==============================================================================
--- projects/routing/sys/net/rt_nhops.c	Sun Aug 23 18:26:42 2015	(r287064)
+++ projects/routing/sys/net/rt_nhops.c	Sun Aug 23 18:27:28 2015	(r287065)
@@ -498,6 +498,42 @@ fib4_lookup_nh_basic(uint32_t fibnum, st
 	return (ENOENT);
 }
 
+int
+fib4_lookup_nh_ifp(uint32_t fibnum, struct in_addr dst, uint32_t flowid,
+    struct nhop4_basic *pnh4)
+{
+	struct radix_node_head *rnh;
+	struct radix_node *rn;
+	struct sockaddr_in sin;
+	struct rtentry *rte;
+
+	KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_ifp: bad fibnum"));
+	rnh = rt_tables_get_rnh(fibnum, AF_INET);
+	if (rnh == 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(rnh);
+	rn = rnh->rnh_matchaddr((void *)&sin, rnh);
+	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, pnh4);
+			RADIX_NODE_HEAD_RUNLOCK(rnh);
+			pnh4->nh_ifp = rte->rt_ifp;
+			return (0);
+		}
+	}
+	RADIX_NODE_HEAD_RUNLOCK(rnh);
+
+	return (ENOENT);
+}
+
 /*
  * Performs IPv4 route table lookup on @dst. Returns 0 on success.
  * Stores extende nexthop info provided @pnh4 structure.

Modified: projects/routing/sys/net/rt_nhops.h
==============================================================================
--- projects/routing/sys/net/rt_nhops.h	Sun Aug 23 18:26:42 2015	(r287064)
+++ projects/routing/sys/net/rt_nhops.h	Sun Aug 23 18:27:28 2015	(r287065)
@@ -169,6 +169,7 @@ struct nhop4_extended {
 	uint64_t	spare2[2];
 };
 
+/* Does not differ from nhop6_basic */
 struct nhop6_extended {
 	struct ifnet	*nh_ifp;	/* Logical egress interface */
 	uint16_t	nh_mtu;		/* nexthop mtu */
@@ -178,6 +179,27 @@ struct nhop6_extended {
 	uint64_t	spare2[2];
 };
 
+/* route info used for control plane purposes */
+struct rt4_basic {
+	struct in_addr	rt_addr;	/* route prefix */
+	struct in_addr	rt_gateway;	/* GW used */
+	int		rt_flags;	/* Copy of rte flags */
+	uint16_t	rt_mtu;
+	uint16_t	rt_nhop;	/* nexthop id (might bi mpath) */
+	struct in_addr	rt_mask;	/* route mask */
+	uint16_t	spare[2];
+};
+
+struct rt6_basic {
+	struct in6_addr	rt_addr;
+	struct in6_addr	rt_gateway;
+	int		rt_flags;
+	uint16_t	rt_mtu;
+	uint16_t	rt_nhop;
+	uint8_t		rt_mask;
+	uint8_t		spare[7];
+};
+
 struct nhopu_extended {
 	union {
 		struct nhop4_extended	nh4;
@@ -200,6 +222,8 @@ struct route_compat {
 	int			ro_flags;
 };
 
+int fib4_lookup_nh_ifp(uint32_t fibnum, struct in_addr dst, uint32_t flowid,
+    struct nhop4_basic *pnh4);
 int fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flowid,
     struct nhop4_basic *pnh4);
 int fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst,

Modified: projects/routing/sys/netinet/in.c
==============================================================================
--- projects/routing/sys/netinet/in.c	Sun Aug 23 18:26:42 2015	(r287064)
+++ projects/routing/sys/netinet/in.c	Sun Aug 23 18:27:28 2015	(r287065)
@@ -58,7 +58,6 @@ __FBSDID("$FreeBSD$");
 #include <net/if_llatbl.h>
 #include <net/if_types.h>
 #include <net/route.h>
-#include <net/route_internal.h>
 #include <net/vnet.h>
 
 #include <netinet/if_ether.h>
@@ -71,6 +70,8 @@ __FBSDID("$FreeBSD$");
 #include <netinet/udp.h>
 #include <netinet/udp_var.h>
 
+#include <net/rt_nhops.h>
+
 static int in_aifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *);
 static int in_difaddr_ioctl(caddr_t, struct ifnet *, struct thread *);
 
@@ -1037,16 +1038,14 @@ in_lltable_prefix_free(struct lltable *l
 static int
 in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
 {
-	struct rtentry *rt;
+	struct nhop4_basic nh4;
+	struct in_addr dst;
 
 	KASSERT(l3addr->sa_family == AF_INET,
 	    ("sin_family %d", l3addr->sa_family));
 
-	/* XXX rtalloc1_fib should take a const param */
-	rt = rtalloc1_fib(__DECONST(struct sockaddr *, l3addr), 0, 0,
-	    ifp->if_fib);
-
-	if (rt == NULL)
+	dst = ((const struct sockaddr_in *)l3addr)->sin_addr;
+	if (fib4_lookup_nh_ifp(ifp->if_fib, dst, 0, &nh4) != 0)
 		return (EINVAL);
 
 	/*
@@ -1054,57 +1053,26 @@ in_lltable_rtcheck(struct ifnet *ifp, u_
 	 * address, which is a special route inserted by some implementation
 	 * such as MANET, and the interface is of the correct type, then
 	 * allow for ARP to proceed.
+	 * XXX: !RTF_HOST condition (temporarily) skipped.
 	 */
-	if (rt->rt_flags & RTF_GATEWAY) {
-		if (!(rt->rt_flags & RTF_HOST) || !rt->rt_ifp ||
-		    rt->rt_ifp->if_type != IFT_ETHER ||
-		    (rt->rt_ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0 ||
-		    memcmp(rt->rt_gateway->sa_data, l3addr->sa_data,
-		    sizeof(in_addr_t)) != 0) {
-			RTFREE_LOCKED(rt);
-			return (EINVAL);
-		}
-	}
-
-	/*
-	 * Make sure that at least the destination address is covered
-	 * by the route. This is for handling the case where 2 or more
-	 * interfaces have the same prefix. An incoming packet arrives
-	 * on one interface and the corresponding outgoing packet leaves
-	 * another interface.
-	 */
-	if (!(rt->rt_flags & RTF_HOST) && rt->rt_ifp != ifp) {
-		const char *sa, *mask, *addr, *lim;
-		int len;
-
-		mask = (const char *)rt_mask(rt);
-		/*
-		 * Just being extra cautious to avoid some custom
-		 * code getting into trouble.
-		 */
-		if (mask == NULL) {
-			RTFREE_LOCKED(rt);
+	if (nh4.nh_flags & NHF_GATEWAY) {
+		if (nh4.nh_ifp->if_type != IFT_ETHER ||
+		    (nh4.nh_ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0 ||
+		    nh4.nh_addr.s_addr != dst.s_addr) {
 			return (EINVAL);
 		}
 
-		sa = (const char *)rt_key(rt);
-		addr = (const char *)l3addr;
-		len = ((const struct sockaddr_in *)l3addr)->sin_len;
-		lim = addr + len;
+		return (0);
+	}
 
-		for ( ; addr < lim; sa++, mask++, addr++) {
-			if ((*sa ^ *addr) & *mask) {
+	if (((nh4.nh_flags & NHF_GATEWAY) != 0) || nh4.nh_ifp != ifp) {
 #ifdef DIAGNOSTIC
-				log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
-				    inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
+		log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
+		    inet_ntoa(dst));
 #endif
-				RTFREE_LOCKED(rt);
-				return (EINVAL);
-			}
-		}
+		return (EINVAL);
 	}
 
-	RTFREE_LOCKED(rt);
 	return (0);
 }
 

Modified: projects/routing/sys/netinet6/in6.c
==============================================================================
--- projects/routing/sys/netinet6/in6.c	Sun Aug 23 18:26:42 2015	(r287064)
+++ projects/routing/sys/netinet6/in6.c	Sun Aug 23 18:27:28 2015	(r287065)
@@ -110,6 +110,8 @@ __FBSDID("$FreeBSD$");
 #include <netinet6/scope6_var.h>
 #include <netinet6/in6_pcb.h>
 
+#include <net/rt_nhops.h>
+
 VNET_DECLARE(int, icmp6_nodeinfo_oldmcprefix);
 #define V_icmp6_nodeinfo_oldmcprefix	VNET(icmp6_nodeinfo_oldmcprefix)
 
@@ -2146,17 +2148,20 @@ in6_lltable_rtcheck(struct ifnet *ifp,
 		    u_int flags,
 		    const struct sockaddr *l3addr)
 {
-	struct rtentry *rt;
+	struct nhop6_basic nh6;
+	struct in6_addr dst;
+	uint32_t scopeid;
+	int error;
 	char ip6buf[INET6_ADDRSTRLEN];
 
 	KASSERT(l3addr->sa_family == AF_INET6,
 	    ("sin_family %d", l3addr->sa_family));
 
 	/* Our local addresses are always only installed on the default FIB. */
-	/* XXX rtalloc1 should take a const param */
-	rt = in6_rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0,
-	    RT_DEFAULT_FIB);
-	if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) || rt->rt_ifp != ifp) {
+
+	in6_splitscope(&((const struct sockaddr_in6 *)l3addr)->sin6_addr, &dst, &scopeid);
+	error = fib6_lookup_nh_ifp(RT_DEFAULT_FIB, &dst, scopeid, 0, &nh6);
+	if (error != 0 || ((nh6.nh_flags & NHF_GATEWAY) != 0) || nh6.nh_ifp != ifp) {
 		struct ifaddr *ifa;
 		/*
 		 * Create an ND6 cache for an IPv6 neighbor
@@ -2166,17 +2171,12 @@ in6_lltable_rtcheck(struct ifnet *ifp,
 		ifa = ifaof_ifpforaddr(__DECONST(struct sockaddr *, l3addr), ifp);
 		if (ifa != NULL) {
 			ifa_free(ifa);
-			if (rt != NULL)
-				RTFREE_LOCKED(rt);
 			return 0;
 		}
 		log(LOG_INFO, "IPv6 address: \"%s\" is not on the network\n",
 		    ip6_sprintf(ip6buf, &((const struct sockaddr_in6 *)l3addr)->sin6_addr));
-		if (rt != NULL)
-			RTFREE_LOCKED(rt);
 		return EINVAL;
 	}
-	RTFREE_LOCKED(rt);
 	return 0;
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508231827.t7NIRTkk047337>