Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Jun 2017 09:21:25 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r319408 - stable/11/sys/netinet
Message-ID:  <201706010921.v519LPKj043564@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Thu Jun  1 09:21:25 2017
New Revision: 319408
URL: https://svnweb.freebsd.org/changeset/base/319408

Log:
  MFC r317597:
  
  Allow SCTP to use the hostcache.
  
  This patch allows the MTU stored in the hostcache to be used as an
  initial value for SCTP paths. When an ICMP PTB message is received,
  store the MTU in the hostcache.

Modified:
  stable/11/sys/netinet/sctp_pcb.c
  stable/11/sys/netinet/sctp_usrreq.c
  stable/11/sys/netinet/sctputil.c
  stable/11/sys/netinet/sctputil.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/netinet/sctp_pcb.c
==============================================================================
--- stable/11/sys/netinet/sctp_pcb.c	Thu Jun  1 09:18:03 2017	(r319407)
+++ stable/11/sys/netinet/sctp_pcb.c	Thu Jun  1 09:21:25 2017	(r319408)
@@ -3933,6 +3933,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct soc
 	    stcb->asoc.vrf_id,
 	    stcb->sctp_ep->fibnum);
 
+	net->src_addr_selected = 0;
 	if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
 		/* Get source address */
 		net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep,
@@ -3942,18 +3943,18 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct soc
 		    0,
 		    stcb->asoc.vrf_id);
 		if (net->ro._s_addr != NULL) {
+			uint32_t imtu, rmtu, hcmtu;
+
 			net->src_addr_selected = 1;
 			/* Now get the interface MTU */
 			if (net->ro._s_addr->ifn_p != NULL) {
-				net->mtu = SCTP_GATHER_MTU_FROM_INTFC(net->ro._s_addr->ifn_p);
+				imtu = SCTP_GATHER_MTU_FROM_INTFC(net->ro._s_addr->ifn_p);
+			} else {
+				imtu = 0;
 			}
-		} else {
-			net->src_addr_selected = 0;
-		}
-		if (net->mtu > 0) {
-			uint32_t rmtu;
-
 			rmtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, net->ro.ro_rt);
+			hcmtu = sctp_hc_get_mtu(&net->ro._l_addr, stcb->sctp_ep->fibnum);
+			net->mtu = sctp_min_mtu(hcmtu, rmtu, imtu);
 			if (rmtu == 0) {
 				/*
 				 * Start things off to match mtu of
@@ -3961,17 +3962,8 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct soc
 				 */
 				SCTP_SET_MTU_OF_ROUTE(&net->ro._l_addr.sa,
 				    net->ro.ro_rt, net->mtu);
-			} else {
-				/*
-				 * we take the route mtu over the interface,
-				 * since the route may be leading out the
-				 * loopback, or a different interface.
-				 */
-				net->mtu = rmtu;
 			}
 		}
-	} else {
-		net->src_addr_selected = 0;
 	}
 	if (net->mtu == 0) {
 		switch (newaddr->sa_family) {

Modified: stable/11/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/11/sys/netinet/sctp_usrreq.c	Thu Jun  1 09:18:03 2017	(r319407)
+++ stable/11/sys/netinet/sctp_usrreq.c	Thu Jun  1 09:21:25 2017	(r319408)
@@ -225,6 +225,11 @@ sctp_notify(struct sctp_inpcb *inp,
 		}
 		if (net->mtu > next_mtu) {
 			net->mtu = next_mtu;
+			if (net->port) {
+				sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu + sizeof(struct udphdr));
+			} else {
+				sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu);
+			}
 		}
 		/* Update the association MTU */
 		if (stcb->asoc.smallest_mtu > next_mtu) {

Modified: stable/11/sys/netinet/sctputil.c
==============================================================================
--- stable/11/sys/netinet/sctputil.c	Thu Jun  1 09:18:03 2017	(r319407)
+++ stable/11/sys/netinet/sctputil.c	Thu Jun  1 09:21:25 2017	(r319408)
@@ -49,6 +49,9 @@ __FBSDID("$FreeBSD$");
 #include <netinet/sctp_auth.h>
 #include <netinet/sctp_asconf.h>
 #include <netinet/sctp_bsd_addr.h>
+#if defined(INET6) || defined(INET)
+#include <netinet/tcp_var.h>
+#endif
 #include <netinet/udp.h>
 #include <netinet/udp_var.h>
 #include <sys/proc.h>
@@ -7235,3 +7238,90 @@ sctp_over_udp_start(void)
 #endif
 	return (0);
 }
