Page MenuHomeFreeBSD

D6295.id16111.diff
No OneTemporary

D6295.id16111.diff

Index: head/sys/dev/sfxge/common/hunt_filter.c
===================================================================
--- head/sys/dev/sfxge/common/hunt_filter.c
+++ head/sys/dev/sfxge/common/hunt_filter.c
@@ -982,19 +982,15 @@
}
static __checkReturn efx_rc_t
-ef10_filter_unicast_refresh(
+ef10_filter_insert_unicast(
__in efx_nic_t *enp,
__in_ecount(6) uint8_t const *addr,
- __in boolean_t all_unicst,
__in efx_filter_flag_t filter_flags)
{
ef10_filter_table_t *eftp = enp->en_filter.ef_ef10_filter_table;
efx_filter_spec_t spec;
efx_rc_t rc;
- if (all_unicst == B_TRUE)
- goto use_uc_def;
-
/* Insert the filter for the local station address */
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
filter_flags,
@@ -1002,43 +998,48 @@
efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC, addr);
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
- &eftp->eft_unicst_filter_index);
- if (rc != 0) {
- /*
- * Fall back to an unknown filter. We may be able to subscribe
- * to it even if we couldn't insert the unicast filter.
- */
- goto use_uc_def;
- }
- eftp->eft_unicst_filter_set = B_TRUE;
+ &eftp->eft_unicst_filter_indexes[eftp->eft_unicst_filter_count]);
+ if (rc != 0)
+ goto fail1;
+
+ eftp->eft_unicst_filter_count++;
+ EFSYS_ASSERT(eftp->eft_unicst_filter_count <=
+ EFX_EF10_FILTER_UNICAST_FILTERS_MAX);
return (0);
-use_uc_def:
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+ return (rc);
+}
+
+static __checkReturn efx_rc_t
+ef10_filter_insert_all_unicast(
+ __in efx_nic_t *enp,
+ __in efx_filter_flag_t filter_flags)
+{
+ ef10_filter_table_t *eftp = enp->en_filter.ef_ef10_filter_table;
+ efx_filter_spec_t spec;
+ efx_rc_t rc;
+
/* Insert the unknown unicast filter */
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
filter_flags,
eftp->eft_default_rxq);
efx_filter_spec_set_uc_def(&spec);
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
- &eftp->eft_unicst_filter_index);
+ &eftp->eft_unicst_filter_indexes[eftp->eft_unicst_filter_count]);
if (rc != 0)
goto fail1;
- eftp->eft_unicst_filter_set = B_TRUE;
+ eftp->eft_unicst_filter_count++;
+ EFSYS_ASSERT(eftp->eft_unicst_filter_count <=
+ EFX_EF10_FILTER_UNICAST_FILTERS_MAX);
return (0);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
-
- if (eftp->eft_unicst_filter_set != B_FALSE) {
- (void) ef10_filter_delete_internal(enp,
- eftp->eft_unicst_filter_index);
-
- eftp->eft_unicst_filter_set = B_FALSE;
- }
-
return (rc);
}
@@ -1207,7 +1208,7 @@
ef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table;
efx_filter_flag_t filter_flags;
unsigned i;
- int all_unicst_rc;
+ int all_unicst_rc = 0;
int all_mulcst_rc;
efx_rc_t rc;
@@ -1218,11 +1219,12 @@
* filters must be removed (ignore errors in case the MC
* has rebooted, which removes hardware filters).
*/
- if (table->eft_unicst_filter_set != B_FALSE) {
+ for (i = 0; i < table->eft_unicst_filter_count; i++) {
(void) ef10_filter_delete_internal(enp,
- table->eft_unicst_filter_index);
- table->eft_unicst_filter_set = B_FALSE;
+ table->eft_unicst_filter_indexes[i]);
}
+ table->eft_unicst_filter_count = 0;
+
for (i = 0; i < table->eft_mulcst_filter_count; i++) {
(void) ef10_filter_delete_internal(enp,
table->eft_mulcst_filter_indexes[i]);
@@ -1238,27 +1240,39 @@
filter_flags = 0;
/* Mark old filters which may need to be removed */
- if (table->eft_unicst_filter_set != B_FALSE) {
+ for (i = 0; i < table->eft_unicst_filter_count; i++) {
ef10_filter_set_entry_auto_old(table,
- table->eft_unicst_filter_index);
+ table->eft_unicst_filter_indexes[i]);
}
for (i = 0; i < table->eft_mulcst_filter_count; i++) {
ef10_filter_set_entry_auto_old(table,
table->eft_mulcst_filter_indexes[i]);
}
- /* Insert or renew unicast filters */
- if ((all_unicst_rc = ef10_filter_unicast_refresh(enp, mac_addr,
- all_unicst, filter_flags)) != 0) {
- if (all_unicst == B_FALSE) {
- rc = all_unicst_rc;
+ /*
+ * Insert or renew unicast filters.
+ *
+ * Frimware does not perform chaining on unicast filters. As traffic is
+ * therefore only delivered to the first matching filter, we should
+ * always insert the specific filter for our MAC address, to try and
+ * ensure we get that traffic.
+ *
+ * (If the filter for our MAC address has already been inserted by
+ * another function, we won't receive traffic sent to us, even if we
+ * insert a unicast mismatch filter. To prevent traffic stealing, this
+ * therefore relies on the privilege model only allowing functions to
+ * insert filters for their own MAC address unless explicitly given
+ * additional privileges by the user. This also means that, even on a
+ * priviliged function, inserting a unicast mismatch filter may not
+ * catch all traffic in multi PCI function scenarios.)
+ */
+ table->eft_unicst_filter_count = 0;
+ rc = ef10_filter_insert_unicast(enp, mac_addr, filter_flags);
+ if (all_unicst || (rc != 0)) {
+ all_unicst_rc = ef10_filter_insert_all_unicast(enp,
+ filter_flags);
+ if ((rc != 0) && (all_unicst_rc != 0))
goto fail1;
- }
- /* Retry without all_unicast flag */
- rc = ef10_filter_unicast_refresh(enp, mac_addr,
- B_FALSE, filter_flags);
- if (rc != 0)
- goto fail2;
}
/*
@@ -1278,7 +1292,7 @@
* FIXME: On Medford multicast chaining should always be on.
*/
if ((rc = hunt_filter_get_workarounds(enp)) != 0)
- goto fail3;
+ goto fail2;
/* Insert or renew multicast filters */
if ((all_mulcst_rc = ef10_filter_multicast_refresh(enp, mulcst,
@@ -1286,14 +1300,14 @@
addrs, count, filter_flags)) != 0) {
if (all_mulcst == B_FALSE) {
rc = all_mulcst_rc;
- goto fail4;
+ goto fail3;
}
/* Retry without all_mulcast flag */
rc = ef10_filter_multicast_refresh(enp, mulcst,
B_FALSE, brdcst,
addrs, count, filter_flags);
if (rc != 0)
- goto fail5;
+ goto fail4;
}
/* Remove old filters which were not renewed */
@@ -1311,8 +1325,6 @@
return (rc);
-fail5:
- EFSYS_PROBE(fail5);
fail4:
EFSYS_PROBE(fail4);
fail3:
Index: head/sys/dev/sfxge/common/hunt_impl.h
===================================================================
--- head/sys/dev/sfxge/common/hunt_impl.h
+++ head/sys/dev/sfxge/common/hunt_impl.h
@@ -966,6 +966,9 @@
*/
#define EFX_EF10_FILTER_TBL_ROWS 8192
+/* Only need to allow for one directed and one unknown unicast filter */
+#define EFX_EF10_FILTER_UNICAST_FILTERS_MAX 2
+
/* Allow for the broadcast address to be added to the multicast list */
#define EFX_EF10_FILTER_MULTICAST_FILTERS_MAX (EFX_MAC_MULTICAST_LIST_MAX + 1)
@@ -973,8 +976,9 @@
ef10_filter_entry_t eft_entry[EFX_EF10_FILTER_TBL_ROWS];
efx_rxq_t * eft_default_rxq;
boolean_t eft_using_rss;
- uint32_t eft_unicst_filter_index;
- boolean_t eft_unicst_filter_set;
+ uint32_t eft_unicst_filter_indexes[
+ EFX_EF10_FILTER_UNICAST_FILTERS_MAX];
+ boolean_t eft_unicst_filter_count;
uint32_t eft_mulcst_filter_indexes[
EFX_EF10_FILTER_MULTICAST_FILTERS_MAX];
uint32_t eft_mulcst_filter_count;

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 4, 7:56 PM (17 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29254750
Default Alt Text
D6295.id16111.diff (7 KB)

Event Timeline