svn commit: r293544 - in head/sys: net netinet ofed/drivers/infiniband/ulp/ipoib

Alexander V. Chernikov melifaro at FreeBSD.org
Sat Jan 9 16:34:39 UTC 2016


Author: melifaro
Date: Sat Jan  9 16:34:37 2016
New Revision: 293544
URL: https://svnweb.freebsd.org/changeset/base/293544

Log:
  Finish r275196: do not dereference rtentry in if_output() routines.
  
  The only piece of information that is required is rt_flags subset.
  
  In particular, if_loop() requires RTF_REJECT and RTF_BLACKHOLE flags
    to check if this particular mbuf needs to be dropped (and what
    error should be returned).
  Note that if_loop() will always return EHOSTUNREACH for "reject" routes
    regardless of RTF_HOST flag existence. This is due to upcoming routing
    changes where RTF_HOST value won't be available as lookup result.
  
  All other functions require RTF_GATEWAY flag to check if they need
    to return EHOSTUNREACH instead of EHOSTDOWN error.
  
  There are 11 places where non-zero 'struct route' is passed to if_output().
  For most of the callers (forwarding, bpf, arp) does not care about exact
    error value. In fact, the only place where this result is propagated
    is ip_output(). (ip6_output() passes NULL route to nd6_output_ifp()).
  
  Given that, add 3 new 'struct route' flags (RT_REJECT, RT_BLACKHOLE and
    RT_IS_GW) and inline function (rt_update_ro_flags()) to copy necessary
    rte flags to ro_flags. Call this function in ip_output() after looking up/
    verifying rte.
  
  Reviewed by:	ae

Modified:
  head/sys/net/if_arcsubr.c
  head/sys/net/if_ethersubr.c
  head/sys/net/if_fddisubr.c
  head/sys/net/if_fwsubr.c
  head/sys/net/if_iso88025subr.c
  head/sys/net/if_loop.c
  head/sys/net/route.h
  head/sys/netinet/ip_output.c
  head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c

