Skip to content

Commit 621650c

Browse files
aloktionJeff Kirsher
authored andcommitted
i40e: Refactoring VF MAC filters counting to make more reliable
This patch prepares ground for the next VF MAC address change fix. It lets untrusted VF to delete any VF mac filter, but it still doesn't let untrusted VF to add mac filter not setup by PF. It removes information duplication in num_mac mac filters counter. And improves exact h/w mac filters usage checking in the i40e_check_vf_permission() function by counting mac2add_cnt. It also improves logging because now all mac addresses will be validated first and corresponding messages will be logged. Signed-off-by: Aleksandr Loktionov <[email protected]> Tested-by: Andrew Bowers <[email protected]>
1 parent d80a476 commit 621650c

File tree

4 files changed

+39
-27
lines changed

4 files changed

+39
-27
lines changed

drivers/net/ethernet/intel/i40e/i40e.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,7 @@ struct i40e_mac_filter *i40e_add_mac_filter(struct i40e_vsi *vsi,
11181118
const u8 *macaddr);
11191119
int i40e_del_mac_filter(struct i40e_vsi *vsi, const u8 *macaddr);
11201120
bool i40e_is_vsi_in_vlan(struct i40e_vsi *vsi);
1121+
int i40e_count_filters(struct i40e_vsi *vsi);
11211122
struct i40e_mac_filter *i40e_find_mac(struct i40e_vsi *vsi, const u8 *macaddr);
11221123
void i40e_vlan_stripping_enable(struct i40e_vsi *vsi);
11231124
#ifdef CONFIG_I40E_DCB

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,25 @@ void i40e_update_stats(struct i40e_vsi *vsi)
11091109
i40e_update_vsi_stats(vsi);
11101110
}
11111111

1112+
/**
1113+
* i40e_count_filters - counts VSI mac filters
1114+
* @vsi: the VSI to be searched
1115+
*
1116+
* Returns count of mac filters
1117+
**/
1118+
int i40e_count_filters(struct i40e_vsi *vsi)
1119+
{
1120+
struct i40e_mac_filter *f;
1121+
struct hlist_node *h;
1122+
int bkt;
1123+
int cnt = 0;
1124+
1125+
hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist)
1126+
++cnt;
1127+
1128+
return cnt;
1129+
}
1130+
11121131
/**
11131132
* i40e_find_filter - Search VSI filter list for specific mac/vlan filter
11141133
* @vsi: the VSI to be searched

drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,6 @@ static void i40e_free_vf_res(struct i40e_vf *vf)
955955
i40e_vsi_release(pf->vsi[vf->lan_vsi_idx]);
956956
vf->lan_vsi_idx = 0;
957957
vf->lan_vsi_id = 0;
958-
vf->num_mac = 0;
959958
}
960959

961960
/* do the accounting and remove additional ADq VSI's */
@@ -2548,20 +2547,12 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,
25482547
struct virtchnl_ether_addr_list *al)
25492548
{
25502549
struct i40e_pf *pf = vf->pf;
2550+
struct i40e_vsi *vsi = pf->vsi[vf->lan_vsi_idx];
2551+
int mac2add_cnt = 0;
25512552
int i;
25522553

2553-
/* If this VF is not privileged, then we can't add more than a limited
2554-
* number of addresses. Check to make sure that the additions do not
2555-
* push us over the limit.
2556-
*/
2557-
if (!test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) &&
2558-
(vf->num_mac + al->num_elements) > I40E_VC_MAX_MAC_ADDR_PER_VF) {
2559-
dev_err(&pf->pdev->dev,
2560-
"Cannot add more MAC addresses, VF is not trusted, switch the VF to trusted to add more functionality\n");
2561-
return -EPERM;
2562-
}
2563-
25642554
for (i = 0; i < al->num_elements; i++) {
2555+
struct i40e_mac_filter *f;
25652556
u8 *addr = al->list[i].addr;
25662557

25672558
if (is_broadcast_ether_addr(addr) ||
@@ -2585,8 +2576,24 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,
25852576
"VF attempting to override administratively set MAC address, bring down and up the VF interface to resume normal operation\n");
25862577
return -EPERM;
25872578
}
2579+
2580+
/*count filters that really will be added*/
2581+
f = i40e_find_mac(vsi, addr);
2582+
if (!f)
2583+
++mac2add_cnt;
25882584
}
25892585

2586+
/* If this VF is not privileged, then we can't add more than a limited
2587+
* number of addresses. Check to make sure that the additions do not
2588+
* push us over the limit.
2589+
*/
2590+
if (!test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) &&
2591+
(i40e_count_filters(vsi) + mac2add_cnt) >
2592+
I40E_VC_MAX_MAC_ADDR_PER_VF) {
2593+
dev_err(&pf->pdev->dev,
2594+
"Cannot add more MAC addresses, VF is not trusted, switch the VF to trusted to add more functionality\n");
2595+
return -EPERM;
2596+
}
25902597
return 0;
25912598
}
25922599

@@ -2640,8 +2647,6 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg)
26402647
ret = I40E_ERR_PARAM;
26412648
spin_unlock_bh(&vsi->mac_filter_hash_lock);
26422649
goto error_param;
2643-
} else {
2644-
vf->num_mac++;
26452650
}
26462651
}
26472652
}
@@ -2689,16 +2694,6 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg)
26892694
ret = I40E_ERR_INVALID_MAC_ADDR;
26902695
goto error_param;
26912696
}
2692-
2693-
if (vf->pf_set_mac &&
2694-
ether_addr_equal(al->list[i].addr,
2695-
vf->default_lan_addr.addr)) {
2696-
dev_err(&pf->pdev->dev,
2697-
"MAC addr %pM has been set by PF, cannot delete it for VF %d, reset VF to change MAC addr\n",
2698-
vf->default_lan_addr.addr, vf->vf_id);
2699-
ret = I40E_ERR_PARAM;
2700-
goto error_param;
2701-
}
27022697
}
27032698
vsi = pf->vsi[vf->lan_vsi_idx];
27042699

@@ -2709,8 +2704,6 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg)
27092704
ret = I40E_ERR_INVALID_MAC_ADDR;
27102705
spin_unlock_bh(&vsi->mac_filter_hash_lock);
27112706
goto error_param;
2712-
} else {
2713-
vf->num_mac--;
27142707
}
27152708

27162709
spin_unlock_bh(&vsi->mac_filter_hash_lock);

drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ struct i40e_vf {
101101
bool link_up; /* only valid if VF link is forced */
102102
bool queues_enabled; /* true if the VF queues are enabled */
103103
bool spoofchk;
104-
u16 num_mac;
105104
u16 num_vlan;
106105

107106
/* ADq related variables */

0 commit comments

Comments
 (0)