From owner-svn-src-all@freebsd.org Wed Dec 12 20:15:07 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 28C4D132421B; Wed, 12 Dec 2018 20:15:07 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id BF4EB76B47; Wed, 12 Dec 2018 20:15:06 +0000 (UTC) (envelope-from kp@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id ADB2ED105; Wed, 12 Dec 2018 20:15:06 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wBCKF66R051985; Wed, 12 Dec 2018 20:15:06 GMT (envelope-from kp@FreeBSD.org) Received: (from kp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wBCKF6C6051983; Wed, 12 Dec 2018 20:15:06 GMT (envelope-from kp@FreeBSD.org) Message-Id: <201812122015.wBCKF6C6051983@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kp set sender to kp@FreeBSD.org using -f From: Kristof Provost Date: Wed, 12 Dec 2018 20:15:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r341998 - head/sys/netpfil/pf X-SVN-Group: head X-SVN-Commit-Author: kp X-SVN-Commit-Paths: head/sys/netpfil/pf X-SVN-Commit-Revision: 341998 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: BF4EB76B47 X-Spamd-Bar: - Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-1.64 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-0.83)[-0.828,0]; NEURAL_HAM_SHORT(-0.81)[-0.812,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Dec 2018 20:15:07 -0000 Author: kp Date: Wed Dec 12 20:15:06 2018 New Revision: 341998 URL: https://svnweb.freebsd.org/changeset/base/341998 Log: pf: Fix endless loop on NAT exhaustion with sticky-address When we try to find a source port in pf_get_sport() it's possible that all available source ports will be in use. In that case we call pf_map_addr() to try to find a new source IP to try from. If there are no more available source IPs pf_map_addr() will return 1 and we stop trying. However, if sticky-address is set we'll always return the same IP address, even if we've already tried that one. We need to check the supplied address, because if that's the one we'd set it means pf_get_sport() has already tried it, and we should error out rather than keep trying. PR: 233867 MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D18483 Modified: head/sys/netpfil/pf/pf.c head/sys/netpfil/pf/pf_lb.c Modified: head/sys/netpfil/pf/pf.c ============================================================================== --- head/sys/netpfil/pf/pf.c Wed Dec 12 19:58:54 2018 (r341997) +++ head/sys/netpfil/pf/pf.c Wed Dec 12 20:15:06 2018 (r341998) @@ -5513,6 +5513,8 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, dst.sin_len = sizeof(dst); dst.sin_addr = ip->ip_dst; + bzero(&naddr, sizeof(naddr)); + if (TAILQ_EMPTY(&r->rpool.list)) { DPFPRINTF(PF_DEBUG_URGENT, ("%s: TAILQ_EMPTY(&r->rpool.list)\n", __func__)); @@ -5671,6 +5673,8 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, dst.sin6_family = AF_INET6; dst.sin6_len = sizeof(dst); dst.sin6_addr = ip6->ip6_dst; + + bzero(&naddr, sizeof(naddr)); if (TAILQ_EMPTY(&r->rpool.list)) { DPFPRINTF(PF_DEBUG_URGENT, Modified: head/sys/netpfil/pf/pf_lb.c ============================================================================== --- head/sys/netpfil/pf/pf_lb.c Wed Dec 12 19:58:54 2018 (r341997) +++ head/sys/netpfil/pf/pf_lb.c Wed Dec 12 20:15:06 2018 (r341998) @@ -328,6 +328,12 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct src node was created just a moment ago in pf_create_state and it needs to be filled in with routing decision calculated here. */ if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) { + /* If the supplied address is the same as the current one we've + * been asked before, so tell the caller that there's no other + * address to be had. */ + if (PF_AEQ(naddr, &(*sn)->raddr, af)) + return (1); + PF_ACPY(naddr, &(*sn)->raddr, af); if (V_pf_status.debug >= PF_DEBUG_MISC) { printf("pf_map_addr: src tracking maps ");