提交 176621c9 编写于 作者: S Sridhar Samudrala 提交者: Jeff Kirsher

ixgbe: fix error handling in TC cls_u32 offload routines

Check for handle ids when adding/deleting hash nodes OR adding/deleting
filter entries and limit them to max number of links or header nodes
supported(IXGBE_MAX_LINK_HANDLE).

Start from bit 0 when setting hash table bit-map.(adapter->tables)
Signed-off-by: NSridhar Samudrala <sridhar.samudrala@intel.com>
Acked-by: NJohn Fastabend <john.r.fastabend@intel.com>
Tested-by: NAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: NJeff Kirsher <jeffrey.t.kirsher@intel.com>
上级 6e2a60b5
...@@ -8192,10 +8192,17 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) ...@@ -8192,10 +8192,17 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
static int ixgbe_delete_clsu32(struct ixgbe_adapter *adapter, static int ixgbe_delete_clsu32(struct ixgbe_adapter *adapter,
struct tc_cls_u32_offload *cls) struct tc_cls_u32_offload *cls)
{ {
u32 uhtid = TC_U32_USERHTID(cls->knode.handle);
u32 loc;
int err; int err;
if ((uhtid != 0x800) && (uhtid >= IXGBE_MAX_LINK_HANDLE))
return -EINVAL;
loc = cls->knode.handle & 0xfffff;
spin_lock(&adapter->fdir_perfect_lock); spin_lock(&adapter->fdir_perfect_lock);
err = ixgbe_update_ethtool_fdir_entry(adapter, NULL, cls->knode.handle); err = ixgbe_update_ethtool_fdir_entry(adapter, NULL, loc);
spin_unlock(&adapter->fdir_perfect_lock); spin_unlock(&adapter->fdir_perfect_lock);
return err; return err;
} }
...@@ -8204,20 +8211,30 @@ static int ixgbe_configure_clsu32_add_hnode(struct ixgbe_adapter *adapter, ...@@ -8204,20 +8211,30 @@ static int ixgbe_configure_clsu32_add_hnode(struct ixgbe_adapter *adapter,
__be16 protocol, __be16 protocol,
struct tc_cls_u32_offload *cls) struct tc_cls_u32_offload *cls)
{ {
u32 uhtid = TC_U32_USERHTID(cls->hnode.handle);
if (uhtid >= IXGBE_MAX_LINK_HANDLE)
return -EINVAL;
/* This ixgbe devices do not support hash tables at the moment /* This ixgbe devices do not support hash tables at the moment
* so abort when given hash tables. * so abort when given hash tables.
*/ */
if (cls->hnode.divisor > 0) if (cls->hnode.divisor > 0)
return -EINVAL; return -EINVAL;
set_bit(TC_U32_USERHTID(cls->hnode.handle), &adapter->tables); set_bit(uhtid - 1, &adapter->tables);
return 0; return 0;
} }
static int ixgbe_configure_clsu32_del_hnode(struct ixgbe_adapter *adapter, static int ixgbe_configure_clsu32_del_hnode(struct ixgbe_adapter *adapter,
struct tc_cls_u32_offload *cls) struct tc_cls_u32_offload *cls)
{ {
clear_bit(TC_U32_USERHTID(cls->hnode.handle), &adapter->tables); u32 uhtid = TC_U32_USERHTID(cls->hnode.handle);
if (uhtid >= IXGBE_MAX_LINK_HANDLE)
return -EINVAL;
clear_bit(uhtid - 1, &adapter->tables);
return 0; return 0;
} }
...@@ -8235,27 +8252,29 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, ...@@ -8235,27 +8252,29 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
#endif #endif
int i, err = 0; int i, err = 0;
u8 queue; u8 queue;
u32 handle; u32 uhtid, link_uhtid;
memset(&mask, 0, sizeof(union ixgbe_atr_input)); memset(&mask, 0, sizeof(union ixgbe_atr_input));
handle = cls->knode.handle; uhtid = TC_U32_USERHTID(cls->knode.handle);
link_uhtid = TC_U32_USERHTID(cls->knode.link_handle);
/* At the moment cls_u32 jumps to transport layer and skips past /* At the moment cls_u32 jumps to network layer and skips past
* L2 headers. The canonical method to match L2 frames is to use * L2 headers. The canonical method to match L2 frames is to use
* negative values. However this is error prone at best but really * negative values. However this is error prone at best but really
* just broken because there is no way to "know" what sort of hdr * just broken because there is no way to "know" what sort of hdr
* is in front of the transport layer. Fix cls_u32 to support L2 * is in front of the network layer. Fix cls_u32 to support L2
* headers when needed. * headers when needed.
*/ */
if (protocol != htons(ETH_P_IP)) if (protocol != htons(ETH_P_IP))
return -EINVAL; return -EINVAL;
if (cls->knode.link_handle || if (link_uhtid) {
cls->knode.link_handle >= IXGBE_MAX_LINK_HANDLE) {
struct ixgbe_nexthdr *nexthdr = ixgbe_ipv4_jumps; struct ixgbe_nexthdr *nexthdr = ixgbe_ipv4_jumps;
u32 uhtid = TC_U32_USERHTID(cls->knode.link_handle);
if (!test_bit(uhtid, &adapter->tables)) if (link_uhtid >= IXGBE_MAX_LINK_HANDLE)
return -EINVAL;
if (!test_bit(link_uhtid - 1, &adapter->tables))
return -EINVAL; return -EINVAL;
for (i = 0; nexthdr[i].jump; i++) { for (i = 0; nexthdr[i].jump; i++) {
...@@ -8271,10 +8290,7 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, ...@@ -8271,10 +8290,7 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
nexthdr->mask != cls->knode.sel->keys[0].mask) nexthdr->mask != cls->knode.sel->keys[0].mask)
return -EINVAL; return -EINVAL;
if (uhtid >= IXGBE_MAX_LINK_HANDLE) adapter->jump_tables[link_uhtid] = nexthdr->jump;
return -EINVAL;
adapter->jump_tables[uhtid] = nexthdr->jump;
} }
return 0; return 0;
} }
...@@ -8291,13 +8307,13 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, ...@@ -8291,13 +8307,13 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
* To add support for new nodes update ixgbe_model.h parse structures * To add support for new nodes update ixgbe_model.h parse structures
* this function _should_ be generic try not to hardcode values here. * this function _should_ be generic try not to hardcode values here.
*/ */
if (TC_U32_USERHTID(handle) == 0x800) { if (uhtid == 0x800) {
field_ptr = adapter->jump_tables[0]; field_ptr = adapter->jump_tables[0];
} else { } else {
if (TC_U32_USERHTID(handle) >= ARRAY_SIZE(adapter->jump_tables)) if (uhtid >= IXGBE_MAX_LINK_HANDLE)
return -EINVAL; return -EINVAL;
field_ptr = adapter->jump_tables[TC_U32_USERHTID(handle)]; field_ptr = adapter->jump_tables[uhtid];
} }
if (!field_ptr) if (!field_ptr)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册