From owner-svn-src-stable@freebsd.org Sat Jun 4 15:01:09 2016 Return-Path: Delivered-To: svn-src-stable@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 82336B694BA; Sat, 4 Jun 2016 15:01:09 +0000 (UTC) (envelope-from arybchik@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 5E222167E; Sat, 4 Jun 2016 15:01:09 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u54F1856002441; Sat, 4 Jun 2016 15:01:08 GMT (envelope-from arybchik@FreeBSD.org) Received: (from arybchik@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u54F18K9002439; Sat, 4 Jun 2016 15:01:08 GMT (envelope-from arybchik@FreeBSD.org) Message-Id: <201606041501.u54F18K9002439@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: arybchik set sender to arybchik@FreeBSD.org using -f From: Andrew Rybchenko Date: Sat, 4 Jun 2016 15:01:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r301342 - stable/10/sys/dev/sfxge/common X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 04 Jun 2016 15:01:09 -0000 Author: arybchik Date: Sat Jun 4 15:01:08 2016 New Revision: 301342 URL: https://svnweb.freebsd.org/changeset/base/301342 Log: MFC r299594 sfxge(4): avoid duplicate delivery of packets when changing multicast mode with multicast chaining enabled With multicast chaining, if e.g. a specific multicast filter is inserted and the multicast mis-match filter is then inserted, both may match a packet and cause it to be delivered. Copy the behaviour of the Linux driver, which is to remove the old filters first, on the basis that customers are more likely to be able to handle drops than duplicates (see bug49178 comment 4). Submitted by: Mark Spender Sponsored by: Solarflare Communications, Inc. Modified: stable/10/sys/dev/sfxge/common/hunt_filter.c stable/10/sys/dev/sfxge/common/hunt_impl.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sfxge/common/hunt_filter.c ============================================================================== --- stable/10/sys/dev/sfxge/common/hunt_filter.c Sat Jun 4 14:59:54 2016 (r301341) +++ stable/10/sys/dev/sfxge/common/hunt_filter.c Sat Jun 4 15:01:08 2016 (r301342) @@ -1121,6 +1121,7 @@ ef10_filter_insert_multicast_list( } eftp->eft_mulcst_filter_count = filter_count; + eftp->eft_using_all_mulcst = B_FALSE; return (0); @@ -1160,6 +1161,7 @@ ef10_filter_insert_all_multicast( goto fail1; eftp->eft_mulcst_filter_count = 1; + eftp->eft_using_all_mulcst = B_TRUE; /* * FIXME: If brdcst == B_FALSE, add a filter to drop broadcast traffic. @@ -1173,6 +1175,20 @@ fail1: return (rc); } +static void +ef10_filter_remove_old( + __in efx_nic_t *enp) +{ + ef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table; + uint32_t i; + + for (i = 0; i < EFX_ARRAY_SIZE(table->eft_entry); i++) { + if (ef10_filter_entry_is_auto_old(table, i)) { + (void) ef10_filter_delete_internal(enp, i); + } + } +} + static __checkReturn efx_rc_t hunt_filter_get_workarounds( @@ -1227,6 +1243,7 @@ ef10_filter_reconfigure( __in_ecount(6*count) uint8_t const *addrs, __in uint32_t count) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; ef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table; efx_filter_flag_t filter_flags; unsigned i; @@ -1316,6 +1333,18 @@ ef10_filter_reconfigure( if ((rc = hunt_filter_get_workarounds(enp)) != 0) goto fail2; + if ((table->eft_using_all_mulcst != all_mulcst) && + (encp->enc_bug26807_workaround == B_TRUE)) { + /* + * Multicast filter chaining is enabled, so traffic that matches + * more than one multicast filter will be replicated and + * delivered to multiple recipients. To avoid this duplicate + * delivery, remove old multicast filters before inserting new + * multicast filters. + */ + ef10_filter_remove_old(enp); + } + /* Insert or renew multicast filters */ if (all_mulcst == B_TRUE) { /* @@ -1342,6 +1371,17 @@ ef10_filter_reconfigure( rc = ef10_filter_insert_multicast_list(enp, mulcst, brdcst, addrs, count, filter_flags, B_TRUE); if (rc != 0) { + if ((table->eft_using_all_mulcst == B_FALSE) && + (encp->enc_bug26807_workaround == B_TRUE)) { + /* + * Multicast filter chaining is on, so remove + * old filters before inserting the multicast + * all filter to avoid duplicate delivery caused + * by packets matching multiple filters. + */ + ef10_filter_remove_old(enp); + } + rc = ef10_filter_insert_all_multicast(enp, filter_flags); if (rc != 0) { @@ -1355,11 +1395,7 @@ ef10_filter_reconfigure( } /* Remove old filters which were not renewed */ - for (i = 0; i < EFX_ARRAY_SIZE(table->eft_entry); i++) { - if (ef10_filter_entry_is_auto_old(table, i)) { - (void) ef10_filter_delete_internal(enp, i); - } - } + ef10_filter_remove_old(enp); /* report if any optional flags were rejected */ if (((all_unicst != B_FALSE) && (all_unicst_rc != 0)) || Modified: stable/10/sys/dev/sfxge/common/hunt_impl.h ============================================================================== --- stable/10/sys/dev/sfxge/common/hunt_impl.h Sat Jun 4 14:59:54 2016 (r301341) +++ stable/10/sys/dev/sfxge/common/hunt_impl.h Sat Jun 4 15:01:08 2016 (r301342) @@ -1046,6 +1046,7 @@ typedef struct ef10_filter_table_s { uint32_t eft_mulcst_filter_indexes[ EFX_EF10_FILTER_MULTICAST_FILTERS_MAX]; uint32_t eft_mulcst_filter_count; + boolean_t eft_using_all_mulcst; } ef10_filter_table_t; __checkReturn efx_rc_t