Modified: head/sys/net/if_arcsubr.c
==============================================================================
--- head/sys/net/if_arcsubr.c	Sat Jan  9 16:33:55 2016	(r293543)
+++ head/sys/net/if_arcsubr.c	Sat Jan  9 16:34:37 2016	(r293544)
@@ -113,9 +113,8 @@ arc_output(struct ifnet *ifp, struct mbu
 
 	error = 0;
 #if defined(INET) || defined(INET6)
-	if (ro != NULL && ro->ro_rt != NULL &&
-	    (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0)
-		is_gw = 1;
+	if (ro != NULL)
+		is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
 #endif
 
 	switch (dst->sa_family) {

Modified: head/sys/net/if_ethersubr.c
==============================================================================
--- head/sys/net/if_ethersubr.c	Sat Jan  9 16:33:55 2016	(r293543)
+++ head/sys/net/if_ethersubr.c	Sat Jan  9 16:34:37 2016	(r293544)
@@ -202,7 +202,6 @@ ether_resolve_addr(struct ifnet *ifp, st
 	uint32_t *pflags)
 {
 	struct ether_header *eh;
-	struct rtentry *rt;
 	uint32_t lleflags = 0;
 	int error = 0;
 #if defined(INET) || defined(INET6)
@@ -253,8 +252,7 @@ ether_resolve_addr(struct ifnet *ifp, st
 	}
 
 	if (error == EHOSTDOWN) {
-		rt = (ro != NULL) ? ro->ro_rt : NULL;
-		if (rt != NULL && (rt->rt_flags & RTF_GATEWAY) != 0)
+		if (ro != NULL && (ro->ro_flags & RT_HAS_GW) != 0)
 			error = EHOSTUNREACH;
 	}
 

Modified: head/sys/net/if_fddisubr.c
==============================================================================
--- head/sys/net/if_fddisubr.c	Sat Jan  9 16:33:55 2016	(r293543)
+++ head/sys/net/if_fddisubr.c	Sat Jan  9 16:34:37 2016	(r293544)
@@ -119,9 +119,8 @@ fddi_output(struct ifnet *ifp, struct mb
 	getmicrotime(&ifp->if_lastchange);
 
 #if defined(INET) || defined(INET6)
-	if (ro != NULL && ro->ro_rt != NULL &&
-	    (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0)
-		is_gw = 1;
+	if (ro != NULL)
+		is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
 #endif
 
 	switch (dst->sa_family) {

Modified: head/sys/net/if_fwsubr.c
==============================================================================
--- head/sys/net/if_fwsubr.c	Sat Jan  9 16:33:55 2016	(r293543)
+++ head/sys/net/if_fwsubr.c	Sat Jan  9 16:34:37 2016	(r293544)
@@ -106,9 +106,8 @@ firewire_output(struct ifnet *ifp, struc
 	}
 
 #if defined(INET) || defined(INET6)
-	if (ro != NULL && ro->ro_rt != NULL &&
-	    (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0)
-		is_gw = 1;
+	if (ro != NULL)
+		is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
 #endif
 	/*
 	 * For unicast, we make a tag to store the lladdr of the
@@ -145,10 +144,6 @@ firewire_output(struct ifnet *ifp, struc
 		 * doesn't fit into the arp model.
 		 */
 		if (unicast) {
-			is_gw = 0;
-			if (ro != NULL && ro->ro_rt != NULL &&
-			    (ro->ro_rt->rt_flags & RTF_GATEWAY) != 0)
-				is_gw = 1;
 			error = arpresolve(ifp, is_gw, m, dst, (u_char *) destfw, NULL);
 			if (error)
 				return (error == EWOULDBLOCK ? 0 : error);

Modified: head/sys/net/if_iso88025subr.c
==============================================================================
--- head/sys/net/if_iso88025subr.c	Sat Jan  9 16:33:55 2016	(r293543)
+++ head/sys/net/if_iso88025subr.c	Sat Jan  9 16:34:37 2016	(r293544)
@@ -214,12 +214,8 @@ iso88025_output(struct ifnet *ifp, struc
 	struct rtentry *rt0 = NULL;
 	int is_gw = 0;
 
-	if (ro != NULL) {
-		rt0 = ro->ro_rt;
-		if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0)
-			is_gw = 1;
-	}
-
+	if (ro != NULL)
+		is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
 #ifdef MAC
 	error = mac_ifnet_check_transmit(ifp, m);
 	if (error)

Modified: head/sys/net/if_loop.c
==============================================================================
--- head/sys/net/if_loop.c	Sat Jan  9 16:33:55 2016	(r293543)
+++ head/sys/net/if_loop.c	Sat Jan  9 16:34:37 2016	(r293544)
@@ -202,15 +202,12 @@ looutput(struct ifnet *ifp, struct mbuf 
     struct route *ro)
 {
 	u_int32_t af;
-	struct rtentry *rt = NULL;
 #ifdef MAC
 	int error;
 #endif
 
 	M_ASSERTPKTHDR(m); /* check if we have the packet header */
 
-	if (ro != NULL)
-		rt = ro->ro_rt;
 #ifdef MAC
 	error = mac_ifnet_check_transmit(ifp, m);
 	if (error) {
@@ -219,10 +216,9 @@ looutput(struct ifnet *ifp, struct mbuf 
 	}
 #endif
 
-	if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
+	if (ro != NULL && ro->ro_flags & (RT_REJECT|RT_BLACKHOLE)) {
 		m_freem(m);
-		return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
-		        rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+		return (ro->ro_flags & RT_BLACKHOLE ? 0 : EHOSTUNREACH);
 	}
 
 	if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);

Modified: head/sys/net/route.h
==============================================================================
--- head/sys/net/route.h	Sat Jan  9 16:33:55 2016	(r293543)
+++ head/sys/net/route.h	Sat Jan  9 16:34:37 2016	(r293544)
@@ -64,9 +64,13 @@ struct route {
 
 #define	RT_CACHING_CONTEXT	0x1	/* XXX: not used anywhere */
 #define	RT_NORTREF		0x2	/* doesn't hold reference on ro_rt */
-#define	RT_L2_ME		(1 << RT_L2_ME_BIT)
-#define	RT_MAY_LOOP		(1 << RT_MAY_LOOP_BIT)
-#define	RT_HAS_HEADER		(1 << RT_HAS_HEADER_BIT)
+#define	RT_L2_ME		(1 << RT_L2_ME_BIT)		/* 0x0004 */
+#define	RT_MAY_LOOP		(1 << RT_MAY_LOOP_BIT)		/* 0x0008 */
+#define	RT_HAS_HEADER		(1 << RT_HAS_HEADER_BIT)	/* 0x0010 */
+
+#define	RT_REJECT		0x0020		/* Destination is reject */
+#define	RT_BLACKHOLE		0x0040		/* Destination is blackhole */
+#define	RT_HAS_GW		0x0080		/* Destination has GW  */
 
 struct rt_metrics {
 	u_long	rmx_locks;	/* Kernel must leave these values alone */
@@ -215,6 +219,19 @@ fib_rte_to_nh_flags(int rt_flags)
 	return (res);
 }
 
+/* rte<>ro_flags translation */
+static inline void
+rt_update_ro_flags(struct route *ro)
+{
+	int rt_flags = ro->ro_rt->rt_flags;
+
+	ro->ro_flags &= ~ (RT_REJECT|RT_BLACKHOLE|RT_HAS_GW);
+
+	ro->ro_flags = (rt_flags & RTF_REJECT) ? RT_REJECT : 0;
+	ro->ro_flags |= (rt_flags & RTF_BLACKHOLE) ? RT_BLACKHOLE : 0;
+	ro->ro_flags |= (rt_flags & RTF_GATEWAY) ? RT_HAS_GW : 0;
+}
+
 /*
  * Routing statistics.
  */

Modified: head/sys/netinet/ip_output.c
==============================================================================
--- head/sys/netinet/ip_output.c	Sat Jan  9 16:33:55 2016	(r293543)
+++ head/sys/netinet/ip_output.c	Sat Jan  9 16:34:37 2016	(r293544)
@@ -376,6 +376,7 @@ again:
 		ia = ifatoia(rte->rt_ifa);
 		ifp = rte->rt_ifp;
 		counter_u64_add(rte->rt_pksent, 1);
+		rt_update_ro_flags(ro);
 		if (rte->rt_flags & RTF_GATEWAY)
 			gw = (struct sockaddr_in *)rte->rt_gateway;
 		if (rte->rt_flags & RTF_HOST)

Modified: head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c	Sat Jan  9 16:33:55 2016	(r293543)
+++ head/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c	Sat Jan  9 16:34:37 2016	(r293544)
@@ -1260,16 +1260,12 @@ ipoib_output(struct ifnet *ifp, struct m
 #if defined(INET) || defined(INET6)
 	struct llentry *lle = NULL;
 #endif
-	struct rtentry *rt0 = NULL;
 	struct ipoib_header *eh;
 	int error = 0, is_gw = 0;
 	short type;
 
-	if (ro != NULL) {
-		rt0 = ro->ro_rt;
-		if (rt0 != NULL && (rt0->rt_flags & RTF_GATEWAY) != 0)
-			is_gw = 1;
-	}
+	if (ro != NULL)
+		is_gw = (ro->ro_flags & RT_HAS_GW) != 0;
 #ifdef MAC
 	error = mac_ifnet_check_transmit(ifp, m);
 	if (error)


More information about the svn-src-head mailing list