ft_check.c (45785B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: ft_group.c 8 * Purpose: The purpose of this file is to set flow tracker group methods. 9 * Requires: 10 */ 11 12 #include <bcm_int/esw/flowtracker/ft_group.h> 13 14 #if defined(BCM_FLOWTRACKER_SUPPORT) 15 16 /* External Common Group software State. */ 17 extern bcmi_ft_group_sw_info_t **bcmi_ft_group_sw_state[BCM_MAX_NUM_UNITS]; 18 19 bcmi_ft_flowchecker_sw_state_t bcmi_ft_flowchecker_state[BCM_MAX_NUM_UNITS]; 20 21 /* 22 * Function: 23 * bcmi_ft_flowchecker_get_free_index 24 * Purpose: 25 * Get gree index of the flowtracker check element. 26 * Description: 27 * At present the checks are numbered equal to group 28 * number but there is a provision to increase it to any 29 * number by adding them to the linked list. 30 * But it may not be required as checks can be shared 31 * among various groups and therefore we may not need 32 * exlicit check for each group. 33 * Parameters: 34 * unit - (IN) BCM device id 35 * 36 * Returns: 37 * iBCM_E_XXX. 38 */ 39 int 40 bcmi_ft_flowchecker_get_free_index(int unit, int *index) 41 { 42 43 int num_flowcheckers = 0; 44 soc_mem_t mem; 45 int i = 0; 46 47 /* assign the memory. */ 48 mem = BSC_KG_GROUP_TABLEm; 49 50 /* Total number of groups in device. */ 51 num_flowcheckers = soc_mem_index_max(unit, mem); 52 53 if (*index != -1) { 54 i = *index; 55 num_flowcheckers = *index; 56 } 57 58 for (; i<=num_flowcheckers; i++) { 59 if (!(SHR_BITGET(BCMI_FT_FLOWCHECKER_BITMAP(unit), i))) { 60 /* Got the free index. use it. */ 61 SHR_BITSET(BCMI_FT_FLOWCHECKER_BITMAP(unit), i); 62 *index = i; 63 return BCM_E_NONE; 64 } 65 } 66 67 return BCM_E_RESOURCE; 68 } 69 70 /* 71 * Function: 72 * bcmi_ft_flowchecker_init 73 * Purpose: 74 * Initialize software state of flowtracker checks. 75 * Parameters: 76 * unit - (IN) BCM device id 77 * 78 * Returns: 79 * BCM_E_XXX. 80 */ 81 82 int bcmi_ft_flowchecker_init(int unit) 83 { 84 85 int num_flowcheckers = 0; 86 soc_mem_t mem; 87 mem = BSC_KG_GROUP_TABLEm; 88 89 /* Total number of groups in device. */ 90 num_flowcheckers = soc_mem_index_count(unit, mem); 91 92 /* Allocate space for the flowchecker database structures. */ 93 BCMI_FT_FLOWCHECKER_STATE(unit) = (bcmi_flowtracker_flowchecker_info_t **) 94 sal_alloc((num_flowcheckers * 95 sizeof(bcmi_flowtracker_flowchecker_info_t *)), 96 "flowtracker group sw state"); 97 98 if (BCMI_FT_FLOWCHECKER_STATE(unit) == NULL) { 99 return BCM_E_MEMORY; 100 } 101 sal_memset(BCMI_FT_FLOWCHECKER_STATE(unit), 0, 102 (num_flowcheckers * sizeof(bcmi_ft_flowchecker_sw_state_t *))); 103 104 /* allocate Group bitmap for whole chip. */ 105 BCMI_FT_FLOWCHECKER_BITMAP(unit) = 106 sal_alloc(SHR_BITALLOCSIZE(num_flowcheckers), 107 "ft_flowchecker_bitmap"); 108 109 if (BCMI_FT_FLOWCHECKER_BITMAP(unit) == NULL) { 110 return BCM_E_MEMORY; 111 } 112 113 sal_memset(BCMI_FT_FLOWCHECKER_BITMAP(unit), 0, 114 SHR_BITALLOCSIZE(num_flowcheckers)); 115 116 /* Allocate memory for refcounting the flowchecker indexes. */ 117 bcmi_ft_flowchecker_state[unit].fc_idx_refcount = (uint32 *) 118 sal_alloc((num_flowcheckers * sizeof(uint32)), 119 "flowchecker refcount state"); 120 121 if (bcmi_ft_flowchecker_state[unit].fc_idx_refcount == NULL) { 122 return BCM_E_MEMORY; 123 } 124 125 sal_memset(bcmi_ft_flowchecker_state[unit].fc_idx_refcount, 0, 126 (num_flowcheckers * sizeof(uint32))); 127 128 /* Reserve the 0th index. */ 129 /* SHR_BITSET(BCMI_FT_FLOWCHECKER_BITMAP(unit), 0);*/ 130 131 return BCM_E_NONE; 132 } 133 134 /* 135 * Function: 136 * bcmi_ft_flowchecker_cleanup 137 * Purpose: 138 * Cleanup software state of flowtracker checks. 139 * Parameters: 140 * unit - (IN) BCM device id 141 * 142 * Returns: 143 * None. 144 */ 145 146 void 147 bcmi_ft_flowchecker_cleanup(int unit) 148 { 149 150 if (bcmi_ft_flowchecker_state[unit].fc_idx_refcount != NULL) { 151 sal_free(bcmi_ft_flowchecker_state[unit].fc_idx_refcount); 152 bcmi_ft_flowchecker_state[unit].fc_idx_refcount = NULL; 153 } 154 155 if (BCMI_FT_FLOWCHECKER_BITMAP(unit) != NULL) { 156 sal_free(BCMI_FT_FLOWCHECKER_BITMAP(unit)); 157 BCMI_FT_FLOWCHECKER_BITMAP(unit) = NULL; 158 } 159 160 if (BCMI_FT_FLOWCHECKER_STATE(unit) != NULL) { 161 sal_free(BCMI_FT_FLOWCHECKER_STATE(unit)); 162 BCMI_FT_FLOWCHECKER_STATE(unit) = NULL; 163 } 164 165 } 166 167 /* 168 * Function: 169 * bcmi_ft_flowchecker_is_invalid 170 * Purpose: 171 * Chekc if the flowtracker check index is valid 172 * Parameters: 173 * unit - (IN) BCM device id 174 * flowchecker_id - (IN) flowchecker index. 175 * Returns: 176 * BCM_E_XXX. 177 */ 178 int 179 bcmi_ft_flowchecker_is_invalid(int unit, int flowchecker_id) 180 { 181 182 int num_flowcheckers = 0; 183 184 /* Total number of groups/flowcheckers in device. */ 185 num_flowcheckers = soc_mem_index_max(unit, BSC_KG_GROUP_TABLEm); 186 187 if (flowchecker_id > num_flowcheckers) { 188 return BCM_E_PARAM; 189 } 190 191 if (BCMI_FT_FLOWCHECKER_BITMAP(unit) == NULL) { 192 return BCM_E_INIT; 193 } 194 195 if (!(SHR_BITGET(BCMI_FT_FLOWCHECKER_BITMAP(unit), flowchecker_id))) { 196 return BCM_E_NOT_FOUND; 197 } 198 199 if (BCMI_FT_FLOWCHECKER_INFO(unit, flowchecker_id) == NULL) { 200 return BCM_E_NOT_FOUND; 201 } 202 203 return BCM_E_NONE; 204 } 205 206 int 207 bcmi_ft_check_param_sanity( 208 int unit, 209 bcm_flowtracker_check_info_t flow_check_info) 210 { 211 uint32 max_value = 0, min_value = 0; 212 const char *plist_str[] = BCM_FT_TRACKING_PARAM_STRINGS; 213 214 switch(flow_check_info.param) { 215 /* Tracking Params which are not mapped to qualifier. */ 216 case bcmFlowtrackerTrackingParamTypeNone: 217 case bcmFlowtrackerTrackingParamTypePktCount: 218 case bcmFlowtrackerTrackingParamTypeByteCount: 219 case bcmFlowtrackerTrackingParamTypeTimestampNewLearn: 220 case bcmFlowtrackerTrackingParamTypeTimestampFlowStart: 221 case bcmFlowtrackerTrackingParamTypeTimestampFlowEnd: 222 case bcmFlowtrackerTrackingParamTypeTimestampCheckEvent1: 223 case bcmFlowtrackerTrackingParamTypeTimestampCheckEvent2: 224 case bcmFlowtrackerTrackingParamTypeCount: 225 return BCM_E_PARAM; 226 227 /* Tracking params too big for flow check. */ 228 case bcmFlowtrackerTrackingParamTypeSrcIPv6: 229 case bcmFlowtrackerTrackingParamTypeDstIPv6: 230 case bcmFlowtrackerTrackingParamTypeInnerSrcIPv6: 231 case bcmFlowtrackerTrackingParamTypeInnerDstIPv6: 232 return BCM_E_PARAM; 233 234 case bcmFlowtrackerTrackingParamTypeDosAttack: 235 case bcmFlowtrackerTrackingParamTypeInnerDosAttack: 236 if (!soc_feature(unit, 237 soc_feature_flowtracker_ver_1_dos_attack_check)) { 238 239 LOG_INFO(BSL_LS_BCM_FLOWTRACKER, 240 (BSL_META_U(unit, "Tracking Param(%s) is not supported in" 241 " flowcheck.\n"), 242 plist_str[flow_check_info.param])); 243 return BCM_E_UNAVAIL; 244 } 245 break; 246 247 default: 248 /* Other tracking params are valid for Flowcheck */ 249 break; 250 } 251 252 /* Tracking params which are mapped to qualifier. */ 253 BCM_IF_ERROR_RETURN(_bcm_field_ft_tracking_param_range_get(unit, 254 flow_check_info.param, &min_value, &max_value)); 255 256 if (flow_check_info.min_value < min_value) { 257 return BCM_E_PARAM; 258 } 259 260 if (flow_check_info.max_value > max_value) { 261 return BCM_E_PARAM; 262 } 263 264 if ((flow_check_info.min_value != 0) && 265 (flow_check_info.max_value != 0)) { 266 267 if (flow_check_info.min_value > flow_check_info.max_value) { 268 return BCM_E_PARAM; 269 } 270 } 271 272 if (!flow_check_info.operation) { 273 /* No operation is sent. return config error. */ 274 return BCM_E_CONFIG; 275 } 276 277 278 return BCM_E_NONE; 279 } 280 281 /* 282 * Function: 283 * bcmi_ft_check_create 284 * Purpose: 285 * Create flowtracker index from information 286 * provided by user. 287 * Parameters: 288 * unit - (IN) BCM device id 289 * options - (IN) options to create flowtracker check. 290 * flow_check_info - (IN) information to create flowtracker check. 291 * flowchecker_id - (OUT) Placeholder for index generated. 292 * 293 * Returns: 294 * BCM_E_XXX. 295 */ 296 int 297 bcmi_ft_check_create( 298 int unit, uint32 options, 299 bcm_flowtracker_check_info_t flow_check_info, 300 bcm_flowtracker_check_t *flowchecker_id) 301 { 302 303 int index = -1; 304 bcmi_flowtracker_flowchecker_info_t fc_info; 305 306 /* Check if input params are correct. */ 307 if (flowchecker_id == NULL) { 308 return BCM_E_PARAM; 309 } 310 311 BCM_IF_ERROR_RETURN(bcmi_ft_check_param_sanity(unit, flow_check_info)); 312 313 if ((options & BCM_FLOWTRACKER_CHECK_SECOND) && 314 (options & BCM_FLOWTRACKER_CHECK_WITH_ID)) { 315 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 316 "Secondary check is not allowed with BCM_FLOWTRACKER_CHECK_WITH_ID. \n"))); 317 return BCM_E_CONFIG; 318 } 319 320 if (options & BCM_FLOWTRACKER_CHECK_WITH_ID) { 321 322 if (!BCMI_FT_IDX_IS_CHECK(*flowchecker_id)) { 323 return BCM_E_PARAM; 324 } 325 326 /* get the index from bitmap. */ 327 index = BCMI_FT_FLOWCHECKER_INDEX_GET(*flowchecker_id); 328 329 if (!(bcmi_ft_flowchecker_is_invalid(unit, index))) { 330 return BCM_E_PARAM; 331 } 332 } 333 334 if (options & BCM_FLOWTRACKER_CHECK_SECOND) { 335 if (!BCMI_FT_IDX_IS_CHECK(flow_check_info.primary_check_id)) { 336 return BCM_E_PARAM; 337 } 338 339 sal_memset(&fc_info, 0, sizeof(bcmi_flowtracker_flowchecker_info_t)); 340 341 BCM_IF_ERROR_RETURN(bcmi_ft_flowchecker_get 342 (unit, flow_check_info.primary_check_id, &fc_info)); 343 344 if (bcmi_ft_flowchecker_opr_is_dual(unit, fc_info.check1.operation)) { 345 /* Dual operations used in first check.*/ 346 return BCM_E_CONFIG; 347 } 348 349 if ((flow_check_info.flags & 350 BCM_FLOWTRACKER_CHECK_DATA_CLEAR_ON_EXPORT) || (flow_check_info.flags & 351 BCM_FLOWTRACKER_CHECK_EXPORT_MODE_THRESHOLD)) { 352 353 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 354 "Export configuration now not allowed on Secondary Check.\n"))); 355 return BCM_E_CONFIG; 356 } 357 358 if (fc_info.check2.operation) { 359 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 360 "Secondary Check already exists for this primary. \n"))); 361 return BCM_E_EXISTS; 362 } 363 364 if (soc_feature(unit, soc_feature_hx5_ft_32bit_param_update)) { 365 /* Not allowed to create a second check if dos attack is updated.*/ 366 if (((fc_info.check1.param == 367 bcmFlowtrackerTrackingParamTypeDosAttack) || 368 (fc_info.check1.param == 369 bcmFlowtrackerTrackingParamTypeInnerDosAttack)) && 370 (fc_info.action_info.action == 371 bcmFlowtrackerCheckActionUpdateValue)) { 372 373 return BCM_E_CONFIG; 374 } 375 } 376 377 index = BCMI_FT_FLOWCHECKER_INDEX_GET(flow_check_info.primary_check_id); 378 379 if ((bcmi_ft_flowchecker_is_invalid(unit, index))) { 380 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 381 "The primary check is not created or invalid.\n"))); 382 383 return BCM_E_PARAM; 384 } 385 386 /* If Primary is associated with any FT Group, we should not allow 387 * added second to it. */ 388 if (BCMI_FT_FLOWCHECKER_REFCOUNT(unit, index)) { 389 return BCM_E_CONFIG; 390 } 391 392 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.param = 393 flow_check_info.param; 394 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.min_value = 395 flow_check_info.min_value; 396 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.max_value = 397 flow_check_info.max_value; 398 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.operation = 399 flow_check_info.operation; 400 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.flags = 401 flow_check_info.flags; 402 BCMI_FT_FLOWCHECKER_INFO(unit, index)->flags |= 403 flow_check_info.flags; 404 405 /* Set flowchecker type in the index. */ 406 *flowchecker_id = 407 BCMI_FT_FLOWCHECKER_INDEX_SET(index, BCM_FT_IDX_TYPE_2ND_CHECK); 408 409 return BCM_E_NONE; 410 } 411 412 BCM_IF_ERROR_RETURN(bcmi_ft_flowchecker_get_free_index(unit, &index)); 413 414 /* Allocate memory for the new flowchecker. */ 415 BCMI_FT_FLOWCHECKER_INFO(unit, index) = 416 (bcmi_flowtracker_flowchecker_info_t *) 417 sal_alloc(sizeof(bcmi_flowtracker_flowchecker_info_t), 418 "flowtracker info"); 419 420 if (BCMI_FT_FLOWCHECKER_INFO(unit, index) == NULL) { 421 return BCM_E_MEMORY; 422 } 423 424 /* Rather than doing memcpy, we should actually set each element. */ 425 sal_memset(BCMI_FT_FLOWCHECKER_INFO(unit, index), 0, 426 sizeof(bcmi_flowtracker_flowchecker_info_t)); 427 428 429 /* We can also do memset here as the data is same. 430 bcmi_ft_flowchecker_info_set(unit, BCMI_FT_FLOWCHECKER_INFO(unit, index), 431 flow_check_info); 432 */ 433 434 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.param = 435 flow_check_info.param; 436 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.min_value = 437 flow_check_info.min_value; 438 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.max_value = 439 flow_check_info.max_value; 440 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.operation = 441 flow_check_info.operation; 442 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.flags = 443 flow_check_info.flags; 444 BCMI_FT_FLOWCHECKER_INFO(unit, index)->flags |= 445 flow_check_info.flags; 446 447 /* Set flowchecker type in the index. */ 448 *flowchecker_id = 449 BCMI_FT_FLOWCHECKER_INDEX_SET(index, BCM_FT_IDX_TYPE_CHECK); 450 451 return BCM_E_NONE; 452 } 453 454 /* 455 * Function: 456 * bcmi_ft_check_get 457 * Purpose: 458 * Get flowtracker information from the index 459 * provided by user. This is user interfacing method 460 * which will only send particular info which user API exposes. 461 * Parameters: 462 * unit - (IN) BCM device id 463 * flowchecker_id - (IN) flowtracker check index. 464 * flow_check_info - (OUT) information to create flowtracker check. 465 * 466 * Returns: 467 * BCM_E_XXX. 468 */ 469 int bcmi_ft_check_get( 470 int unit, 471 bcm_flowtracker_check_t flowchecker_id, 472 bcm_flowtracker_check_info_t *flow_check_info) 473 { 474 475 int index; 476 477 /* Check if input params are correct. */ 478 if (!flow_check_info) { 479 return BCM_E_PARAM; 480 } 481 482 if (!BCMI_FT_IDX_IS_CHECK(flowchecker_id)) { 483 return BCM_E_PARAM; 484 } 485 486 /* get the index from bitmap. */ 487 index = BCMI_FT_FLOWCHECKER_INDEX_GET(flowchecker_id); 488 489 if (bcmi_ft_flowchecker_is_invalid(unit, index)) { 490 return BCM_E_PARAM; 491 } 492 493 sal_memset(flow_check_info, 0, sizeof(bcm_flowtracker_check_info_t)); 494 495 if (BCMI_FT_IDX_IS_2ND_CHECK(flowchecker_id)) { 496 flow_check_info->param = 497 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.param; 498 flow_check_info->min_value = 499 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.min_value; 500 flow_check_info->max_value = 501 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.max_value; 502 flow_check_info->operation = 503 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.operation; 504 flow_check_info->flags = 505 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.flags; 506 507 if (BCMI_FT_FLOWCHECKER_INFO(unit, index)->flags & 508 BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT2) { 509 flow_check_info->flags |= 510 BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT2; 511 } 512 flow_check_info->primary_check_id = 513 BCMI_FT_FLOWCHECKER_INDEX_SET(index, BCM_FT_IDX_TYPE_CHECK); 514 515 } else { 516 517 flow_check_info->param = 518 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.param; 519 flow_check_info->min_value = 520 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.min_value; 521 flow_check_info->max_value = 522 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.max_value; 523 flow_check_info->operation = 524 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.operation; 525 flow_check_info->flags = 526 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.flags; 527 528 if (BCMI_FT_FLOWCHECKER_INFO(unit, index)->flags & 529 BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT1) { 530 flow_check_info->flags |= 531 BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT1; 532 } 533 534 } 535 536 return BCM_E_NONE; 537 } 538 539 /* 540 * Function: 541 * bcmi_ft_check_traverse 542 * Purpose: 543 * Traverse througth all the flowtracker check objects. 544 * Parameters: 545 * unit - (IN) BCM device id 546 * cb - (IN) Callback 547 * user_data - (INOUT) User data which is sent back. 548 * 549 * Returns: 550 * BCM_E_XXX. 551 */ 552 int 553 bcmi_ft_check_traverse( 554 int unit, 555 bcm_flowtracker_check_traverse_cb cb, 556 void *user_data) 557 { 558 bcm_flowtracker_check_t flowchecker_id; 559 bcm_flowtracker_check_info_t flow_check_info; 560 int index = 0; 561 int num_flowcheckers = 0; 562 soc_mem_t mem; 563 mem = BSC_KG_GROUP_TABLEm; 564 565 /* Total number of groups in device. */ 566 num_flowcheckers = soc_mem_index_count(unit, mem); 567 568 if (cb == NULL) { 569 return BCM_E_PARAM; 570 } 571 572 for(; index<num_flowcheckers; index++) { 573 574 if (bcmi_ft_flowchecker_is_invalid(unit, index)) { 575 continue; 576 } 577 sal_memset(&flow_check_info, 0, sizeof(bcm_flowtracker_check_info_t)); 578 579 flowchecker_id = 580 BCMI_FT_FLOWCHECKER_INDEX_SET(index, BCM_FT_IDX_TYPE_CHECK); 581 582 flow_check_info.param = 583 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.param; 584 flow_check_info.min_value = 585 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.min_value; 586 flow_check_info.max_value = 587 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.max_value; 588 flow_check_info.operation = 589 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.operation; 590 flow_check_info.flags = 591 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.flags; 592 593 /* Invoke call back routine. */ 594 (*cb)(unit, flowchecker_id, &flow_check_info, user_data); 595 596 /* Now send second check information. */ 597 if (!BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.param) { 598 continue; 599 } 600 601 sal_memset(&flow_check_info, 0, sizeof(bcm_flowtracker_check_info_t)); 602 603 flowchecker_id = 604 BCMI_FT_FLOWCHECKER_INDEX_SET(index, BCM_FT_IDX_TYPE_2ND_CHECK); 605 606 flow_check_info.param = 607 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.param; 608 flow_check_info.min_value = 609 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.min_value; 610 flow_check_info.max_value = 611 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.max_value; 612 flow_check_info.operation = 613 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.operation; 614 flow_check_info.flags = 615 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.flags; 616 617 flow_check_info.primary_check_id = 618 BCMI_FT_FLOWCHECKER_INDEX_SET(index, BCM_FT_IDX_TYPE_CHECK); 619 620 /* Invoke call back routine. */ 621 (*cb)(unit, flowchecker_id, &flow_check_info, user_data); 622 } 623 624 return BCM_E_NONE; 625 } 626 627 /* 628 * Function: 629 * bcmi_ft_check_get 630 * Purpose: 631 * Get flowtracker information from the index 632 * provided by user. This is internal function 633 * which provides all the internal data. 634 * Parameters: 635 * unit - (IN) BCM device id 636 * flowchecker_id - (IN) flowtracker check index. 637 * flow_check_info - (OUT) information to create flowtracker check. 638 * 639 * Returns: 640 * BCM_E_XXX. 641 */ 642 int 643 bcmi_ft_flowchecker_get( 644 int unit, 645 bcm_flowtracker_check_t flowchecker_id, 646 bcmi_flowtracker_flowchecker_info_t *flow_check_info) 647 { 648 649 int index; 650 651 /* Check if input params are correct. */ 652 if (!flow_check_info) { 653 return BCM_E_PARAM; 654 } 655 if (!BCMI_FT_IDX_IS_CHECK(flowchecker_id)) { 656 return BCM_E_PARAM; 657 } 658 659 /* get the index from bitmap. */ 660 index = BCMI_FT_FLOWCHECKER_INDEX_GET(flowchecker_id); 661 662 if (bcmi_ft_flowchecker_is_invalid(unit, index)) { 663 return BCM_E_PARAM; 664 } 665 666 /* Get the flags. */ 667 flow_check_info->flags = 668 BCMI_FT_FLOWCHECKER_INFO(unit, index)->flags; 669 670 /* Data of first check. */ 671 flow_check_info->check1.param = 672 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.param; 673 flow_check_info->check1.min_value = 674 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.min_value; 675 flow_check_info->check1.max_value = 676 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.max_value; 677 flow_check_info->check1.operation = 678 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.operation; 679 flow_check_info->check1.flags = 680 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.flags; 681 682 /* Data of second check. */ 683 flow_check_info->check2.param = 684 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.param; 685 flow_check_info->check2.min_value = 686 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.min_value; 687 flow_check_info->check2.max_value = 688 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.max_value; 689 flow_check_info->check2.operation = 690 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.operation; 691 flow_check_info->check2.flags = 692 BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.flags; 693 694 flow_check_info->action_info.param = 695 BCMI_FT_FLOWCHECKER_INFO(unit, index)->action_info.param; 696 flow_check_info->action_info.action = 697 BCMI_FT_FLOWCHECKER_INFO(unit, index)->action_info.action; 698 699 700 flow_check_info->export_info.export_check_threshold = 701 BCMI_FT_FLOWCHECKER_INFO(unit, index)-> 702 export_info.export_check_threshold; 703 704 flow_check_info->export_info.operation = 705 BCMI_FT_FLOWCHECKER_INFO(unit, index)->export_info.operation; 706 707 return BCM_E_NONE; 708 } 709 710 /* 711 * Function: 712 * bcmi_ft_check_destroy 713 * Purpose: 714 * Destroy flowtracker from the index 715 * provided by user. 716 * Parameters: 717 * unit - (IN) BCM device id 718 * flowchecker_id - (IN) Placeholder for index generated. 719 * 720 * Returns: 721 * BCM_E_XXX. 722 */ 723 int 724 bcmi_ft_check_destroy( 725 int unit, 726 bcm_flowtracker_check_t flowchecker_id) 727 { 728 729 int index; 730 731 if (!BCMI_FT_IDX_IS_CHECK(flowchecker_id)) { 732 return BCM_E_PARAM; 733 } 734 735 /* get the index from bitmap. */ 736 index = BCMI_FT_FLOWCHECKER_INDEX_GET(flowchecker_id); 737 738 BCM_IF_ERROR_RETURN(bcmi_ft_flowchecker_is_invalid(unit, index)); 739 740 if (BCMI_FT_FLOWCHECKER_REFCOUNT(unit, index)) { 741 /* For removing checks, they should be removed from FT groups. */ 742 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 743 "The check is still attached to FT groups.\n"))); 744 return BCM_E_BUSY; 745 } 746 747 if (BCMI_FT_IDX_IS_2ND_CHECK(flowchecker_id)) { 748 /* Check if second check is configured. */ 749 if (!BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.operation) { 750 return BCM_E_NOT_FOUND; 751 } 752 753 sal_memset((void *) (&(BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2)), 754 0, sizeof(bcm_flowtracker_check_info_t)); 755 756 /* Second flowchecker is deleted. return. */ 757 return BCM_E_NONE; 758 } else { 759 /* Check if second check is configured. */ 760 if (BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.operation) { 761 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 762 "Second Check is associated\n"))); 763 return BCM_E_BUSY; 764 } 765 } 766 767 /* Free the flowchecker sw state. */ 768 sal_free(BCMI_FT_FLOWCHECKER_INFO(unit, index)); 769 770 /* Clear the bit for flowchecker. */ 771 SHR_BITCLR(BCMI_FT_FLOWCHECKER_BITMAP(unit), index); 772 773 return BCM_E_NONE; 774 } 775 776 /* 777 * Function: 778 * bcmi_ft_check_destroy_all 779 * Purpose: 780 * Destroy all flowtrackers from the index 781 * provided by user which are not linked to any group. 782 * Parameters: 783 * unit - (IN) BCM device id 784 * 785 * Returns: 786 * BCM_E_XXX. 787 */ 788 int 789 bcmi_ft_check_destroy_all(int unit) 790 { 791 int index = 0; 792 int num_flowcheckers = 0; 793 soc_mem_t mem; 794 mem = BSC_KG_GROUP_TABLEm; 795 796 /* Total number of groups in device. */ 797 num_flowcheckers = soc_mem_index_count(unit, mem); 798 799 for(index = 0; index < num_flowcheckers; index++) { 800 801 /* 802 * If we are not able to destroy then either it does not exists 803 * or may be it is linked to group. both cases, we just bypass. 804 */ 805 806 (void) bcmi_ft_check_destroy(unit, BCMI_FT_FLOWCHECKER_INDEX_SET( \ 807 index, BCM_FT_IDX_TYPE_2ND_CHECK)); 808 (void) bcmi_ft_check_destroy(unit, BCMI_FT_FLOWCHECKER_INDEX_SET( \ 809 index, BCM_FT_IDX_TYPE_CHECK)); 810 } 811 812 return BCM_E_NONE; 813 } 814 815 /* 816 * Function: 817 * bcmi_ft_check_action_info_set 818 * Purpose: 819 * Set action informaiton on the flowtracker check 820 * Parameters: 821 * unit - (IN) BCM device id 822 * flowchecker_id - (IN) flowtracker check index. 823 * info - (IN) action information. 824 * 825 * Returns: 826 * BCM_E_XXX. 827 */ 828 int 829 bcmi_ft_check_action_info_set( 830 int unit, 831 bcm_flowtracker_check_t check_id, 832 bcm_flowtracker_check_action_info_t info) 833 { 834 int index = 0; 835 836 if (!BCMI_FT_IDX_IS_CHECK(check_id)) { 837 return BCM_E_PARAM; 838 } 839 840 if (BCMI_FT_IDX_IS_2ND_CHECK(check_id)) { 841 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 842 "Actions can only be set on primary check.\n"))); 843 844 return BCM_E_PARAM; 845 } 846 847 848 /* get the index from bitmap. */ 849 index = BCMI_FT_FLOWCHECKER_INDEX_GET(check_id); 850 851 if (bcmi_ft_flowchecker_is_invalid(unit, index)) { 852 return BCM_E_PARAM; 853 } 854 855 /* 856 * If the check is created on Dos Attacks and it is 857 * dual operation on check 1 then raise error. 858 */ 859 if (soc_feature(unit, soc_feature_hx5_ft_32bit_param_update)) { 860 861 if ((info.action == bcmFlowtrackerCheckActionUpdateValue) && 862 ((BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.param == 863 bcmFlowtrackerTrackingParamTypeDosAttack) || 864 (BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.param == 865 bcmFlowtrackerTrackingParamTypeInnerDosAttack))) { 866 867 if (bcmi_ft_flowchecker_opr_is_dual(unit, 868 (BCMI_FT_FLOWCHECKER_INFO(unit, index)->check1.operation))) { 869 return BCM_E_CONFIG; 870 } 871 /* Not allowed to create second check if dos vector is updated. */ 872 if (BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.param) { 873 return BCM_E_CONFIG; 874 } 875 } 876 } 877 878 BCMI_FT_FLOWCHECKER_INFO(unit, index)->action_info.param = info.param; 879 BCMI_FT_FLOWCHECKER_INFO(unit, index)->action_info.action = info.action; 880 881 return BCM_E_NONE; 882 } 883 884 /* 885 * Function: 886 * bcmi_ft_check_action_info_get 887 * Purpose: 888 * Get action informaiton from the flowtracker check 889 * Parameters: 890 * unit - (IN) BCM device id 891 * flowchecker_id - (IN) flowtracker check index. 892 * info - (OUT) action information. 893 * 894 * Returns: 895 * BCM_E_XXX. 896 */ 897 int 898 bcmi_ft_check_action_info_get( 899 int unit, 900 bcm_flowtracker_check_t check_id, 901 bcm_flowtracker_check_action_info_t *info) 902 { 903 int index = 0; 904 905 if (!BCMI_FT_IDX_IS_CHECK(check_id)) { 906 return BCM_E_PARAM; 907 } 908 909 if (BCMI_FT_IDX_IS_2ND_CHECK(check_id)) { 910 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 911 "Actions can only be retrieved on primary check.\n"))); 912 913 return BCM_E_PARAM; 914 } 915 916 /* get the index from bitmap. */ 917 index = BCMI_FT_FLOWCHECKER_INDEX_GET(check_id); 918 919 if (bcmi_ft_flowchecker_is_invalid(unit, index)) { 920 return BCM_E_PARAM; 921 } 922 923 info->param = BCMI_FT_FLOWCHECKER_INFO(unit, index)->action_info.param; 924 info->action = BCMI_FT_FLOWCHECKER_INFO(unit, index)->action_info.action; 925 926 return BCM_E_NONE; 927 } 928 929 /* 930 * Function: 931 * bcmi_ft_check_export_info_set 932 * Purpose: 933 * set export informaiton from the flowtracker check 934 * Parameters: 935 * unit - (IN) BCM device id 936 * flowchecker_id - (IN) flowtracker check index. 937 * info - (IN) export information. 938 * 939 * Returns: 940 * BCM_E_XXX. 941 */ 942 int 943 bcmi_ft_check_export_info_set( 944 int unit, 945 bcm_flowtracker_check_t check_id, 946 bcm_flowtracker_check_export_info_t info) 947 { 948 int index = 0; 949 950 if (!BCMI_FT_IDX_IS_CHECK(check_id)) { 951 return BCM_E_PARAM; 952 } 953 954 if (BCMI_FT_IDX_IS_2ND_CHECK(check_id)) { 955 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 956 "Export info can only be set on primary check.\n"))); 957 958 return BCM_E_PARAM; 959 } 960 961 /* get the index from bitmap. */ 962 index = BCMI_FT_FLOWCHECKER_INDEX_GET(check_id); 963 964 if (bcmi_ft_flowchecker_is_invalid(unit, index)) { 965 return BCM_E_PARAM; 966 } 967 968 if (bcmi_ft_flowchecker_opr_is_dual(unit, info.operation)) { 969 /* No dual operations are supported for export threshold.*/ 970 return BCM_E_PARAM; 971 } 972 973 if (info.export_check_threshold && 974 (info.operation != bcmFlowtrackerCheckOpGreaterEqual)) { 975 976 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 977 "Export threshold is only supported with GreaterEqual operation.\n"))); 978 979 return BCM_E_CONFIG; 980 } 981 982 983 BCMI_FT_FLOWCHECKER_INFO(unit, index)->export_info.export_check_threshold = 984 info.export_check_threshold; 985 BCMI_FT_FLOWCHECKER_INFO(unit, index)->export_info.operation = 986 info.operation; 987 988 return BCM_E_NONE; 989 } 990 991 /* 992 * Function: 993 * bcmi_ft_check_export_info_get 994 * Purpose: 995 * Get export informaiton from the flowtracker check 996 * Parameters: 997 * unit - (IN) BCM device id 998 * flowchecker_id - (IN) flowtracker check index. 999 * info - (OUT) export information. 1000 * 1001 * Returns: 1002 * BCM_E_XXX. 1003 */ 1004 int 1005 bcmi_ft_check_export_info_get( 1006 int unit, 1007 bcm_flowtracker_check_t check_id, 1008 bcm_flowtracker_check_export_info_t *info) 1009 { 1010 int index = 0; 1011 1012 if (!BCMI_FT_IDX_IS_CHECK(check_id)) { 1013 return BCM_E_PARAM; 1014 } 1015 1016 if (BCMI_FT_IDX_IS_2ND_CHECK(check_id)) { 1017 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 1018 "Export info can only be retrieved from primary check.\n"))); 1019 1020 return BCM_E_PARAM; 1021 } 1022 1023 /* get the index from bitmap. */ 1024 index = BCMI_FT_FLOWCHECKER_INDEX_GET(check_id); 1025 1026 if (bcmi_ft_flowchecker_is_invalid(unit, index)) { 1027 return BCM_E_PARAM; 1028 } 1029 1030 info->export_check_threshold = 1031 BCMI_FT_FLOWCHECKER_INFO(unit, index)-> 1032 export_info.export_check_threshold; 1033 1034 info->operation = 1035 BCMI_FT_FLOWCHECKER_INFO(unit, index)->export_info.operation; 1036 1037 return BCM_E_NONE; 1038 } 1039 1040 /* 1041 * Function: 1042 * bcmi_ft_flowchecker_list_length_get 1043 * Purpose: 1044 * Add this flowtracker into the group. 1045 * Parameters: 1046 * unit - (IN) BCM device id 1047 * head - (INOUT) Head pointer of the list. 1048 * 1049 * Returns: 1050 * BCM_E_XXX. 1051 */ 1052 int 1053 bcmi_ft_flowchecker_list_length_get( 1054 int unit, 1055 bcmi_ft_flowchecker_list_t **head) 1056 { 1057 1058 int length = 0; 1059 bcmi_ft_flowchecker_list_t *temp = NULL; 1060 1061 if (!head) { 1062 return 0; 1063 } 1064 1065 temp = (*head); 1066 1067 while(temp) { 1068 length++; 1069 temp = temp->next; 1070 } 1071 1072 return length; 1073 } 1074 /* 1075 * Function: 1076 * bcmi_ft_flowchecker_list_add 1077 * Purpose: 1078 * Add this flowtracker into the group. 1079 * Parameters: 1080 * unit - (IN) BCM device id 1081 * head - (INOUT) Head pointer of the list. 1082 * flowchecker_id - (IN) flowtracker check index. 1083 * 1084 * Returns: 1085 * BCM_E_XXX. 1086 */ 1087 int 1088 bcmi_ft_flowchecker_list_add( 1089 int unit, 1090 bcmi_ft_flowchecker_list_t **head, 1091 bcm_flowtracker_check_t flowchecker_id) 1092 { 1093 bcmi_ft_flowchecker_list_t *temp_node = NULL; 1094 bcmi_ft_flowchecker_list_t *node_iter = NULL; 1095 bcmi_ft_flowchecker_list_t *node_prev = NULL; 1096 1097 /* Create node */ 1098 temp_node = (bcmi_ft_flowchecker_list_t *) 1099 sal_alloc(sizeof(bcmi_ft_flowchecker_list_t), 1100 "flowchecker list Node"); 1101 if (temp_node == NULL) { 1102 return BCM_E_MEMORY; 1103 } 1104 temp_node->flowchecker_id = flowchecker_id; 1105 temp_node->next = NULL; 1106 1107 node_prev = NULL; 1108 node_iter = (*head); 1109 while (node_iter != NULL) { 1110 if (node_iter->flowchecker_id == flowchecker_id) { 1111 sal_free(temp_node); 1112 return BCM_E_NONE; 1113 } 1114 node_prev = node_iter; 1115 node_iter = node_iter->next; 1116 } 1117 1118 /* Insert */ 1119 if (node_prev != NULL) { 1120 temp_node->next = node_prev->next; 1121 node_prev->next = temp_node; 1122 } else { 1123 temp_node->next = (*head); 1124 (*head) = temp_node; 1125 } 1126 1127 return BCM_E_NONE; 1128 } 1129 1130 /* 1131 * Function: 1132 * bcmi_ft_flowchecker_list_delete 1133 * Purpose: 1134 * Delete this flowtracker check from group list. 1135 * Parameters: 1136 * unit - (IN) BCM device id 1137 * head - (INOUT) Head pointer of the list. 1138 * flowchecker_id - (IN) flowtracker check index. 1139 * 1140 * Returns: 1141 * BCM_E_XXX. 1142 */ 1143 int 1144 bcmi_ft_flowchecker_list_delete( 1145 int unit, 1146 bcmi_ft_flowchecker_list_t **head, 1147 bcm_flowtracker_check_t flowchecker_id) 1148 { 1149 1150 bcmi_ft_flowchecker_list_t *temp, *prev; 1151 #if 0 1152 int index = 0; 1153 1154 if (!BCMI_FT_IDX_IS_CHECK(flowchecker_id)) { 1155 return BCM_E_NONE; 1156 } 1157 1158 /* get the index from bitmap. */ 1159 index = BCMI_FT_FLOWCHECKER_INDEX_GET(flowchecker_id); 1160 1161 if (bcmi_ft_flowchecker_is_invalid(unit, index)) { 1162 return BCM_E_NONE; 1163 } 1164 #endif 1165 if (!head || (!(*head))) { 1166 return BCM_E_NOT_FOUND; 1167 } 1168 1169 prev = temp = (*head); 1170 1171 while(temp) { 1172 if (temp->flowchecker_id == flowchecker_id) { 1173 if (temp == (*head)) { 1174 (*head) = temp->next; 1175 } else { 1176 prev->next = temp->next; 1177 } 1178 sal_free(temp); 1179 temp = NULL; 1180 return BCM_E_NONE; 1181 } 1182 prev = temp; 1183 temp = temp->next; 1184 } 1185 1186 return BCM_E_NOT_FOUND; 1187 } 1188 1189 /* 1190 * Function: 1191 * bcmi_ft_check_parts_get 1192 * Purpose: 1193 * Get check parts for given primary check. 1194 * Parameters: 1195 * unit - (IN) BCM device id 1196 * flowchecker_id - (IN) flowtracker check index. 1197 * check_ids - (OUT) Pointer to check Ids 1198 * num_parts - (OUT) Number of parts 1199 * 1200 * Returns: 1201 * BCM_E_XXX. 1202 */ 1203 1204 int 1205 bcmi_ft_check_parts_get( 1206 int unit, 1207 bcm_flowtracker_check_t flowchecker_id, 1208 bcm_flowtracker_check_t *check_ids, 1209 int *num_parts) 1210 { 1211 int part = 0; 1212 int index = 0; 1213 bcmi_flowtracker_flowchecker_info_t fc_info; 1214 sal_memset(&fc_info, 0, sizeof(bcmi_flowtracker_flowchecker_info_t)); 1215 1216 BCM_IF_ERROR_RETURN(bcmi_ft_flowchecker_get 1217 (unit, flowchecker_id, &fc_info)); 1218 1219 /* Adding Primary */ 1220 check_ids[part++] = flowchecker_id; 1221 1222 /* get the index from bitmap. */ 1223 index = BCMI_FT_FLOWCHECKER_INDEX_GET(flowchecker_id); 1224 1225 /* Adding Secondary */ 1226 if (BCMI_FT_FLOWCHECKER_INFO(unit, index)->check2.operation) { 1227 check_ids[part++] = 1228 BCMI_FT_FLOWCHECKER_INDEX_SET(index, BCM_FT_IDX_TYPE_2ND_CHECK); 1229 } 1230 1231 *num_parts = part; 1232 1233 return BCM_E_NONE; 1234 } 1235 1236 /* 1237 * Function: 1238 * bcmi_ft_group_flowchecker_add 1239 * Purpose: 1240 * Add this flowtracker check into group. 1241 * Parameters: 1242 * unit - (IN) BCM device id 1243 * id - (IN) flowtracker group index. 1244 * flowchecker_id - (IN) flowtracker check index. 1245 * 1246 * Returns: 1247 * BCM_E_XXX. 1248 */ 1249 1250 int 1251 bcmi_ft_group_flowchecker_add( 1252 int unit, 1253 bcm_flowtracker_group_t id, 1254 bcm_flowtracker_check_t flowchecker_id) 1255 { 1256 int part = 0; 1257 int index; 1258 int rv = BCM_E_NONE; 1259 int num_parts = 0; 1260 bcm_flowtracker_check_t check_ids[2]; 1261 bcmi_ft_flowchecker_list_t **head = NULL; 1262 1263 /* validate flow group index. */ 1264 if (bcmi_ft_group_is_invalid(unit, id)) { 1265 return (BCM_E_PARAM); 1266 } 1267 1268 if (!BCMI_FT_IDX_IS_CHECK(flowchecker_id)) { 1269 return BCM_E_PARAM; 1270 } 1271 1272 /* get the index from bitmap. */ 1273 index = BCMI_FT_FLOWCHECKER_INDEX_GET(flowchecker_id); 1274 1275 /* Validate flow checker index. */ 1276 if (bcmi_ft_flowchecker_is_invalid(unit, index)) { 1277 return BCM_E_PARAM; 1278 } 1279 1280 if (BCMI_FT_GROUP_IS_BUSY(unit, id)) { 1281 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, "Adding check to" 1282 " installed Group (%d) is not allowed. \n"), id)); 1283 return BCM_E_CONFIG; 1284 } 1285 if (!BCMI_FT_IDX_IS_PRIMARY_CHECK(flowchecker_id)) { 1286 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, "Given check" 1287 " is not primary\n"))); 1288 return BCM_E_PARAM; 1289 } 1290 1291 /* set Check timestamp */ 1292 rv = bcmi_ft_group_check_ts_set(unit, id, flowchecker_id, 1293 bcmFlowtrackerFlowCheckTsSet); 1294 BCM_IF_ERROR_RETURN(rv); 1295 1296 /* Get associated flowchecks */ 1297 rv = bcmi_ft_check_parts_get(unit, flowchecker_id, check_ids, &num_parts); 1298 BCM_IF_ERROR_RETURN(rv); 1299 1300 /* Add to flowchecker list of group */ 1301 head = &(BCMI_FT_GROUP_FLOWCHECKER_HEAD(unit, id)); 1302 for (part = 0; (part < num_parts) && BCM_SUCCESS(rv); part++) { 1303 rv = bcmi_ft_flowchecker_list_add(unit, head, check_ids[part]); 1304 } 1305 1306 if (BCM_FAILURE(rv)) { 1307 for (part = 0; part < num_parts; part++) { 1308 bcmi_ft_flowchecker_list_delete(unit, head, check_ids[part]); 1309 } 1310 1311 return rv; 1312 } 1313 1314 BCMI_FT_FLOWCHECKER_REFCOUNT_INC(unit, index); 1315 1316 return rv; 1317 } 1318 1319 /* 1320 * Function: 1321 * bcmi_ft_group_flowchecker_delete 1322 * Purpose: 1323 * Delete this flowtracker check from group. 1324 * Parameters: 1325 * unit - (IN) BCM device id 1326 * id - (IN) flowtracker group index. 1327 * flowchecker_id - (IN) flowtracker check index. 1328 * 1329 * Returns: 1330 * BCM_E_XXX. 1331 */ 1332 int 1333 bcmi_ft_group_flowchecker_delete( 1334 int unit, 1335 bcm_flowtracker_group_t id, 1336 bcm_flowtracker_check_t flowchecker_id) 1337 { 1338 int rv = BCM_E_NONE; 1339 int index; 1340 int part = 0; 1341 int num_parts = 0; 1342 bcmi_ft_flowchecker_list_t **head = NULL; 1343 bcm_flowtracker_check_t check_ids[2]; 1344 1345 /* validate flow group index. */ 1346 if (bcmi_ft_group_is_invalid(unit, id)) { 1347 return (BCM_E_PARAM); 1348 } 1349 1350 if (!BCMI_FT_IDX_IS_CHECK(flowchecker_id)) { 1351 return BCM_E_PARAM; 1352 } 1353 1354 /* get the index from bitmap. */ 1355 index = BCMI_FT_FLOWCHECKER_INDEX_GET(flowchecker_id); 1356 1357 /* Validate flow checker index. */ 1358 if (bcmi_ft_flowchecker_is_invalid(unit, index)) { 1359 return BCM_E_PARAM; 1360 } 1361 1362 if (BCMI_FT_GROUP_IS_BUSY(unit, id)) { 1363 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, "Please uninstall" 1364 " Group (%d). operation is not allowed. \n"), id)); 1365 return BCM_E_CONFIG; 1366 } 1367 1368 if (!BCMI_FT_IDX_IS_PRIMARY_CHECK(flowchecker_id)) { 1369 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, "Given check" 1370 " is not primary\n"))); 1371 return BCM_E_PARAM; 1372 } 1373 1374 /* reset Check timestamps */ 1375 rv = bcmi_ft_group_check_ts_set(unit, id, flowchecker_id, 1376 bcmFlowtrackerFlowCheckTsReset); 1377 BCM_IF_ERROR_RETURN(rv); 1378 1379 /* Get associated flowchecks */ 1380 rv = bcmi_ft_check_parts_get(unit, flowchecker_id, check_ids, &num_parts); 1381 BCM_IF_ERROR_RETURN(rv); 1382 1383 head = &(BCMI_FT_GROUP_FLOWCHECKER_HEAD(unit, id)); 1384 for (part = 0; (part < num_parts) && (BCM_SUCCESS(rv)); part++) { 1385 rv = bcmi_ft_flowchecker_list_delete(unit, head, check_ids[part]); 1386 } 1387 1388 if (BCM_SUCCESS(rv)) { 1389 BCMI_FT_FLOWCHECKER_REFCOUNT_DEC(unit, index); 1390 } 1391 1392 return rv; 1393 } 1394 1395 /* 1396 * Function: 1397 * bcmi_ft_group_flowchecker_get_all 1398 * Purpose: 1399 * Get all the flowtracker checks from group. 1400 * Parameters: 1401 * unit - (IN) BCM device id 1402 * id - (IN) flowtracker group index. 1403 * max_checks - (IN) max number of flowtracker check ids to be sent.. 1404 * list_of_check_ids - (IN) list of the flowtracker check ids. 1405 * num_checks - NUmber of checks actually sent. 1406 * 1407 * Returns: 1408 * BCM_E_XXX. 1409 */ 1410 int 1411 bcmi_flowtracker_check_get_all( 1412 int unit, 1413 bcm_flowtracker_group_t id, 1414 int skip_non_primary, 1415 int max_checks, 1416 bcm_flowtracker_check_t *list_of_check_ids, 1417 int *num_checks) 1418 { 1419 1420 bcmi_ft_flowchecker_list_t *temp; 1421 int only_count = 0; 1422 int i = 0; 1423 1424 /* validate flow group index. */ 1425 if (bcmi_ft_group_is_invalid(unit, id)) { 1426 return (BCM_E_PARAM); 1427 } 1428 1429 /* If the max_checks is non zero and list == NULL, return 1430 * BCM_E_PARAM. 1431 */ 1432 if (max_checks != 0 && list_of_check_ids == NULL) { 1433 return BCM_E_PARAM; 1434 } 1435 1436 /* If max_alu_info == 0 and list_of_export_elements == NULL, 1437 * return the number of export elements in list_size 1438 * variable. 1439 */ 1440 if (max_checks == 0 && list_of_check_ids == NULL) { 1441 only_count = 1; 1442 } 1443 1444 temp = BCMI_FT_GROUP_FLOWCHECKER_HEAD(unit, id); 1445 1446 while (temp) { 1447 /* 1448 * Go till end and start putting ids in array. 1449 * The limit is given by max_checks. 1450 */ 1451 if ((!only_count) && (max_checks != -1) && (i < max_checks)) { 1452 if ((skip_non_primary == TRUE) && 1453 (!BCMI_FT_IDX_IS_PRIMARY_CHECK(temp->flowchecker_id))) { 1454 temp = temp->next; 1455 continue; 1456 } 1457 list_of_check_ids[i] = temp->flowchecker_id; 1458 } 1459 1460 i++; 1461 temp = temp->next; 1462 } 1463 1464 *num_checks = i; 1465 1466 return BCM_E_NONE; 1467 } 1468 1469 1470 /* 1471 * Function: 1472 * bcmi_ft_check_compare 1473 * Purpose: 1474 * Compare two flowtracker checks. 1475 * Parameters: 1476 * unit - (IN) BCM device id 1477 * check_id1 - (IN) first flowtracker check index. 1478 * check_id2 - (IN) Second flowtracker check index. 1479 * Returns: 1480 * BCM_E_XXX. 1481 */ 1482 int 1483 bcmi_ft_check_compare( 1484 int unit, 1485 bcm_flowtracker_check_t check_id1, 1486 bcm_flowtracker_check_t check_id2) 1487 { 1488 1489 bcmi_flowtracker_flowchecker_info_t fc_info1, fc_info2; 1490 1491 1492 sal_memset(&fc_info1, 0, sizeof(bcmi_flowtracker_flowchecker_info_t)); 1493 sal_memset(&fc_info2, 0, sizeof(bcmi_flowtracker_flowchecker_info_t)); 1494 1495 /* If both flow checks are same then return match. */ 1496 if (check_id1 == check_id2) { 1497 return BCM_E_NONE; 1498 } 1499 1500 /* Validate flow checker index. */ 1501 if (bcmi_ft_flowchecker_is_invalid(unit, 1502 BCMI_FT_FLOWCHECKER_INDEX_GET(check_id1))) { 1503 1504 return BCM_E_NOT_FOUND; 1505 } 1506 1507 /* Validate flow checker index. */ 1508 if (bcmi_ft_flowchecker_is_invalid(unit, 1509 BCMI_FT_FLOWCHECKER_INDEX_GET(check_id2))) { 1510 1511 return BCM_E_NOT_FOUND; 1512 } 1513 1514 BCM_IF_ERROR_RETURN(bcmi_ft_flowchecker_get 1515 (unit, check_id1, &fc_info1)); 1516 1517 BCM_IF_ERROR_RETURN(bcmi_ft_flowchecker_get 1518 (unit, check_id2, &fc_info2)); 1519 1520 /* Compare the flow checks and if same then return MATCH. */ 1521 if (!(sal_memcmp(&fc_info1, &fc_info2, 1522 sizeof(bcmi_flowtracker_flowchecker_info_t)))) { 1523 return BCM_E_NONE; 1524 } 1525 1526 return BCM_E_NOT_FOUND; 1527 } 1528 1529 /* 1530 * Function: 1531 * bcmi_ft_check_list_compare 1532 * Purpose: 1533 * Compare all the checks in group list. 1534 * Parameters: 1535 * unit - (IN) BCM device id 1536 * head - (IN) Head of the flowchecker list. 1537 * check_id - (IN) flowtracker check index. 1538 * Returns: 1539 * BCM_E_XXX. 1540 */ 1541 int 1542 bcmi_ft_check_list_compare( 1543 int unit, 1544 bcmi_ft_flowchecker_list_t **head, 1545 bcm_flowtracker_check_t check_id) 1546 { 1547 1548 bcmi_ft_flowchecker_list_t *temp; 1549 1550 if ((head == NULL) || (*head == NULL)) { 1551 return BCM_E_NOT_FOUND; 1552 } 1553 1554 temp = *head; 1555 1556 while (temp != NULL) { 1557 if (!(bcmi_ft_check_compare(unit, check_id, temp->flowchecker_id))) { 1558 return BCM_E_NONE; 1559 } 1560 temp = temp->next; 1561 } 1562 1563 return BCM_E_NOT_FOUND; 1564 } 1565 1566 /* 1567 * Function: 1568 * bcmi_ft_group_check_validate 1569 * Purpose: 1570 * Validate Flowcheck if given configuration is allowed 1571 * based in options params. 1572 * Parameters: 1573 * unit - (IN) BCM device id 1574 * optiosn - (IN) Match criteria 1575 * id - (IN) Flowtracker group 1576 * check_id - (IN) flowtracker check 1577 * Returns: 1578 * BCM_E_XXX. 1579 */ 1580 int 1581 bcmi_ft_group_check_validate( 1582 int unit, 1583 uint32 options, 1584 bcm_flowtracker_group_t id, 1585 bcm_flowtracker_check_t check_id) 1586 { 1587 int index; 1588 int found = FALSE; 1589 bcmi_ft_flowchecker_list_t *head = NULL; 1590 bcmi_ft_flowchecker_list_t *temp = NULL; 1591 1592 if (!BCMI_FT_IDX_IS_CHECK(check_id)) { 1593 return BCM_E_PARAM; 1594 } 1595 index = BCMI_FT_FLOWCHECKER_INDEX_GET(check_id); 1596 if (bcmi_ft_flowchecker_is_invalid(unit, index)) { 1597 return BCM_E_PARAM; 1598 } 1599 1600 if (options & BCMI_FT_GROUP_CHECK_MATCH_PRIMARY) { 1601 if (!BCMI_FT_IDX_IS_PRIMARY_CHECK(check_id)) { 1602 return BCM_E_PARAM; 1603 } 1604 } 1605 1606 if(options & BCMI_FT_GROUP_CHECK_MATCH_GROUP) { 1607 /* Search for CheckId in the Group */ 1608 if (bcmi_ft_group_is_invalid(unit, id)) { 1609 return BCM_E_NOT_FOUND; 1610 } 1611 head = BCMI_FT_GROUP_FLOWCHECKER_HEAD(unit, id); 1612 if (!head) { 1613 return BCM_E_NOT_FOUND; 1614 } 1615 temp = (head); 1616 while(temp) { 1617 if (temp->flowchecker_id == check_id) { 1618 found = TRUE; 1619 break; 1620 } 1621 temp = temp->next; 1622 } 1623 if (found == FALSE) { 1624 return BCM_E_PARAM; 1625 } 1626 } 1627 1628 return BCM_E_NONE; 1629 } 1630 1631 1632 #else /* BCM_FLOWTRCAKER_SUPPORT*/ 1633 int bcmi_ft_check_not_empty; 1634 #endif /* BCM_FLOWTRCAKER_SUPPORT */