Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146579842
D6295.id16111.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D6295.id16111.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D6295: sfxge(4): update unicast filter insertion algorithm
Attached
Detach File
Event Timeline
Log In to Comment