Commit e8379c79 authored by Yuval Mintz's avatar Yuval Mintz Committed by David S. Miller

bnx2x: fix VLAN configuration for VFs.

If the hypervisor configures a vlan for the VF via the PF, the expected
result is that only packets tagged by said vlan will be received by the VF
(and that vlan will be silently removed).
Due to an incorrect manipulation of vlan filters in the driver, the
VF can receive untagged traffic even if the hypervisor configured
some vlan for it.

This patch corrects the behaviour.
Signed-off-by: default avatarYuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: default avatarAriel Elior <ariele@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9dfef3ad
...@@ -2038,6 +2038,7 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp, ...@@ -2038,6 +2038,7 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp,
struct bnx2x_vlan_mac_ramrod_params p; struct bnx2x_vlan_mac_ramrod_params p;
struct bnx2x_exe_queue_obj *exeq = &o->exe_queue; struct bnx2x_exe_queue_obj *exeq = &o->exe_queue;
struct bnx2x_exeq_elem *exeq_pos, *exeq_pos_n; struct bnx2x_exeq_elem *exeq_pos, *exeq_pos_n;
unsigned long flags;
int read_lock; int read_lock;
int rc = 0; int rc = 0;
...@@ -2046,8 +2047,9 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp, ...@@ -2046,8 +2047,9 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp,
spin_lock_bh(&exeq->lock); spin_lock_bh(&exeq->lock);
list_for_each_entry_safe(exeq_pos, exeq_pos_n, &exeq->exe_queue, link) { list_for_each_entry_safe(exeq_pos, exeq_pos_n, &exeq->exe_queue, link) {
if (exeq_pos->cmd_data.vlan_mac.vlan_mac_flags == flags = exeq_pos->cmd_data.vlan_mac.vlan_mac_flags;
*vlan_mac_flags) { if (BNX2X_VLAN_MAC_CMP_FLAGS(flags) ==
BNX2X_VLAN_MAC_CMP_FLAGS(*vlan_mac_flags)) {
rc = exeq->remove(bp, exeq->owner, exeq_pos); rc = exeq->remove(bp, exeq->owner, exeq_pos);
if (rc) { if (rc) {
BNX2X_ERR("Failed to remove command\n"); BNX2X_ERR("Failed to remove command\n");
...@@ -2080,7 +2082,9 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp, ...@@ -2080,7 +2082,9 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp,
return read_lock; return read_lock;
list_for_each_entry(pos, &o->head, link) { list_for_each_entry(pos, &o->head, link) {
if (pos->vlan_mac_flags == *vlan_mac_flags) { flags = pos->vlan_mac_flags;
if (BNX2X_VLAN_MAC_CMP_FLAGS(flags) ==
BNX2X_VLAN_MAC_CMP_FLAGS(*vlan_mac_flags)) {
p.user_req.vlan_mac_flags = pos->vlan_mac_flags; p.user_req.vlan_mac_flags = pos->vlan_mac_flags;
memcpy(&p.user_req.u, &pos->u, sizeof(pos->u)); memcpy(&p.user_req.u, &pos->u, sizeof(pos->u));
rc = bnx2x_config_vlan_mac(bp, &p); rc = bnx2x_config_vlan_mac(bp, &p);
......
...@@ -266,6 +266,13 @@ enum { ...@@ -266,6 +266,13 @@ enum {
BNX2X_DONT_CONSUME_CAM_CREDIT, BNX2X_DONT_CONSUME_CAM_CREDIT,
BNX2X_DONT_CONSUME_CAM_CREDIT_DEST, BNX2X_DONT_CONSUME_CAM_CREDIT_DEST,
}; };
/* When looking for matching filters, some flags are not interesting */
#define BNX2X_VLAN_MAC_CMP_MASK (1 << BNX2X_UC_LIST_MAC | \
1 << BNX2X_ETH_MAC | \
1 << BNX2X_ISCSI_ETH_MAC | \
1 << BNX2X_NETQ_ETH_MAC)
#define BNX2X_VLAN_MAC_CMP_FLAGS(flags) \
((flags) & BNX2X_VLAN_MAC_CMP_MASK)
struct bnx2x_vlan_mac_ramrod_params { struct bnx2x_vlan_mac_ramrod_params {
/* Object to run the command from */ /* Object to run the command from */
......
...@@ -74,6 +74,7 @@ struct bnx2x_vf_queue { ...@@ -74,6 +74,7 @@ struct bnx2x_vf_queue {
/* VLANs object */ /* VLANs object */
struct bnx2x_vlan_mac_obj vlan_obj; struct bnx2x_vlan_mac_obj vlan_obj;
atomic_t vlan_count; /* 0 means vlan-0 is set ~ untagged */ atomic_t vlan_count; /* 0 means vlan-0 is set ~ untagged */
unsigned long accept_flags; /* last accept flags configured */
/* Queue Slow-path State object */ /* Queue Slow-path State object */
struct bnx2x_queue_sp_obj sp_obj; struct bnx2x_queue_sp_obj sp_obj;
......
...@@ -1598,6 +1598,8 @@ static void bnx2x_vfop_mbx_qfilters(struct bnx2x *bp, struct bnx2x_virtf *vf) ...@@ -1598,6 +1598,8 @@ static void bnx2x_vfop_mbx_qfilters(struct bnx2x *bp, struct bnx2x_virtf *vf)
if (msg->flags & VFPF_SET_Q_FILTERS_RX_MASK_CHANGED) { if (msg->flags & VFPF_SET_Q_FILTERS_RX_MASK_CHANGED) {
unsigned long accept = 0; unsigned long accept = 0;
struct pf_vf_bulletin_content *bulletin =
BP_VF_BULLETIN(bp, vf->index);
/* covert VF-PF if mask to bnx2x accept flags */ /* covert VF-PF if mask to bnx2x accept flags */
if (msg->rx_mask & VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST) if (msg->rx_mask & VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST)
...@@ -1617,9 +1619,11 @@ static void bnx2x_vfop_mbx_qfilters(struct bnx2x *bp, struct bnx2x_virtf *vf) ...@@ -1617,9 +1619,11 @@ static void bnx2x_vfop_mbx_qfilters(struct bnx2x *bp, struct bnx2x_virtf *vf)
__set_bit(BNX2X_ACCEPT_BROADCAST, &accept); __set_bit(BNX2X_ACCEPT_BROADCAST, &accept);
/* A packet arriving the vf's mac should be accepted /* A packet arriving the vf's mac should be accepted
* with any vlan * with any vlan, unless a vlan has already been
* configured.
*/ */
__set_bit(BNX2X_ACCEPT_ANY_VLAN, &accept); if (!(bulletin->valid_bitmap & (1 << VLAN_VALID)))
__set_bit(BNX2X_ACCEPT_ANY_VLAN, &accept);
/* set rx-mode */ /* set rx-mode */
rc = bnx2x_vfop_rxmode_cmd(bp, vf, &cmd, rc = bnx2x_vfop_rxmode_cmd(bp, vf, &cmd,
...@@ -1710,6 +1714,21 @@ static void bnx2x_vf_mbx_set_q_filters(struct bnx2x *bp, ...@@ -1710,6 +1714,21 @@ static void bnx2x_vf_mbx_set_q_filters(struct bnx2x *bp,
goto response; goto response;
} }
} }
/* if vlan was set by hypervisor we don't allow guest to config vlan */
if (bulletin->valid_bitmap & 1 << VLAN_VALID) {
int i;
/* search for vlan filters */
for (i = 0; i < filters->n_mac_vlan_filters; i++) {
if (filters->filters[i].flags &
VFPF_Q_FILTER_VLAN_TAG_VALID) {
BNX2X_ERR("VF[%d] attempted to configure vlan but one was already set by Hypervisor. Aborting request\n",
vf->abs_vfid);
vf->op_rc = -EPERM;
goto response;
}
}
}
/* verify vf_qid */ /* verify vf_qid */
if (filters->vf_qid > vf_rxq_count(vf)) if (filters->vf_qid > vf_rxq_count(vf))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment