From owner-svn-src-head@freebsd.org Mon Oct 21 18:07:50 2019 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id DBD1415D7A0; Mon, 21 Oct 2019 18:07:50 +0000 (UTC) (envelope-from glebius@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 46xl3p4Jjmz4ZYZ; Mon, 21 Oct 2019 18:07:50 +0000 (UTC) (envelope-from glebius@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 EAAAB27B62; Mon, 21 Oct 2019 18:07:49 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x9LI7nfc065866; Mon, 21 Oct 2019 18:07:49 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x9LI7nkp065865; Mon, 21 Oct 2019 18:07:49 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201910211807.x9LI7nkp065865@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Mon, 21 Oct 2019 18:07:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r353827 - head/sys/dev/sk X-SVN-Group: head X-SVN-Commit-Author: glebius X-SVN-Commit-Paths: head/sys/dev/sk X-SVN-Commit-Revision: 353827 X-SVN-Commit-Repository: base 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.29 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: Mon, 21 Oct 2019 18:07:51 -0000 Author: glebius Date: Mon Oct 21 18:07:49 2019 New Revision: 353827 URL: https://svnweb.freebsd.org/changeset/base/353827 Log: Convert to if_foreach_llmaddr() KPI. Modified: head/sys/dev/sk/if_sk.c Modified: head/sys/dev/sk/if_sk.c ============================================================================== --- head/sys/dev/sk/if_sk.c Mon Oct 21 18:07:44 2019 (r353826) +++ head/sys/dev/sk/if_sk.c Mon Oct 21 18:07:49 2019 (r353827) @@ -718,21 +718,49 @@ sk_rxfilter(sc_if) sk_rxfilter_yukon(sc_if); } +struct sk_add_maddr_genesis_ctx { + struct sk_if_softc *sc_if; + uint32_t hashes[2]; + uint32_t mode; +}; + +static u_int +sk_add_maddr_genesis(void *arg, struct sockaddr_dl *sdl, u_int cnt) +{ + struct sk_add_maddr_genesis_ctx *ctx = arg; + int h; + + /* + * Program the first XM_RXFILT_MAX multicast groups + * into the perfect filter. + */ + if (cnt + 1 < XM_RXFILT_MAX) { + sk_setfilt(ctx->sc_if, (uint16_t *)LLADDR(sdl), cnt + 1); + ctx->mode |= XM_MODE_RX_USE_PERFECT; + return (1); + } + h = sk_xmchash((const uint8_t *)LLADDR(sdl)); + if (h < 32) + ctx->hashes[0] |= (1 << h); + else + ctx->hashes[1] |= (1 << (h - 32)); + ctx->mode |= XM_MODE_RX_USE_HASH; + + return (1); +} + static void -sk_rxfilter_genesis(sc_if) - struct sk_if_softc *sc_if; +sk_rxfilter_genesis(struct sk_if_softc *sc_if) { struct ifnet *ifp = sc_if->sk_ifp; - u_int32_t hashes[2] = { 0, 0 }, mode; - int h = 0, i; - struct ifmultiaddr *ifma; + struct sk_add_maddr_genesis_ctx ctx = { sc_if, { 0, 0 } }; + int i; u_int16_t dummy[] = { 0, 0, 0 }; - u_int16_t maddr[(ETHER_ADDR_LEN+1)/2]; SK_IF_LOCK_ASSERT(sc_if); - mode = SK_XM_READ_4(sc_if, XM_MODE); - mode &= ~(XM_MODE_RX_PROMISC | XM_MODE_RX_USE_HASH | + ctx.mode = SK_XM_READ_4(sc_if, XM_MODE); + ctx.mode &= ~(XM_MODE_RX_PROMISC | XM_MODE_RX_USE_HASH | XM_MODE_RX_USE_PERFECT); /* First, zot all the existing perfect filters. */ for (i = 1; i < XM_RXFILT_MAX; i++) @@ -741,53 +769,39 @@ sk_rxfilter_genesis(sc_if) /* Now program new ones. */ if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { if (ifp->if_flags & IFF_ALLMULTI) - mode |= XM_MODE_RX_USE_HASH; + ctx.mode |= XM_MODE_RX_USE_HASH; if (ifp->if_flags & IFF_PROMISC) - mode |= XM_MODE_RX_PROMISC; - hashes[0] = 0xFFFFFFFF; - hashes[1] = 0xFFFFFFFF; - } else { - i = 1; - if_maddr_rlock(ifp); + ctx.mode |= XM_MODE_RX_PROMISC; + ctx.hashes[0] = 0xFFFFFFFF; + ctx.hashes[1] = 0xFFFFFFFF; + } else /* XXX want to maintain reverse semantics */ - CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, - ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - /* - * Program the first XM_RXFILT_MAX multicast groups - * into the perfect filter. - */ - bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), - maddr, ETHER_ADDR_LEN); - if (i < XM_RXFILT_MAX) { - sk_setfilt(sc_if, maddr, i); - mode |= XM_MODE_RX_USE_PERFECT; - i++; - continue; - } - h = sk_xmchash((const uint8_t *)maddr); - if (h < 32) - hashes[0] |= (1 << h); - else - hashes[1] |= (1 << (h - 32)); - mode |= XM_MODE_RX_USE_HASH; - } - if_maddr_runlock(ifp); - } + if_foreach_llmaddr(ifp, sk_add_maddr_genesis, &ctx); - SK_XM_WRITE_4(sc_if, XM_MODE, mode); - SK_XM_WRITE_4(sc_if, XM_MAR0, hashes[0]); - SK_XM_WRITE_4(sc_if, XM_MAR2, hashes[1]); + SK_XM_WRITE_4(sc_if, XM_MODE, ctx.mode); + SK_XM_WRITE_4(sc_if, XM_MAR0, ctx.hashes[0]); + SK_XM_WRITE_4(sc_if, XM_MAR2, ctx.hashes[1]); } +static u_int +sk_hash_maddr_yukon(void *arg, struct sockaddr_dl *sdl, u_int cnt) +{ + uint32_t crc, *hashes = arg; + + crc = ether_crc32_be(LLADDR(sdl), ETHER_ADDR_LEN); + /* Just want the 6 least significant bits. */ + crc &= 0x3f; + /* Set the corresponding bit in the hash table. */ + hashes[crc >> 5] |= 1 << (crc & 0x1f); + + return (1); +} + static void -sk_rxfilter_yukon(sc_if) - struct sk_if_softc *sc_if; +sk_rxfilter_yukon(struct sk_if_softc *sc_if) { struct ifnet *ifp; - u_int32_t crc, hashes[2] = { 0, 0 }, mode; - struct ifmultiaddr *ifma; + uint32_t hashes[2] = { 0, 0 }, mode; SK_IF_LOCK_ASSERT(sc_if); @@ -801,18 +815,7 @@ sk_rxfilter_yukon(sc_if) hashes[1] = 0xFFFFFFFF; } else { mode |= YU_RCR_UFLEN; - if_maddr_rlock(ifp); - CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - crc = ether_crc32_be(LLADDR((struct sockaddr_dl *) - ifma->ifma_addr), ETHER_ADDR_LEN); - /* Just want the 6 least significant bits. */ - crc &= 0x3f; - /* Set the corresponding bit in the hash table. */ - hashes[crc >> 5] |= 1 << (crc & 0x1f); - } - if_maddr_runlock(ifp); + if_foreach_llmaddr(ifp, sk_hash_maddr_yukon, hashes); if (hashes[0] != 0 || hashes[1] != 0) mode |= YU_RCR_MUFLEN; }