Date: Tue, 28 Jul 2015 19:59:23 +0000 (UTC) From: Xin LI <delphij@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r285980 - in releng: 8.4 8.4/contrib/bind9/lib/dns 8.4/crypto/openssh 8.4/sys/conf 8.4/sys/netinet 9.3 9.3/contrib/bind9/lib/dns 9.3/crypto/openssh 9.3/sys/conf 9.3/sys/netinet Message-ID: <201507281959.t6SJxNAJ002737@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: delphij Date: Tue Jul 28 19:59:22 2015 New Revision: 285980 URL: https://svnweb.freebsd.org/changeset/base/285980 Log: Fix resource exhaustion in TCP reassembly. [SA-15:15] Fix OpenSSH multiple vulnerabilities. [SA-15:16] Fix BIND remote denial of service vulnerability. [SA-15:17] Approved by: so Modified: releng/8.4/UPDATING releng/8.4/contrib/bind9/lib/dns/tkey.c releng/8.4/crypto/openssh/auth2-chall.c releng/8.4/crypto/openssh/sshconnect.c releng/8.4/sys/conf/newvers.sh releng/8.4/sys/netinet/tcp_reass.c releng/8.4/sys/netinet/tcp_subr.c releng/8.4/sys/netinet/tcp_var.h releng/9.3/UPDATING releng/9.3/contrib/bind9/lib/dns/tkey.c releng/9.3/crypto/openssh/auth2-chall.c releng/9.3/crypto/openssh/sshconnect.c releng/9.3/sys/conf/newvers.sh releng/9.3/sys/netinet/tcp_reass.c releng/9.3/sys/netinet/tcp_subr.c releng/9.3/sys/netinet/tcp_var.h Modified: releng/8.4/UPDATING ============================================================================== --- releng/8.4/UPDATING Tue Jul 28 19:59:11 2015 (r285979) +++ releng/8.4/UPDATING Tue Jul 28 19:59:22 2015 (r285980) @@ -15,6 +15,16 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8. debugging tools present in HEAD were left in place because sun4v support still needs work to become production ready. +20150728: p35 FreeBSD-SA-15:15.tcp + FreeBSD-SA-15:16.openssh + FreeBSD-SA-15:17.bind + + Fix resource exhaustion in TCP reassembly. [SA-15:15] + + Fix OpenSSH multiple vulnerabilities. [SA-15:16] + + Fix BIND remote denial of service vulnerability. [SA-15:17] + 20150721: p34 FreeBSD-SA-15:13.tcp Fix resource exhaustion due to sessions stuck in LAST_ACK state. Modified: releng/8.4/contrib/bind9/lib/dns/tkey.c ============================================================================== --- releng/8.4/contrib/bind9/lib/dns/tkey.c Tue Jul 28 19:59:11 2015 (r285979) +++ releng/8.4/contrib/bind9/lib/dns/tkey.c Tue Jul 28 19:59:22 2015 (r285980) @@ -650,6 +650,7 @@ dns_tkey_processquery(dns_message_t *msg * Try the answer section, since that's where Win2000 * puts it. */ + name = NULL; if (dns_message_findname(msg, DNS_SECTION_ANSWER, qname, dns_rdatatype_tkey, 0, &name, &tkeyset) != ISC_R_SUCCESS) { Modified: releng/8.4/crypto/openssh/auth2-chall.c ============================================================================== --- releng/8.4/crypto/openssh/auth2-chall.c Tue Jul 28 19:59:11 2015 (r285979) +++ releng/8.4/crypto/openssh/auth2-chall.c Tue Jul 28 19:59:22 2015 (r285980) @@ -82,6 +82,7 @@ struct KbdintAuthctxt void *ctxt; KbdintDevice *device; u_int nreq; + u_int devices_done; }; #ifdef USE_PAM @@ -169,9 +170,14 @@ kbdint_next_device(KbdintAuthctxt *kbdin if (len == 0) break; - for (i = 0; devices[i]; i++) - if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0) + for (i = 0; devices[i]; i++) { + if ((kbdintctxt->devices_done & (1 << i)) != 0) + continue; + if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0) { kbdintctxt->device = devices[i]; + kbdintctxt->devices_done |= 1 << i; + } + } t = kbdintctxt->devices; kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL; xfree(t); Modified: releng/8.4/crypto/openssh/sshconnect.c ============================================================================== --- releng/8.4/crypto/openssh/sshconnect.c Tue Jul 28 19:59:11 2015 (r285979) +++ releng/8.4/crypto/openssh/sshconnect.c Tue Jul 28 19:59:22 2015 (r285980) @@ -1141,29 +1141,39 @@ verify_host_key(char *host, struct socka { int flags = 0; char *fp; + Key *plain = NULL; fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); debug("Server host key: %s %s", key_type(host_key), fp); xfree(fp); - /* XXX certs are not yet supported for DNS */ - if (!key_is_cert(host_key) && options.verify_host_key_dns && - verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { - if (flags & DNS_VERIFY_FOUND) { - - if (options.verify_host_key_dns == 1 && - flags & DNS_VERIFY_MATCH && - flags & DNS_VERIFY_SECURE) - return 0; - - if (flags & DNS_VERIFY_MATCH) { - matching_host_key_dns = 1; - } else { - warn_changed_key(host_key); - error("Update the SSHFP RR in DNS with the new " - "host key to get rid of this message."); + if (options.verify_host_key_dns) { + /* + * XXX certs are not yet supported for DNS, so downgrade + * them and try the plain key. + */ + plain = key_from_private(host_key); + if (key_is_cert(plain)) + key_drop_cert(plain); + if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) { + if (flags & DNS_VERIFY_FOUND) { + if (options.verify_host_key_dns == 1 && + flags & DNS_VERIFY_MATCH && + flags & DNS_VERIFY_SECURE) { + key_free(plain); + return 0; + } + if (flags & DNS_VERIFY_MATCH) { + matching_host_key_dns = 1; + } else { + warn_changed_key(plain); + error("Update the SSHFP RR in DNS " + "with the new host key to get rid " + "of this message."); + } } } + key_free(plain); } return check_host_key(host, hostaddr, options.port, host_key, RDRW, Modified: releng/8.4/sys/conf/newvers.sh ============================================================================== --- releng/8.4/sys/conf/newvers.sh Tue Jul 28 19:59:11 2015 (r285979) +++ releng/8.4/sys/conf/newvers.sh Tue Jul 28 19:59:22 2015 (r285980) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.4" -BRANCH="RELEASE-p34" +BRANCH="RELEASE-p35" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/8.4/sys/netinet/tcp_reass.c ============================================================================== --- releng/8.4/sys/netinet/tcp_reass.c Tue Jul 28 19:59:11 2015 (r285979) +++ releng/8.4/sys/netinet/tcp_reass.c Tue Jul 28 19:59:22 2015 (r285980) @@ -80,62 +80,49 @@ static int tcp_reass_sysctl_qsize(SYSCTL SYSCTL_NODE(_net_inet_tcp, OID_AUTO, reass, CTLFLAG_RW, 0, "TCP Segment Reassembly Queue"); -static VNET_DEFINE(int, tcp_reass_maxseg) = 0; -#define V_tcp_reass_maxseg VNET(tcp_reass_maxseg) +static int tcp_reass_maxseg = 0; SYSCTL_VNET_PROC(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLTYPE_INT | CTLFLAG_RDTUN, - &VNET_NAME(tcp_reass_maxseg), 0, &tcp_reass_sysctl_maxseg, "I", + &tcp_reass_maxseg, 0, &tcp_reass_sysctl_maxseg, "I", "Global maximum number of TCP Segments in Reassembly Queue"); -static VNET_DEFINE(int, tcp_reass_qsize) = 0; -#define V_tcp_reass_qsize VNET(tcp_reass_qsize) -SYSCTL_VNET_PROC(_net_inet_tcp_reass, OID_AUTO, cursegments, +static int tcp_reass_qsize = 0; +SYSCTL_PROC(_net_inet_tcp_reass, OID_AUTO, cursegments, CTLTYPE_INT | CTLFLAG_RD, - &VNET_NAME(tcp_reass_qsize), 0, &tcp_reass_sysctl_qsize, "I", + &tcp_reass_qsize, 0, &tcp_reass_sysctl_qsize, "I", "Global number of TCP Segments currently in Reassembly Queue"); -static VNET_DEFINE(int, tcp_reass_overflows) = 0; -#define V_tcp_reass_overflows VNET(tcp_reass_overflows) -SYSCTL_VNET_INT(_net_inet_tcp_reass, OID_AUTO, overflows, +static int tcp_reass_overflows = 0; +SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, overflows, CTLTYPE_INT | CTLFLAG_RD, - &VNET_NAME(tcp_reass_overflows), 0, + &tcp_reass_overflows, 0, "Global number of TCP Segment Reassembly Queue Overflows"); -static VNET_DEFINE(uma_zone_t, tcp_reass_zone); -#define V_tcp_reass_zone VNET(tcp_reass_zone) +static uma_zone_t tcp_reass_zone; /* Initialize TCP reassembly queue */ static void tcp_reass_zone_change(void *tag) { - V_tcp_reass_maxseg = nmbclusters / 16; - uma_zone_set_max(V_tcp_reass_zone, V_tcp_reass_maxseg); + tcp_reass_maxseg = nmbclusters / 16; + uma_zone_set_max(tcp_reass_zone, tcp_reass_maxseg); } void -tcp_reass_init(void) +tcp_reass_global_init(void) { - V_tcp_reass_maxseg = nmbclusters / 16; + tcp_reass_maxseg = nmbclusters / 16; TUNABLE_INT_FETCH("net.inet.tcp.reass.maxsegments", - &V_tcp_reass_maxseg); - V_tcp_reass_zone = uma_zcreate("tcpreass", sizeof (struct tseg_qent), + &tcp_reass_maxseg); + tcp_reass_zone = uma_zcreate("tcpreass", sizeof (struct tseg_qent), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); - uma_zone_set_max(V_tcp_reass_zone, V_tcp_reass_maxseg); + uma_zone_set_max(tcp_reass_zone, tcp_reass_maxseg); EVENTHANDLER_REGISTER(nmbclusters_change, tcp_reass_zone_change, NULL, EVENTHANDLER_PRI_ANY); } -#ifdef VIMAGE -void -tcp_reass_destroy(void) -{ - - uma_zdestroy(V_tcp_reass_zone); -} -#endif - void tcp_reass_flush(struct tcpcb *tp) { @@ -146,7 +133,7 @@ tcp_reass_flush(struct tcpcb *tp) while ((qe = LIST_FIRST(&tp->t_segq)) != NULL) { LIST_REMOVE(qe, tqe_q); m_freem(qe->tqe_m); - uma_zfree(V_tcp_reass_zone, qe); + uma_zfree(tcp_reass_zone, qe); tp->t_segqlen--; } @@ -158,14 +145,14 @@ tcp_reass_flush(struct tcpcb *tp) static int tcp_reass_sysctl_maxseg(SYSCTL_HANDLER_ARGS) { - V_tcp_reass_maxseg = uma_zone_get_max(V_tcp_reass_zone); + tcp_reass_maxseg = uma_zone_get_max(tcp_reass_zone); return (sysctl_handle_int(oidp, arg1, arg2, req)); } static int tcp_reass_sysctl_qsize(SYSCTL_HANDLER_ARGS) { - V_tcp_reass_qsize = uma_zone_get_cur(V_tcp_reass_zone); + tcp_reass_qsize = uma_zone_get_cur(tcp_reass_zone); return (sysctl_handle_int(oidp, arg1, arg2, req)); } @@ -213,7 +200,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd */ if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) { - V_tcp_reass_overflows++; + tcp_reass_overflows++; TCPSTAT_INC(tcps_rcvmemdrop); m_freem(m); *tlenp = 0; @@ -232,7 +219,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd * Use a temporary structure on the stack for the missing segment * when the zone is exhausted. Otherwise we may get stuck. */ - te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT); + te = uma_zalloc(tcp_reass_zone, M_NOWAIT); if (te == NULL) { if (th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) { TCPSTAT_INC(tcps_rcvmemdrop); @@ -283,7 +270,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); if (te != &tqs) - uma_zfree(V_tcp_reass_zone, te); + uma_zfree(tcp_reass_zone, te); tp->t_segqlen--; /* * Try to present any queued data @@ -320,7 +307,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd nq = LIST_NEXT(q, tqe_q); LIST_REMOVE(q, tqe_q); m_freem(q->tqe_m); - uma_zfree(V_tcp_reass_zone, q); + uma_zfree(tcp_reass_zone, q); tp->t_segqlen--; q = nq; } @@ -359,7 +346,7 @@ present: else sbappendstream_locked(&so->so_rcv, q->tqe_m); if (q != &tqs) - uma_zfree(V_tcp_reass_zone, q); + uma_zfree(tcp_reass_zone, q); tp->t_segqlen--; q = nq; } while (q && q->tqe_th->th_seq == tp->rcv_nxt); Modified: releng/8.4/sys/netinet/tcp_subr.c ============================================================================== --- releng/8.4/sys/netinet/tcp_subr.c Tue Jul 28 19:59:11 2015 (r285979) +++ releng/8.4/sys/netinet/tcp_subr.c Tue Jul 28 19:59:22 2015 (r285980) @@ -375,7 +375,6 @@ tcp_init(void) tcp_tw_init(); syncache_init(); tcp_hc_init(); - tcp_reass_init(); TUNABLE_INT_FETCH("net.inet.tcp.sack.enable", &V_tcp_do_sack); V_sack_hole_zone = uma_zcreate("sackhole", sizeof(struct sackhole), @@ -385,6 +384,8 @@ tcp_init(void) if (!IS_DEFAULT_VNET(curvnet)) return; + tcp_reass_global_init(); + /* XXX virtualize those bellow? */ tcp_delacktime = TCPTV_DELACK; tcp_keepinit = TCPTV_KEEP_INIT; @@ -424,7 +425,6 @@ void tcp_destroy(void) { - tcp_reass_destroy(); tcp_hc_destroy(); syncache_destroy(); tcp_tw_destroy(); Modified: releng/8.4/sys/netinet/tcp_var.h ============================================================================== --- releng/8.4/sys/netinet/tcp_var.h Tue Jul 28 19:59:11 2015 (r285979) +++ releng/8.4/sys/netinet/tcp_var.h Tue Jul 28 19:59:22 2015 (r285980) @@ -653,11 +653,8 @@ char *tcp_log_addrs(struct in_conninfo char *tcp_log_vain(struct in_conninfo *, struct tcphdr *, void *, const void *); int tcp_reass(struct tcpcb *, struct tcphdr *, int *, struct mbuf *); -void tcp_reass_init(void); +void tcp_reass_global_init(void); void tcp_reass_flush(struct tcpcb *); -#ifdef VIMAGE -void tcp_reass_destroy(void); -#endif void tcp_input(struct mbuf *, int); u_long tcp_maxmtu(struct in_conninfo *, int *); u_long tcp_maxmtu6(struct in_conninfo *, int *); Modified: releng/9.3/UPDATING ============================================================================== --- releng/9.3/UPDATING Tue Jul 28 19:59:11 2015 (r285979) +++ releng/9.3/UPDATING Tue Jul 28 19:59:22 2015 (r285980) @@ -11,6 +11,16 @@ handbook: Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before running portupgrade. +20150728: p21 FreeBSD-SA-15:15.tcp + FreeBSD-SA-15:16.openssh + FreeBSD-SA-15:17.bind + + Fix resource exhaustion in TCP reassembly. [SA-15:15] + + Fix OpenSSH multiple vulnerabilities. [SA-15:16] + + Fix BIND remote denial of service vulnerability. [SA-15:17] + 20150721: p20 FreeBSD-SA-15:13.tcp Fix resource exhaustion due to sessions stuck in LAST_ACK state. Modified: releng/9.3/contrib/bind9/lib/dns/tkey.c ============================================================================== --- releng/9.3/contrib/bind9/lib/dns/tkey.c Tue Jul 28 19:59:11 2015 (r285979) +++ releng/9.3/contrib/bind9/lib/dns/tkey.c Tue Jul 28 19:59:22 2015 (r285980) @@ -650,6 +650,7 @@ dns_tkey_processquery(dns_message_t *msg * Try the answer section, since that's where Win2000 * puts it. */ + name = NULL; if (dns_message_findname(msg, DNS_SECTION_ANSWER, qname, dns_rdatatype_tkey, 0, &name, &tkeyset) != ISC_R_SUCCESS) { Modified: releng/9.3/crypto/openssh/auth2-chall.c ============================================================================== --- releng/9.3/crypto/openssh/auth2-chall.c Tue Jul 28 19:59:11 2015 (r285979) +++ releng/9.3/crypto/openssh/auth2-chall.c Tue Jul 28 19:59:22 2015 (r285980) @@ -82,6 +82,7 @@ struct KbdintAuthctxt void *ctxt; KbdintDevice *device; u_int nreq; + u_int devices_done; }; #ifdef USE_PAM @@ -168,11 +169,15 @@ kbdint_next_device(Authctxt *authctxt, K if (len == 0) break; for (i = 0; devices[i]; i++) { - if (!auth2_method_allowed(authctxt, + if ((kbdintctxt->devices_done & (1 << i)) != 0 || + !auth2_method_allowed(authctxt, "keyboard-interactive", devices[i]->name)) continue; - if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0) + if (strncmp(kbdintctxt->devices, devices[i]->name, + len) == 0) { kbdintctxt->device = devices[i]; + kbdintctxt->devices_done |= 1 << i; + } } t = kbdintctxt->devices; kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL; Modified: releng/9.3/crypto/openssh/sshconnect.c ============================================================================== --- releng/9.3/crypto/openssh/sshconnect.c Tue Jul 28 19:59:11 2015 (r285979) +++ releng/9.3/crypto/openssh/sshconnect.c Tue Jul 28 19:59:22 2015 (r285980) @@ -1247,29 +1247,39 @@ verify_host_key(char *host, struct socka { int flags = 0; char *fp; + Key *plain = NULL; fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); debug("Server host key: %s %s", key_type(host_key), fp); free(fp); - /* XXX certs are not yet supported for DNS */ - if (!key_is_cert(host_key) && options.verify_host_key_dns && - verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) { - if (flags & DNS_VERIFY_FOUND) { - - if (options.verify_host_key_dns == 1 && - flags & DNS_VERIFY_MATCH && - flags & DNS_VERIFY_SECURE) - return 0; - - if (flags & DNS_VERIFY_MATCH) { - matching_host_key_dns = 1; - } else { - warn_changed_key(host_key); - error("Update the SSHFP RR in DNS with the new " - "host key to get rid of this message."); + if (options.verify_host_key_dns) { + /* + * XXX certs are not yet supported for DNS, so downgrade + * them and try the plain key. + */ + plain = key_from_private(host_key); + if (key_is_cert(plain)) + key_drop_cert(plain); + if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) { + if (flags & DNS_VERIFY_FOUND) { + if (options.verify_host_key_dns == 1 && + flags & DNS_VERIFY_MATCH && + flags & DNS_VERIFY_SECURE) { + key_free(plain); + return 0; + } + if (flags & DNS_VERIFY_MATCH) { + matching_host_key_dns = 1; + } else { + warn_changed_key(plain); + error("Update the SSHFP RR in DNS " + "with the new host key to get rid " + "of this message."); + } } } + key_free(plain); } return check_host_key(host, hostaddr, options.port, host_key, RDRW, Modified: releng/9.3/sys/conf/newvers.sh ============================================================================== --- releng/9.3/sys/conf/newvers.sh Tue Jul 28 19:59:11 2015 (r285979) +++ releng/9.3/sys/conf/newvers.sh Tue Jul 28 19:59:22 2015 (r285980) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="9.3" -BRANCH="RELEASE-p20" +BRANCH="RELEASE-p21" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/9.3/sys/netinet/tcp_reass.c ============================================================================== --- releng/9.3/sys/netinet/tcp_reass.c Tue Jul 28 19:59:11 2015 (r285979) +++ releng/9.3/sys/netinet/tcp_reass.c Tue Jul 28 19:59:22 2015 (r285980) @@ -79,25 +79,22 @@ static int tcp_reass_sysctl_qsize(SYSCTL static SYSCTL_NODE(_net_inet_tcp, OID_AUTO, reass, CTLFLAG_RW, 0, "TCP Segment Reassembly Queue"); -static VNET_DEFINE(int, tcp_reass_maxseg) = 0; -#define V_tcp_reass_maxseg VNET(tcp_reass_maxseg) -SYSCTL_VNET_INT(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLFLAG_RDTUN, - &VNET_NAME(tcp_reass_maxseg), 0, +static int tcp_reass_maxseg = 0; +SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, maxsegments, CTLFLAG_RDTUN, + &tcp_reass_maxseg, 0, "Global maximum number of TCP Segments in Reassembly Queue"); -SYSCTL_VNET_PROC(_net_inet_tcp_reass, OID_AUTO, cursegments, +SYSCTL_PROC(_net_inet_tcp_reass, OID_AUTO, cursegments, (CTLTYPE_INT | CTLFLAG_RD), NULL, 0, &tcp_reass_sysctl_qsize, "I", "Global number of TCP Segments currently in Reassembly Queue"); -static VNET_DEFINE(int, tcp_reass_overflows) = 0; -#define V_tcp_reass_overflows VNET(tcp_reass_overflows) -SYSCTL_VNET_INT(_net_inet_tcp_reass, OID_AUTO, overflows, +static int tcp_reass_overflows = 0; +SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, overflows, CTLTYPE_INT | CTLFLAG_RD, - &VNET_NAME(tcp_reass_overflows), 0, + &tcp_reass_overflows, 0, "Global number of TCP Segment Reassembly Queue Overflows"); -static VNET_DEFINE(uma_zone_t, tcp_reass_zone); -#define V_tcp_reass_zone VNET(tcp_reass_zone) +static uma_zone_t tcp_reass_zone; /* Initialize TCP reassembly queue */ static void @@ -105,36 +102,27 @@ tcp_reass_zone_change(void *tag) { /* Set the zone limit and read back the effective value. */ - V_tcp_reass_maxseg = nmbclusters / 16; - V_tcp_reass_maxseg = uma_zone_set_max(V_tcp_reass_zone, - V_tcp_reass_maxseg); + tcp_reass_maxseg = nmbclusters / 16; + tcp_reass_maxseg = uma_zone_set_max(tcp_reass_zone, + tcp_reass_maxseg); } void -tcp_reass_init(void) +tcp_reass_global_init(void) { - V_tcp_reass_maxseg = nmbclusters / 16; + tcp_reass_maxseg = nmbclusters / 16; TUNABLE_INT_FETCH("net.inet.tcp.reass.maxsegments", - &V_tcp_reass_maxseg); - V_tcp_reass_zone = uma_zcreate("tcpreass", sizeof (struct tseg_qent), + &tcp_reass_maxseg); + tcp_reass_zone = uma_zcreate("tcpreass", sizeof (struct tseg_qent), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); /* Set the zone limit and read back the effective value. */ - V_tcp_reass_maxseg = uma_zone_set_max(V_tcp_reass_zone, - V_tcp_reass_maxseg); + tcp_reass_maxseg = uma_zone_set_max(tcp_reass_zone, + tcp_reass_maxseg); EVENTHANDLER_REGISTER(nmbclusters_change, tcp_reass_zone_change, NULL, EVENTHANDLER_PRI_ANY); } -#ifdef VIMAGE -void -tcp_reass_destroy(void) -{ - - uma_zdestroy(V_tcp_reass_zone); -} -#endif - void tcp_reass_flush(struct tcpcb *tp) { @@ -145,7 +133,7 @@ tcp_reass_flush(struct tcpcb *tp) while ((qe = LIST_FIRST(&tp->t_segq)) != NULL) { LIST_REMOVE(qe, tqe_q); m_freem(qe->tqe_m); - uma_zfree(V_tcp_reass_zone, qe); + uma_zfree(tcp_reass_zone, qe); tp->t_segqlen--; } @@ -159,7 +147,7 @@ tcp_reass_sysctl_qsize(SYSCTL_HANDLER_AR { int qsize; - qsize = uma_zone_get_cur(V_tcp_reass_zone); + qsize = uma_zone_get_cur(tcp_reass_zone); return (sysctl_handle_int(oidp, &qsize, 0, req)); } @@ -207,7 +195,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd */ if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) { - V_tcp_reass_overflows++; + tcp_reass_overflows++; TCPSTAT_INC(tcps_rcvmemdrop); m_freem(m); *tlenp = 0; @@ -226,7 +214,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd * Use a temporary structure on the stack for the missing segment * when the zone is exhausted. Otherwise we may get stuck. */ - te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT); + te = uma_zalloc(tcp_reass_zone, M_NOWAIT); if (te == NULL) { if (th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) { TCPSTAT_INC(tcps_rcvmemdrop); @@ -277,7 +265,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); if (te != &tqs) - uma_zfree(V_tcp_reass_zone, te); + uma_zfree(tcp_reass_zone, te); tp->t_segqlen--; /* * Try to present any queued data @@ -314,7 +302,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd nq = LIST_NEXT(q, tqe_q); LIST_REMOVE(q, tqe_q); m_freem(q->tqe_m); - uma_zfree(V_tcp_reass_zone, q); + uma_zfree(tcp_reass_zone, q); tp->t_segqlen--; q = nq; } @@ -353,7 +341,7 @@ present: else sbappendstream_locked(&so->so_rcv, q->tqe_m); if (q != &tqs) - uma_zfree(V_tcp_reass_zone, q); + uma_zfree(tcp_reass_zone, q); tp->t_segqlen--; q = nq; } while (q && q->tqe_th->th_seq == tp->rcv_nxt); Modified: releng/9.3/sys/netinet/tcp_subr.c ============================================================================== --- releng/9.3/sys/netinet/tcp_subr.c Tue Jul 28 19:59:11 2015 (r285979) +++ releng/9.3/sys/netinet/tcp_subr.c Tue Jul 28 19:59:22 2015 (r285980) @@ -314,7 +314,6 @@ tcp_init(void) tcp_tw_init(); syncache_init(); tcp_hc_init(); - tcp_reass_init(); TUNABLE_INT_FETCH("net.inet.tcp.sack.enable", &V_tcp_do_sack); V_sack_hole_zone = uma_zcreate("sackhole", sizeof(struct sackhole), @@ -324,6 +323,8 @@ tcp_init(void) if (!IS_DEFAULT_VNET(curvnet)) return; + tcp_reass_global_init(); + /* XXX virtualize those bellow? */ tcp_delacktime = TCPTV_DELACK; tcp_keepinit = TCPTV_KEEP_INIT; @@ -371,7 +372,6 @@ void tcp_destroy(void) { - tcp_reass_destroy(); tcp_hc_destroy(); syncache_destroy(); tcp_tw_destroy(); Modified: releng/9.3/sys/netinet/tcp_var.h ============================================================================== --- releng/9.3/sys/netinet/tcp_var.h Tue Jul 28 19:59:11 2015 (r285979) +++ releng/9.3/sys/netinet/tcp_var.h Tue Jul 28 19:59:22 2015 (r285980) @@ -680,11 +680,8 @@ char *tcp_log_addrs(struct in_conninfo * char *tcp_log_vain(struct in_conninfo *, struct tcphdr *, void *, const void *); int tcp_reass(struct tcpcb *, struct tcphdr *, int *, struct mbuf *); -void tcp_reass_init(void); +void tcp_reass_global_init(void); void tcp_reass_flush(struct tcpcb *); -#ifdef VIMAGE -void tcp_reass_destroy(void); -#endif void tcp_input(struct mbuf *, int); u_long tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *); u_long tcp_maxmtu6(struct in_conninfo *, struct tcp_ifcap *);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507281959.t6SJxNAJ002737>