1 /* 2 * This file is part of the Chelsio T4 Ethernet driver for Linux. 3 * 4 * Copyright (c) 2016 Chelsio Communications, Inc. All rights reserved. 5 * 6 * This software is available to you under a choice of one of two 7 * licenses. You may choose to be licensed under the terms of the GNU 8 * General Public License (GPL) Version 2, available from the file 9 * COPYING in the main directory of this source tree, or the 10 * OpenIB.org BSD license below: 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer. 19 * 20 * - Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials 23 * provided with the distribution. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 * SOFTWARE. 33 */ 34 35 #include <net/tc_act/tc_gact.h> 36 #include <net/tc_act/tc_mirred.h> 37 38 #include "cxgb4.h" 39 #include "cxgb4_filter.h" 40 #include "cxgb4_tc_u32_parse.h" 41 #include "cxgb4_tc_u32.h" 42 43 /* Fill ch_filter_specification with parsed match value/mask pair. */ 44 static int fill_match_fields(struct adapter *adap, 45 struct ch_filter_specification *fs, 46 struct tc_cls_u32_offload *cls, 47 const struct cxgb4_match_field *entry, 48 bool next_header) 49 { 50 unsigned int i, j; 51 u32 val, mask; 52 int off, err; 53 bool found; 54 55 for (i = 0; i < cls->knode.sel->nkeys; i++) { 56 off = cls->knode.sel->keys[i].off; 57 val = cls->knode.sel->keys[i].val; 58 mask = cls->knode.sel->keys[i].mask; 59 60 if (next_header) { 61 /* For next headers, parse only keys with offmask */ 62 if (!cls->knode.sel->keys[i].offmask) 63 continue; 64 } else { 65 /* For the remaining, parse only keys without offmask */ 66 if (cls->knode.sel->keys[i].offmask) 67 continue; 68 } 69 70 found = false; 71 72 for (j = 0; entry[j].val; j++) { 73 if (off == entry[j].off) { 74 found = true; 75 err = entry[j].val(fs, val, mask); 76 if (err) 77 return err; 78 break; 79 } 80 } 81 82 if (!found) 83 return -EINVAL; 84 } 85 86 return 0; 87 } 88 89 /* Fill ch_filter_specification with parsed action. */ 90 static int fill_action_fields(struct adapter *adap, 91 struct ch_filter_specification *fs, 92 struct tc_cls_u32_offload *cls) 93 { 94 unsigned int num_actions = 0; 95 const struct tc_action *a; 96 struct tcf_exts *exts; 97 int i; 98 99 exts = cls->knode.exts; 100 if (!tcf_exts_has_actions(exts)) 101 return -EINVAL; 102 103 tcf_exts_for_each_action(i, a, exts) { 104 /* Don't allow more than one action per rule. */ 105 if (num_actions) 106 return -EINVAL; 107 108 /* Drop in hardware. */ 109 if (is_tcf_gact_shot(a)) { 110 fs->action = FILTER_DROP; 111 num_actions++; 112 continue; 113 } 114 115 /* Re-direct to specified port in hardware. */ 116 if (is_tcf_mirred_egress_redirect(a)) { 117 struct net_device *n_dev, *target_dev; 118 bool found = false; 119 unsigned int i; 120 121 target_dev = tcf_mirred_dev(a); 122 for_each_port(adap, i) { 123 n_dev = adap->port[i]; 124 if (target_dev == n_dev) { 125 fs->action = FILTER_SWITCH; 126 fs->eport = i; 127 found = true; 128 break; 129 } 130 } 131 132 /* Interface doesn't belong to any port of 133 * the underlying hardware. 134 */ 135 if (!found) 136 return -EINVAL; 137 138 num_actions++; 139 continue; 140 } 141 142 /* Un-supported action. */ 143 return -EINVAL; 144 } 145 146 return 0; 147 } 148 149 int cxgb4_config_knode(struct net_device *dev, struct tc_cls_u32_offload *cls) 150 { 151 const struct cxgb4_match_field *start, *link_start = NULL; 152 struct netlink_ext_ack *extack = cls->common.extack; 153 struct adapter *adapter = netdev2adap(dev); 154 __be16 protocol = cls->common.protocol; 155 struct ch_filter_specification fs; 156 struct cxgb4_tc_u32_table *t; 157 struct cxgb4_link *link; 158 unsigned int filter_id; 159 u32 uhtid, link_uhtid; 160 bool is_ipv6 = false; 161 int ret; 162 163 if (!can_tc_u32_offload(dev)) 164 return -EOPNOTSUPP; 165 166 if (protocol != htons(ETH_P_IP) && protocol != htons(ETH_P_IPV6)) 167 return -EOPNOTSUPP; 168 169 /* Note that TC uses prio 0 to indicate stack to generate 170 * automatic prio and hence doesn't pass prio 0 to driver. 171 * However, the hardware TCAM index starts from 0. Hence, the 172 * -1 here. 173 */ 174 filter_id = TC_U32_NODE(cls->knode.handle) - 1; 175 176 /* Only insert U32 rule if its priority doesn't conflict with 177 * existing rules in the LETCAM. 178 */ 179 if (filter_id >= adapter->tids.nftids || 180 !cxgb4_filter_prio_in_range(dev, filter_id, cls->common.prio)) { 181 NL_SET_ERR_MSG_MOD(extack, 182 "No free LETCAM index available"); 183 return -ENOMEM; 184 } 185 186 t = adapter->tc_u32; 187 uhtid = TC_U32_USERHTID(cls->knode.handle); 188 link_uhtid = TC_U32_USERHTID(cls->knode.link_handle); 189 190 /* Ensure that uhtid is either root u32 (i.e. 0x800) 191 * or a a valid linked bucket. 192 */ 193 if (uhtid != 0x800 && uhtid >= t->size) 194 return -EINVAL; 195 196 /* Ensure link handle uhtid is sane, if specified. */ 197 if (link_uhtid >= t->size) 198 return -EINVAL; 199 200 memset(&fs, 0, sizeof(fs)); 201 202 fs.tc_prio = cls->common.prio; 203 fs.tc_cookie = cls->knode.handle; 204 205 if (protocol == htons(ETH_P_IPV6)) { 206 start = cxgb4_ipv6_fields; 207 is_ipv6 = true; 208 } else { 209 start = cxgb4_ipv4_fields; 210 is_ipv6 = false; 211 } 212 213 if (uhtid != 0x800) { 214 /* Link must exist from root node before insertion. */ 215 if (!t->table[uhtid - 1].link_handle) 216 return -EINVAL; 217 218 /* Link must have a valid supported next header. */ 219 link_start = t->table[uhtid - 1].match_field; 220 if (!link_start) 221 return -EINVAL; 222 } 223 224 /* Parse links and record them for subsequent jumps to valid 225 * next headers. 226 */ 227 if (link_uhtid) { 228 const struct cxgb4_next_header *next; 229 bool found = false; 230 unsigned int i, j; 231 u32 val, mask; 232 int off; 233 234 if (t->table[link_uhtid - 1].link_handle) { 235 dev_err(adapter->pdev_dev, 236 "Link handle exists for: 0x%x\n", 237 link_uhtid); 238 return -EINVAL; 239 } 240 241 next = is_ipv6 ? cxgb4_ipv6_jumps : cxgb4_ipv4_jumps; 242 243 /* Try to find matches that allow jumps to next header. */ 244 for (i = 0; next[i].jump; i++) { 245 if (next[i].offoff != cls->knode.sel->offoff || 246 next[i].shift != cls->knode.sel->offshift || 247 next[i].mask != cls->knode.sel->offmask || 248 next[i].offset != cls->knode.sel->off) 249 continue; 250 251 /* Found a possible candidate. Find a key that 252 * matches the corresponding offset, value, and 253 * mask to jump to next header. 254 */ 255 for (j = 0; j < cls->knode.sel->nkeys; j++) { 256 off = cls->knode.sel->keys[j].off; 257 val = cls->knode.sel->keys[j].val; 258 mask = cls->knode.sel->keys[j].mask; 259 260 if (next[i].match_off == off && 261 next[i].match_val == val && 262 next[i].match_mask == mask) { 263 found = true; 264 break; 265 } 266 } 267 268 if (!found) 269 continue; /* Try next candidate. */ 270 271 /* Candidate to jump to next header found. 272 * Translate all keys to internal specification 273 * and store them in jump table. This spec is copied 274 * later to set the actual filters. 275 */ 276 ret = fill_match_fields(adapter, &fs, cls, 277 start, false); 278 if (ret) 279 goto out; 280 281 link = &t->table[link_uhtid - 1]; 282 link->match_field = next[i].jump; 283 link->link_handle = cls->knode.handle; 284 memcpy(&link->fs, &fs, sizeof(fs)); 285 break; 286 } 287 288 /* No candidate found to jump to next header. */ 289 if (!found) 290 return -EINVAL; 291 292 return 0; 293 } 294 295 /* Fill ch_filter_specification match fields to be shipped to hardware. 296 * Copy the linked spec (if any) first. And then update the spec as 297 * needed. 298 */ 299 if (uhtid != 0x800 && t->table[uhtid - 1].link_handle) { 300 /* Copy linked ch_filter_specification */ 301 memcpy(&fs, &t->table[uhtid - 1].fs, sizeof(fs)); 302 ret = fill_match_fields(adapter, &fs, cls, 303 link_start, true); 304 if (ret) 305 goto out; 306 } 307 308 ret = fill_match_fields(adapter, &fs, cls, start, false); 309 if (ret) 310 goto out; 311 312 /* Fill ch_filter_specification action fields to be shipped to 313 * hardware. 314 */ 315 ret = fill_action_fields(adapter, &fs, cls); 316 if (ret) 317 goto out; 318 319 /* The filter spec has been completely built from the info 320 * provided from u32. We now set some default fields in the 321 * spec for sanity. 322 */ 323 324 /* Match only packets coming from the ingress port where this 325 * filter will be created. 326 */ 327 fs.val.iport = netdev2pinfo(dev)->port_id; 328 fs.mask.iport = ~0; 329 330 /* Enable filter hit counts. */ 331 fs.hitcnts = 1; 332 333 /* Set type of filter - IPv6 or IPv4 */ 334 fs.type = is_ipv6 ? 1 : 0; 335 336 /* Set the filter */ 337 ret = cxgb4_set_filter(dev, filter_id, &fs); 338 if (ret) 339 goto out; 340 341 /* If this is a linked bucket, then set the corresponding 342 * entry in the bitmap to mark it as belonging to this linked 343 * bucket. 344 */ 345 if (uhtid != 0x800 && t->table[uhtid - 1].link_handle) 346 set_bit(filter_id, t->table[uhtid - 1].tid_map); 347 348 out: 349 return ret; 350 } 351 352 int cxgb4_delete_knode(struct net_device *dev, struct tc_cls_u32_offload *cls) 353 { 354 struct adapter *adapter = netdev2adap(dev); 355 unsigned int filter_id, max_tids, i, j; 356 struct cxgb4_link *link = NULL; 357 struct cxgb4_tc_u32_table *t; 358 u32 handle, uhtid; 359 int ret; 360 361 if (!can_tc_u32_offload(dev)) 362 return -EOPNOTSUPP; 363 364 /* Fetch the location to delete the filter. */ 365 filter_id = TC_U32_NODE(cls->knode.handle) - 1; 366 if (filter_id >= adapter->tids.nftids || 367 cls->knode.handle != adapter->tids.ftid_tab[filter_id].fs.tc_cookie) 368 return -ERANGE; 369 370 t = adapter->tc_u32; 371 handle = cls->knode.handle; 372 uhtid = TC_U32_USERHTID(cls->knode.handle); 373 374 /* Ensure that uhtid is either root u32 (i.e. 0x800) 375 * or a a valid linked bucket. 376 */ 377 if (uhtid != 0x800 && uhtid >= t->size) 378 return -EINVAL; 379 380 /* Delete the specified filter */ 381 if (uhtid != 0x800) { 382 link = &t->table[uhtid - 1]; 383 if (!link->link_handle) 384 return -EINVAL; 385 386 if (!test_bit(filter_id, link->tid_map)) 387 return -EINVAL; 388 } 389 390 ret = cxgb4_del_filter(dev, filter_id, NULL); 391 if (ret) 392 goto out; 393 394 if (link) 395 clear_bit(filter_id, link->tid_map); 396 397 /* If a link is being deleted, then delete all filters 398 * associated with the link. 399 */ 400 max_tids = adapter->tids.nftids; 401 for (i = 0; i < t->size; i++) { 402 link = &t->table[i]; 403 404 if (link->link_handle == handle) { 405 for (j = 0; j < max_tids; j++) { 406 if (!test_bit(j, link->tid_map)) 407 continue; 408 409 ret = __cxgb4_del_filter(dev, j, NULL, NULL); 410 if (ret) 411 goto out; 412 413 clear_bit(j, link->tid_map); 414 } 415 416 /* Clear the link state */ 417 link->match_field = NULL; 418 link->link_handle = 0; 419 memset(&link->fs, 0, sizeof(link->fs)); 420 break; 421 } 422 } 423 424 out: 425 return ret; 426 } 427 428 void cxgb4_cleanup_tc_u32(struct adapter *adap) 429 { 430 struct cxgb4_tc_u32_table *t; 431 unsigned int i; 432 433 if (!adap->tc_u32) 434 return; 435 436 /* Free up all allocated memory. */ 437 t = adap->tc_u32; 438 for (i = 0; i < t->size; i++) { 439 struct cxgb4_link *link = &t->table[i]; 440 441 kvfree(link->tid_map); 442 } 443 kvfree(adap->tc_u32); 444 } 445 446 struct cxgb4_tc_u32_table *cxgb4_init_tc_u32(struct adapter *adap) 447 { 448 unsigned int max_tids = adap->tids.nftids; 449 struct cxgb4_tc_u32_table *t; 450 unsigned int i; 451 452 if (!max_tids) 453 return NULL; 454 455 t = kvzalloc(struct_size(t, table, max_tids), GFP_KERNEL); 456 if (!t) 457 return NULL; 458 459 t->size = max_tids; 460 461 for (i = 0; i < t->size; i++) { 462 struct cxgb4_link *link = &t->table[i]; 463 unsigned int bmap_size; 464 465 bmap_size = BITS_TO_LONGS(max_tids); 466 link->tid_map = kvcalloc(bmap_size, sizeof(unsigned long), 467 GFP_KERNEL); 468 if (!link->tid_map) 469 goto out_no_mem; 470 bitmap_zero(link->tid_map, max_tids); 471 } 472 473 return t; 474 475 out_no_mem: 476 for (i = 0; i < t->size; i++) { 477 struct cxgb4_link *link = &t->table[i]; 478 479 if (link->tid_map) 480 kvfree(link->tid_map); 481 } 482 483 if (t) 484 kvfree(t); 485 486 return NULL; 487 } 488