From owner-svn-src-head@freebsd.org Sat Apr 29 19:20:52 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 694D3D5452F; Sat, 29 Apr 2017 19:20:52 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 233E5166F; Sat, 29 Apr 2017 19:20:52 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v3TJKpGi009348; Sat, 29 Apr 2017 19:20:51 GMT (envelope-from tuexen@FreeBSD.org) Received: (from tuexen@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v3TJKoFs009344; Sat, 29 Apr 2017 19:20:50 GMT (envelope-from tuexen@FreeBSD.org) Message-Id: <201704291920.v3TJKoFs009344@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: tuexen set sender to tuexen@FreeBSD.org using -f From: Michael Tuexen Date: Sat, 29 Apr 2017 19:20:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r317597 - head/sys/netinet X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 29 Apr 2017 19:20:52 -0000 Author: tuexen Date: Sat Apr 29 19:20:50 2017 New Revision: 317597 URL: https://svnweb.freebsd.org/changeset/base/317597 Log: 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. MFC after: 1 week Modified: head/sys/netinet/sctp_pcb.c head/sys/netinet/sctp_usrreq.c head/sys/netinet/sctputil.c head/sys/netinet/sctputil.h Modified: head/sys/netinet/sctp_pcb.c ============================================================================== --- head/sys/netinet/sctp_pcb.c Sat Apr 29 19:12:44 2017 (r317596) +++ head/sys/netinet/sctp_pcb.c Sat Apr 29 19:20:50 2017 (r317597) @@ -3933,6 +3933,7 @@ sctp_add_remote_addr(struct sctp_tcb *st 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 *st 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 *st */ 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: head/sys/netinet/sctp_usrreq.c ============================================================================== --- head/sys/netinet/sctp_usrreq.c Sat Apr 29 19:12:44 2017 (r317596) +++ head/sys/netinet/sctp_usrreq.c Sat Apr 29 19:20:50 2017 (r317597) @@ -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: head/sys/netinet/sctputil.c ============================================================================== --- head/sys/netinet/sctputil.c Sat Apr 29 19:12:44 2017 (r317596) +++ head/sys/netinet/sctputil.c Sat Apr 29 19:20:50 2017 (r317597) @@ -49,6 +49,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#if defined(INET6) || defined(INET) +#include +#endif #include #include #include @@ -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: head/sys/netinet/sctputil.h ============================================================================== --- head/sys/netinet/sctputil.h Sat Apr 29 19:12:44 2017 (r317596) +++ head/sys/netinet/sctputil.h Sat Apr 29 19:20:50 2017 (r317597) @@ -388,5 +388,10 @@ sctp_auditing(int, struct sctp_inpcb *, 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