svn commit: r293657 - in head/sys: net netinet netinet6

Alexander V. Chernikov melifaro at FreeBSD.org
Mon Jan 11 08:45:30 UTC 2016


Author: melifaro
Date: Mon Jan 11 08:45:28 2016
New Revision: 293657
URL: https://svnweb.freebsd.org/changeset/base/293657

Log:
  Bring RADIX_MPATH support to new routing KPI to ease migration.
  
  Move actual rte selection process from rtalloc_mpath_fib()
    to the rt_path_selectrte() function. Add public
    rt_mpath_select() to use in fibX_lookup_ functions.

Modified:
  head/sys/net/radix_mpath.c
  head/sys/net/radix_mpath.h
  head/sys/netinet/in_fib.c
  head/sys/netinet6/in6_fib.c

Modified: head/sys/net/radix_mpath.c
==============================================================================
--- head/sys/net/radix_mpath.c	Mon Jan 11 08:00:13 2016	(r293656)
+++ head/sys/net/radix_mpath.c	Mon Jan 11 08:45:28 2016	(r293657)
@@ -197,14 +197,49 @@ rt_mpath_conflict(struct radix_node_head
 	return (0);
 }
 
-void
-rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum)
+static struct rtentry *
+rt_mpath_selectrte(struct rtentry *rte, uint32_t hash)
 {
 	struct radix_node *rn0, *rn;
 	u_int32_t n;
 	struct rtentry *rt;
 	int64_t weight;
 
+	/* beyond here, we use rn as the master copy */
+	rn0 = rn = (struct radix_node *)rte;
+	n = rn_mpath_count(rn0);
+
+	/* gw selection by Modulo-N Hash (RFC2991) XXX need improvement? */
+	hash += hashjitter;
+	hash %= n;
+	for (weight = abs((int32_t)hash), rt = rte;
+	     weight >= rt->rt_weight && rn; 
+	     weight -= rt->rt_weight) {
+		
+		/* stay within the multipath routes */
+		if (rn->rn_dupedkey && rn->rn_mask != rn->rn_dupedkey->rn_mask)
+			break;
+		rn = rn->rn_dupedkey;
+		rt = (struct rtentry *)rn;
+	}
+
+	return (rt);
+}
+
+struct rtentry *
+rt_mpath_select(struct rtentry *rte, uint32_t hash)
+{
+	if (rn_mpath_next((struct radix_node *)rte) == NULL)
+		return (rte);
+
+	return (rt_mpath_selectrte(rte, hash));
+}
+
+void
+rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum)
+{
+	struct rtentry *rt;
+
 	/*
 	 * XXX we don't attempt to lookup cached route again; what should
 	 * be done for sendto(3) case?
@@ -222,34 +257,18 @@ rtalloc_mpath_fib(struct route *ro, uint
 		return;
 	}
 
-	/* beyond here, we use rn as the master copy */
-	rn0 = rn = (struct radix_node *)ro->ro_rt;
-	n = rn_mpath_count(rn0);
-
-	/* gw selection by Modulo-N Hash (RFC2991) XXX need improvement? */
-	hash += hashjitter;
-	hash %= n;
-	for (weight = abs((int32_t)hash), rt = ro->ro_rt;
-	     weight >= rt->rt_weight && rn; 
-	     weight -= rt->rt_weight) {
-		
-		/* stay within the multipath routes */
-		if (rn->rn_dupedkey && rn->rn_mask != rn->rn_dupedkey->rn_mask)
-			break;
-		rn = rn->rn_dupedkey;
-		rt = (struct rtentry *)rn;
-	}
+	rt = rt_mpath_selectrte(ro->ro_rt, hash);
 	/* XXX try filling rt_gwroute and avoid unreachable gw  */
 
 	/* gw selection has failed - there must be only zero weight routes */
-	if (!rn) {
+	if (!rt) {
 		RT_UNLOCK(ro->ro_rt);
 		ro->ro_rt = NULL;
 		return;
 	}
 	if (ro->ro_rt != rt) {
 		RTFREE_LOCKED(ro->ro_rt);
-		ro->ro_rt = (struct rtentry *)rn;
+		ro->ro_rt = rt;
 		RT_LOCK(ro->ro_rt);
 		RT_ADDREF(ro->ro_rt);
 

Modified: head/sys/net/radix_mpath.h
==============================================================================
--- head/sys/net/radix_mpath.h	Mon Jan 11 08:00:13 2016	(r293656)
+++ head/sys/net/radix_mpath.h	Mon Jan 11 08:45:28 2016	(r293657)
@@ -52,6 +52,7 @@ int rt_mpath_conflict(struct radix_node_
     struct sockaddr *);
 void rtalloc_mpath_fib(struct route *, u_int32_t, u_int);
 #define rtalloc_mpath(_route, _hash) rtalloc_mpath_fib((_route), (_hash), 0)
+struct rtentry *rt_mpath_select(struct rtentry *, uint32_t);
 struct radix_node *rn_mpath_lookup(void *, void *,
     struct radix_node_head *);
 int rt_mpath_deldup(struct rtentry *, struct rtentry *);

Modified: head/sys/netinet/in_fib.c
==============================================================================
--- head/sys/netinet/in_fib.c	Mon Jan 11 08:00:13 2016	(r293656)
+++ head/sys/netinet/in_fib.c	Mon Jan 11 08:45:28 2016	(r293657)
@@ -200,6 +200,13 @@ fib4_lookup_nh_ext(uint32_t fibnum, stru
 	rn = rh->rnh_matchaddr((void *)&sin, rh);
 	if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
 		rte = RNTORT(rn);
+#ifdef RADIX_MPATH
+		rte = rt_mpath_select(rte, flowid);
+		if (rte == NULL) {
+			RADIX_NODE_HEAD_RUNLOCK(rh);
+			return (ENOENT);
+		}
+#endif
 		/* Ensure route & ifp is UP */
 		if (RT_LINK_IS_UP(rte->rt_ifp)) {
 			fib4_rte_to_nh_extended(rte, dst, flags, pnh4);

Modified: head/sys/netinet6/in6_fib.c
==============================================================================
--- head/sys/netinet6/in6_fib.c	Mon Jan 11 08:00:13 2016	(r293656)
+++ head/sys/netinet6/in6_fib.c	Mon Jan 11 08:45:28 2016	(r293657)
@@ -241,6 +241,13 @@ fib6_lookup_nh_ext(uint32_t fibnum, cons
 	rn = rh->rnh_matchaddr((void *)&sin6, rh);
 	if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
 		rte = RNTORT(rn);
+#ifdef RADIX_MPATH
+		rte = rt_mpath_select(rte, flowid);
+		if (rte == NULL) {
+			RADIX_NODE_HEAD_RUNLOCK(rh);
+			return (ENOENT);
+		}
+#endif
 		/* Ensure route & ifp is UP */
 		if (RT_LINK_IS_UP(rte->rt_ifp)) {
 			fib6_rte_to_nh_extended(rte, &sin6.sin6_addr, flags,


More information about the svn-src-all mailing list