+
+#if defined(INET6) || defined(INET)
+
+/*
+ * sctp_min_mtu ()returns the minimum of all non-zero arguments.
+ * If all arguments are zero, zero is returned.
+ */
+uint32_t
+sctp_min_mtu(uint32_t mtu1, uint32_t mtu2, uint32_t mtu3)
+{
+	if (mtu1 > 0) {
+		if (mtu2 > 0) {
+			if (mtu3 > 0) {
+				return (min(mtu1, min(mtu2, mtu3)));
+			} else {
+				return (min(mtu1, mtu2));
+			}
+		} else {
+			if (mtu3 > 0) {
+				return (min(mtu1, mtu3));
+			} else {
+				return (mtu1);
+			}
+		}
+	} else {
+		if (mtu2 > 0) {
+			if (mtu3 > 0) {
+				return (min(mtu2, mtu3));
+			} else {
+				return (mtu2);
+			}
+		} else {
+			return (mtu3);
+		}
+	}
+}
+
+void
+sctp_hc_set_mtu(union sctp_sockstore *addr, uint16_t fibnum, uint32_t mtu)
+{
+	struct in_conninfo inc;
+
+	memset(&inc, 0, sizeof(struct in_conninfo));
+	inc.inc_fibnum = fibnum;
+	switch (addr->sa.sa_family) {
+#ifdef INET
+	case AF_INET:
+		inc.inc_faddr = addr->sin.sin_addr;
+		break;
+#endif
+#ifdef INET6
+	case AF_INET6:
+		inc.inc_flags |= INC_ISIPV6;
+		inc.inc6_faddr = addr->sin6.sin6_addr;
+		break;
+#endif
+	default:
+		return;
+	}
+	tcp_hc_updatemtu(&inc, (u_long)mtu);
+}
+
+uint32_t
+sctp_hc_get_mtu(union sctp_sockstore *addr, uint16_t fibnum)
+{
+	struct in_conninfo inc;
+
+	memset(&inc, 0, sizeof(struct in_conninfo));
+	inc.inc_fibnum = fibnum;
+	switch (addr->sa.sa_family) {
+#ifdef INET
+	case AF_INET:
+		inc.inc_faddr = addr->sin.sin_addr;
+		break;
+#endif
+#ifdef INET6
+	case AF_INET6:
+		inc.inc_flags |= INC_ISIPV6;
+		inc.inc6_faddr = addr->sin6.sin6_addr;
+		break;
+#endif
+	default:
+		return (0);
+	}
+	return ((uint32_t)tcp_hc_getmtu(&inc));
+}
+#endif

Modified: stable/11/sys/netinet/sctputil.h
==============================================================================
--- stable/11/sys/netinet/sctputil.h	Thu Jun  1 09:18:03 2017	(r319407)
+++ stable/11/sys/netinet/sctputil.h	Thu Jun  1 09:21:25 2017	(r319408)
@@ -388,5 +388,10 @@ sctp_auditing(int, struct sctp_inpcb *, struct sctp_tc
 void sctp_audit_log(uint8_t, uint8_t);
 
 #endif
+#if defined(INET6) || defined(INET)
+uint32_t sctp_min_mtu(uint32_t, uint32_t, uint32_t);
+void sctp_hc_set_mtu(union sctp_sockstore *, uint16_t, uint32_t);
+uint32_t sctp_hc_get_mtu(union sctp_sockstore *, uint16_t);
+#endif
 #endif				/* _KERNEL */
 #endif



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