diff options
author | Samuel Mendoza-Jonas <sam@mendozajonas.com> | 2017-10-11 01:54:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-10-11 23:10:37 -0400 |
commit | 6e9c0075409d4ec1bc63558ee5a93916a6d7d16f (patch) | |
tree | 581473860a778dc30a19cbf9a9026bc639af517a | |
parent | bde135a672bfd1cc41d91c2bbbbd36eb25409b74 (diff) |
net/ncsi: Don't limit vids based on hot_channel
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>
-rw-r--r-- | net/ncsi/internal.h | 1 | ||||
-rw-r--r-- | net/ncsi/ncsi-manage.c | 17 |
2 files changed, 10 insertions, 8 deletions
diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h index af3d636534ef..d30f7bd741d0 100644 --- a/net/ncsi/internal.h +++ b/net/ncsi/internal.h | |||
@@ -286,6 +286,7 @@ struct ncsi_dev_priv { | |||
286 | struct work_struct work; /* For channel management */ | 286 | struct work_struct work; /* For channel management */ |
287 | struct packet_type ptype; /* NCSI packet Rx handler */ | 287 | struct packet_type ptype; /* NCSI packet Rx handler */ |
288 | struct list_head node; /* Form NCSI device list */ | 288 | struct list_head node; /* Form NCSI device list */ |
289 | #define NCSI_MAX_VLAN_VIDS 15 | ||
289 | struct list_head vlan_vids; /* List of active VLAN IDs */ | 290 | struct list_head vlan_vids; /* List of active VLAN IDs */ |
290 | }; | 291 | }; |
291 | 292 | ||
diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c index 3fd3c39e6278..b6a449aa9d4b 100644 --- a/net/ncsi/ncsi-manage.c +++ b/net/ncsi/ncsi-manage.c | |||
@@ -732,6 +732,10 @@ static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc, | |||
732 | if (index < 0) { | 732 | if (index < 0) { |
733 | netdev_err(ndp->ndev.dev, | 733 | netdev_err(ndp->ndev.dev, |
734 | "Failed to add new VLAN tag, error %d\n", index); | 734 | "Failed to add new VLAN tag, error %d\n", index); |
735 | if (index == -ENOSPC) | ||
736 | netdev_err(ndp->ndev.dev, | ||
737 | "Channel %u already has all VLAN filters set\n", | ||
738 | nc->id); | ||
735 | return -1; | 739 | return -1; |
736 | } | 740 | } |
737 | 741 | ||
@@ -1403,7 +1407,6 @@ static int ncsi_kick_channels(struct ncsi_dev_priv *ndp) | |||
1403 | 1407 | ||
1404 | int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) | 1408 | int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) |
1405 | { | 1409 | { |
1406 | struct ncsi_channel_filter *ncf; | ||
1407 | struct ncsi_dev_priv *ndp; | 1410 | struct ncsi_dev_priv *ndp; |
1408 | unsigned int n_vids = 0; | 1411 | unsigned int n_vids = 0; |
1409 | struct vlan_vid *vlan; | 1412 | struct vlan_vid *vlan; |
@@ -1420,7 +1423,6 @@ int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) | |||
1420 | } | 1423 | } |
1421 | 1424 | ||
1422 | ndp = TO_NCSI_DEV_PRIV(nd); | 1425 | ndp = TO_NCSI_DEV_PRIV(nd); |
1423 | ncf = ndp->hot_channel->filters[NCSI_FILTER_VLAN]; | ||
1424 | 1426 | ||
1425 | /* Add the VLAN id to our internal list */ | 1427 | /* Add the VLAN id to our internal list */ |
1426 | list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) { | 1428 | list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) { |
@@ -1431,12 +1433,11 @@ int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) | |||
1431 | return 0; | 1433 | return 0; |
1432 | } | 1434 | } |
1433 | } | 1435 | } |
1434 | 1436 | if (n_vids >= NCSI_MAX_VLAN_VIDS) { | |
1435 | if (n_vids >= ncf->total) { | 1437 | netdev_warn(dev, |
1436 | netdev_info(dev, | 1438 | "tried to add vlan id %u but NCSI max already registered (%u)\n", |
1437 | "NCSI Channel supports up to %u VLAN tags but %u are already set\n", | 1439 | vid, NCSI_MAX_VLAN_VIDS); |
1438 | ncf->total, n_vids); | 1440 | return -ENOSPC; |
1439 | return -EINVAL; | ||
1440 | } | 1441 | } |
1441 | 1442 | ||
1442 | vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); | 1443 | vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); |