Skip to content

Commit

Permalink
net/ncsi: Don't limit vids based on hot_channel
Browse files Browse the repository at this point in the history
Currently we drop any new VLAN ids if there are more than the current
(or last used) channel can support. Most importantly this is a problem
if no channel has been selected yet, resulting in a segfault.

Secondly this does not necessarily reflect the capabilities of any other
channels. Instead only drop a new VLAN id if we are already tracking the
maximum allowed by the NCSI specification. Per-channel limits are
already handled by ncsi_add_filter(), but add a message to set_one_vid()
to make it obvious that the channel can not support any more VLAN ids.

Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Samuel Mendoza-Jonas authored and David S. Miller committed Oct 12, 2017
1 parent bde135a commit 6e9c007
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 8 deletions.
1 change: 1 addition & 0 deletions net/ncsi/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ struct ncsi_dev_priv {
struct work_struct work; /* For channel management */
struct packet_type ptype; /* NCSI packet Rx handler */
struct list_head node; /* Form NCSI device list */
#define NCSI_MAX_VLAN_VIDS 15
struct list_head vlan_vids; /* List of active VLAN IDs */
};

Expand Down
17 changes: 9 additions & 8 deletions net/ncsi/ncsi-manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,10 @@ static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc,
if (index < 0) {
netdev_err(ndp->ndev.dev,
"Failed to add new VLAN tag, error %d\n", index);
if (index == -ENOSPC)
netdev_err(ndp->ndev.dev,
"Channel %u already has all VLAN filters set\n",
nc->id);
return -1;
}

Expand Down Expand Up @@ -1403,7 +1407,6 @@ static int ncsi_kick_channels(struct ncsi_dev_priv *ndp)

int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
{
struct ncsi_channel_filter *ncf;
struct ncsi_dev_priv *ndp;
unsigned int n_vids = 0;
struct vlan_vid *vlan;
Expand All @@ -1420,7 +1423,6 @@ int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
}

ndp = TO_NCSI_DEV_PRIV(nd);
ncf = ndp->hot_channel->filters[NCSI_FILTER_VLAN];

/* Add the VLAN id to our internal list */
list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) {
Expand All @@ -1431,12 +1433,11 @@ int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
return 0;
}
}

if (n_vids >= ncf->total) {
netdev_info(dev,
"NCSI Channel supports up to %u VLAN tags but %u are already set\n",
ncf->total, n_vids);
return -EINVAL;
if (n_vids >= NCSI_MAX_VLAN_VIDS) {
netdev_warn(dev,
"tried to add vlan id %u but NCSI max already registered (%u)\n",
vid, NCSI_MAX_VLAN_VIDS);
return -ENOSPC;
}

vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
Expand Down

0 comments on commit 6e9c007

Please sign in to comment.