From nobody Sat Dec 04 18:06:17 2021 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 6976118C65D6; Sat, 4 Dec 2021 18:06:18 +0000 (UTC) (envelope-from git@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) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4J5yLL16nKz4tdv; Sat, 4 Dec 2021 18:06:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 06CB09CE; Sat, 4 Dec 2021 18:06:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 1B4I6Hqd058877; Sat, 4 Dec 2021 18:06:17 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1B4I6HGV058876; Sat, 4 Dec 2021 18:06:17 GMT (envelope-from git) Date: Sat, 4 Dec 2021 18:06:17 GMT Message-Id: <202112041806.1B4I6HGV058876@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: ad2a0aec2954 - main - nhop: hash ifnet pointer instead of if_index List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: ad2a0aec295478e750158b8985422f15deee0e54 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1638641178; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+7L9aYfisz9exKDTOPLAewOFeADUZU87DlPGdWIUYvw=; b=m6xK2LsZQ6H4bxRuxpWMLnT0Q9/Dc4qplMg7JVBUc1bHpp+iyHT7TVlgFchm8V21rzme2S Djt1QJosG6qhiYaqGq3hDFdX+I87VrmhTXq3DN1TkNQGn8FgRgVoTfGzyoCnnCNCq1r9bx NF0k/ouTX09i0zQFEiqkWCfw42qEea/nnMrXnjvMenZ+jsIXh/1Tf3SW+63cIS5BCXZjO+ VGYutybBKeHZtFwuualcwwKGfW1Pj5ilzOE3QUk/vJzkaTSTrCZU4V+jTyhre3y7a2BrYC 3r0d4JamUiiWAjep5H7AqtugWs6RtSQ30HeNhKjOvSv95Da1p2ElclHLrw0vyQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1638641178; a=rsa-sha256; cv=none; b=DIwQHU8E08PNECI7eHRQGaCW58BeXOyLbYmmffEtfeN36F0yYE+CHsQUMn4UKUDHiP5ArA wh3YNUSYtbB0X8TCeth4YWLRXqELsXQfZnik4wiuR1gb9GNvxHFMbyIamHqD4eaAKsKFhu yYpcKmZphxUyhlZ9SDsqTqdyc9FY3OHyY5jyDUv0YNAKpEOPi8cgMyPz2y4vmtvJGXG6wq u5OvxaEqYbNiV74kDMHuPyoGFjHy4CSMHCesgL/fMKGVqjGuEOT9gASdC+u2b6eLDiMl/j eknDpLlX8C2DO6enFlyNQfr7yuXEBlkYSAPZIM/bfkBWmN294Q3M0nCIVX0qYw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=ad2a0aec295478e750158b8985422f15deee0e54 commit ad2a0aec295478e750158b8985422f15deee0e54 Author: Gleb Smirnoff AuthorDate: 2021-12-04 18:05:46 +0000 Commit: Gleb Smirnoff CommitDate: 2021-12-04 18:05:46 +0000 nhop: hash ifnet pointer instead of if_index Yet another problem created by VIMAGE/if_vmove/epair design that relocates ifnet between vnets and changes if_index. Since if_index changes, nhop hash values also changes, unlink_nhop() isn't able to find entry in hash and leaks the nhop. Since nhop references ifnet, the latter is also leaked. As result running network tests leaks memory on every single test that creates vnet jail. While here, rewrite whole hash_priv() to use static initializer, per Alexander's suggestion. Reviewed by: melifaro --- sys/net/route/nhop.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/sys/net/route/nhop.c b/sys/net/route/nhop.c index ab5e393ae56a..531eae03638f 100644 --- a/sys/net/route/nhop.c +++ b/sys/net/route/nhop.c @@ -183,13 +183,13 @@ nhops_destroy_rib(struct rib_head *rh) * With that in mind, hash nexthops by the combination of the interface * and GW IP address. * - * To optimize hash calculation, ignore higher bytes of ifindex, as they - * give very little entropy. + * To optimize hash calculation, ignore lower bits of ifnet pointer, + * as they give very little entropy. * Similarly, use lower 4 bytes of IPv6 address to distinguish between the * neighbors. */ struct _hash_data { - uint16_t ifindex; + uint16_t ifentropy; uint8_t family; uint8_t nh_type; uint32_t gw_addr; @@ -210,21 +210,15 @@ djb_hash(const unsigned char *h, const int len) static uint32_t hash_priv(const struct nhop_priv *priv) { - struct nhop_object *nh; - uint16_t ifindex; - struct _hash_data key; - - nh = priv->nh; - ifindex = nh->nh_ifp->if_index & 0xFFFF; - memset(&key, 0, sizeof(key)); - - key.ifindex = ifindex; - key.family = nh->gw_sa.sa_family; - key.nh_type = priv->nh_type & 0xFF; - if (nh->gw_sa.sa_family == AF_INET6) - memcpy(&key.gw_addr, &nh->gw6_sa.sin6_addr.s6_addr32[3], 4); - else if (nh->gw_sa.sa_family == AF_INET) - memcpy(&key.gw_addr, &nh->gw4_sa.sin_addr, 4); + struct nhop_object *nh = priv->nh; + struct _hash_data key = { + .ifentropy = (uint16_t)((((uintptr_t)nh->nh_ifp) >> 6) & 0xFFFF), + .family = nh->gw_sa.sa_family, + .nh_type = priv->nh_type & 0xFF, + .gw_addr = (nh->gw_sa.sa_family == AF_INET6) ? + nh->gw6_sa.sin6_addr.s6_addr32[3] : + nh->gw4_sa.sin_addr.s_addr + }; return (uint32_t)(djb_hash((const unsigned char *)&key, sizeof(key))); }