aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSridhar Samudrala <sridhar.samudrala@intel.com>2016-03-07 12:41:47 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2016-03-30 02:05:51 -0400
commit176621c964e9279c42c6b641688360e5cd0baedf (patch)
tree3c8ebadaf5d5fb3c79d544a83e63269678856600
parent6e2a60b57a83ea134c06c5226aaff20e7e9ce221 (diff)
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: Sridhar Samudrala <sridhar.samudrala@intel.com> Acked-by: John Fastabend <john.r.fastabend@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c52
1 files changed, 34 insertions, 18 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index f5736a3b252e..ca9c54341784 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8192,10 +8192,17 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
8192static int ixgbe_delete_clsu32(struct ixgbe_adapter *adapter, 8192static int ixgbe_delete_clsu32(struct ixgbe_adapter *adapter,
8193 struct tc_cls_u32_offload *cls) 8193 struct tc_cls_u32_offload *cls)
8194{ 8194{
8195 u32 uhtid = TC_U32_USERHTID(cls->knode.handle);
8196 u32 loc;
8195 int err; 8197 int err;
8196 8198
8199 if ((uhtid != 0x800) && (uhtid >= IXGBE_MAX_LINK_HANDLE))
8200 return -EINVAL;
8201
8202 loc = cls->knode.handle & 0xfffff;
8203
8197 spin_lock(&adapter->fdir_perfect_lock); 8204 spin_lock(&adapter->fdir_perfect_lock);
8198 err = ixgbe_update_ethtool_fdir_entry(adapter, NULL, cls->knode.handle); 8205 err = ixgbe_update_ethtool_fdir_entry(adapter, NULL, loc);
8199 spin_unlock(&adapter->fdir_perfect_lock); 8206 spin_unlock(&adapter->fdir_perfect_lock);
8200 return err; 8207 return err;
8201} 8208}
@@ -8204,20 +8211,30 @@ static int ixgbe_configure_clsu32_add_hnode(struct ixgbe_adapter *adapter,
8204 __be16 protocol, 8211 __be16 protocol,
8205 struct tc_cls_u32_offload *cls) 8212 struct tc_cls_u32_offload *cls)
8206{ 8213{
8214 u32 uhtid = TC_U32_USERHTID(cls->hnode.handle);
8215
8216 if (uhtid >= IXGBE_MAX_LINK_HANDLE)
8217 return -EINVAL;
8218
8207 /* This ixgbe devices do not support hash tables at the moment 8219 /* This ixgbe devices do not support hash tables at the moment
8208 * so abort when given hash tables. 8220 * so abort when given hash tables.
8209 */ 8221 */
8210 if (cls->hnode.divisor > 0) 8222 if (cls->hnode.divisor > 0)
8211 return -EINVAL; 8223 return -EINVAL;
8212 8224
8213 set_bit(TC_U32_USERHTID(cls->hnode.handle), &adapter->tables); 8225 set_bit(uhtid - 1, &adapter->tables);
8214 return 0; 8226 return 0;
8215} 8227}
8216 8228
8217static int ixgbe_configure_clsu32_del_hnode(struct ixgbe_adapter *adapter, 8229static int ixgbe_configure_clsu32_del_hnode(struct ixgbe_adapter *adapter,
8218 struct tc_cls_u32_offload *cls) 8230 struct tc_cls_u32_offload *cls)
8219{ 8231{
8220 clear_bit(TC_U32_USERHTID(cls->hnode.handle), &adapter->tables); 8232 u32 uhtid = TC_U32_USERHTID(cls->hnode.handle);
8233
8234 if (uhtid >= IXGBE_MAX_LINK_HANDLE)
8235 return -EINVAL;
8236
8237 clear_bit(uhtid - 1, &adapter->tables);
8221 return 0; 8238 return 0;
8222} 8239}
8223 8240
@@ -8235,27 +8252,29 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
8235#endif 8252#endif
8236 int i, err = 0; 8253 int i, err = 0;
8237 u8 queue; 8254 u8 queue;
8238 u32 handle; 8255 u32 uhtid, link_uhtid;
8239 8256
8240 memset(&mask, 0, sizeof(union ixgbe_atr_input)); 8257 memset(&mask, 0, sizeof(union ixgbe_atr_input));
8241 handle = cls->knode.handle; 8258 uhtid = TC_U32_USERHTID(cls->knode.handle);
8259 link_uhtid = TC_U32_USERHTID(cls->knode.link_handle);
8242 8260
8243 /* At the moment cls_u32 jumps to transport layer and skips past 8261 /* At the moment cls_u32 jumps to network layer and skips past
8244 * L2 headers. The canonical method to match L2 frames is to use 8262 * L2 headers. The canonical method to match L2 frames is to use
8245 * negative values. However this is error prone at best but really 8263 * negative values. However this is error prone at best but really
8246 * just broken because there is no way to "know" what sort of hdr 8264 * just broken because there is no way to "know" what sort of hdr
8247 * is in front of the transport layer. Fix cls_u32 to support L2 8265 * is in front of the network layer. Fix cls_u32 to support L2
8248 * headers when needed. 8266 * headers when needed.
8249 */ 8267 */
8250 if (protocol != htons(ETH_P_IP)) 8268 if (protocol != htons(ETH_P_IP))
8251 return -EINVAL; 8269 return -EINVAL;
8252 8270
8253 if (cls->knode.link_handle || 8271 if (link_uhtid) {
8254 cls->knode.link_handle >= IXGBE_MAX_LINK_HANDLE) {
8255 struct ixgbe_nexthdr *nexthdr = ixgbe_ipv4_jumps; 8272 struct ixgbe_nexthdr *nexthdr = ixgbe_ipv4_jumps;
8256 u32 uhtid = TC_U32_USERHTID(cls->knode.link_handle);
8257 8273
8258 if (!test_bit(uhtid, &adapter->tables)) 8274 if (link_uhtid >= IXGBE_MAX_LINK_HANDLE)
8275 return -EINVAL;
8276
8277 if (!test_bit(link_uhtid - 1, &adapter->tables))
8259 return -EINVAL; 8278 return -EINVAL;
8260 8279
8261 for (i = 0; nexthdr[i].jump; i++) { 8280 for (i = 0; nexthdr[i].jump; i++) {
@@ -8271,10 +8290,7 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
8271 nexthdr->mask != cls->knode.sel->keys[0].mask) 8290 nexthdr->mask != cls->knode.sel->keys[0].mask)
8272 return -EINVAL; 8291 return -EINVAL;
8273 8292
8274 if (uhtid >= IXGBE_MAX_LINK_HANDLE) 8293 adapter->jump_tables[link_uhtid] = nexthdr->jump;
8275 return -EINVAL;
8276
8277 adapter->jump_tables[uhtid] = nexthdr->jump;
8278 } 8294 }
8279 return 0; 8295 return 0;
8280 } 8296 }
@@ -8291,13 +8307,13 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
8291 * To add support for new nodes update ixgbe_model.h parse structures 8307 * To add support for new nodes update ixgbe_model.h parse structures
8292 * this function _should_ be generic try not to hardcode values here. 8308 * this function _should_ be generic try not to hardcode values here.
8293 */ 8309 */
8294 if (TC_U32_USERHTID(handle) == 0x800) { 8310 if (uhtid == 0x800) {
8295 field_ptr = adapter->jump_tables[0]; 8311 field_ptr = adapter->jump_tables[0];
8296 } else { 8312 } else {
8297 if (TC_U32_USERHTID(handle) >= ARRAY_SIZE(adapter->jump_tables)) 8313 if (uhtid >= IXGBE_MAX_LINK_HANDLE)
8298 return -EINVAL; 8314 return -EINVAL;
8299 8315
8300 field_ptr = adapter->jump_tables[TC_U32_USERHTID(handle)]; 8316 field_ptr = adapter->jump_tables[uhtid];
8301 } 8317 }
8302 8318
8303 if (!field_ptr) 8319 if (!field_ptr)