1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/errno.h> 30*7c478bd9Sstevel@tonic-gate #include <ipp/ipgpc/classifier.h> 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate /* Implementation file for behavior aggregate (BA) lookup table */ 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate /* 35*7c478bd9Sstevel@tonic-gate * ba_insert(bataid, filter_id, val, mask) 36*7c478bd9Sstevel@tonic-gate * 37*7c478bd9Sstevel@tonic-gate * inserts filter_id into element list of bataid->table->masked_values 38*7c478bd9Sstevel@tonic-gate * at position val& mask, mask is inserted into the mask list. 39*7c478bd9Sstevel@tonic-gate * filter_id shouldn't already exist in element list at 40*7c478bd9Sstevel@tonic-gate * bataid->table->masked_values[val], an error message is printed if this 41*7c478bd9Sstevel@tonic-gate * occurs. 42*7c478bd9Sstevel@tonic-gate * return DONTCARE_VALUE if mask == 0, NORMAL_VALUE otherwise 43*7c478bd9Sstevel@tonic-gate */ 44*7c478bd9Sstevel@tonic-gate int 45*7c478bd9Sstevel@tonic-gate ba_insert(ba_table_id_t *bataid, int filter_id, uint8_t val, uint8_t mask) 46*7c478bd9Sstevel@tonic-gate { 47*7c478bd9Sstevel@tonic-gate uint8_t mskd_val = val & mask; 48*7c478bd9Sstevel@tonic-gate ba_table_t *table = &bataid->table; 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate /* dontcares are not inserted */ 51*7c478bd9Sstevel@tonic-gate if (mask == 0) { 52*7c478bd9Sstevel@tonic-gate ++bataid->stats.num_dontcare; 53*7c478bd9Sstevel@tonic-gate return (DONTCARE_VALUE); 54*7c478bd9Sstevel@tonic-gate } 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate if (bataid->info.dontcareonly == B_TRUE) { 57*7c478bd9Sstevel@tonic-gate bataid->info.dontcareonly = B_FALSE; 58*7c478bd9Sstevel@tonic-gate } 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate if (ipgpc_list_insert(&table->masked_values[mskd_val].filter_list, 61*7c478bd9Sstevel@tonic-gate filter_id) == EEXIST) { 62*7c478bd9Sstevel@tonic-gate ipgpc0dbg(("ba_insert():filter_id %d EEXIST in ba_table", 63*7c478bd9Sstevel@tonic-gate filter_id)); 64*7c478bd9Sstevel@tonic-gate } else { 65*7c478bd9Sstevel@tonic-gate /* insert mask */ 66*7c478bd9Sstevel@tonic-gate (void) ipgpc_list_insert(&table->masks, mask); 67*7c478bd9Sstevel@tonic-gate /* update stats */ 68*7c478bd9Sstevel@tonic-gate ++table->masked_values[mskd_val].info; 69*7c478bd9Sstevel@tonic-gate ++bataid->stats.num_inserted; 70*7c478bd9Sstevel@tonic-gate } 71*7c478bd9Sstevel@tonic-gate return (NORMAL_VALUE); 72*7c478bd9Sstevel@tonic-gate } 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate /* 75*7c478bd9Sstevel@tonic-gate * ba_retrieve(bataid, value, fid_table) 76*7c478bd9Sstevel@tonic-gate * 77*7c478bd9Sstevel@tonic-gate * searches for all filters matching value in bataid->table 78*7c478bd9Sstevel@tonic-gate * search is performed by appling each mask in bataid->table->masks list 79*7c478bd9Sstevel@tonic-gate * to value and then looking value up in bataid->table->masked_values. 80*7c478bd9Sstevel@tonic-gate * Each filter id that is matched, is inserted into fid_table 81*7c478bd9Sstevel@tonic-gate * returns number of matched filters or (-1) if memory error 82*7c478bd9Sstevel@tonic-gate */ 83*7c478bd9Sstevel@tonic-gate int 84*7c478bd9Sstevel@tonic-gate ba_retrieve(ba_table_id_t *bataid, uint8_t value, ht_match_t *fid_table) 85*7c478bd9Sstevel@tonic-gate { 86*7c478bd9Sstevel@tonic-gate element_node_t *p; 87*7c478bd9Sstevel@tonic-gate element_node_t *filter_list; 88*7c478bd9Sstevel@tonic-gate int num_found = 0; 89*7c478bd9Sstevel@tonic-gate int ret; 90*7c478bd9Sstevel@tonic-gate int masked_value = 0; 91*7c478bd9Sstevel@tonic-gate ba_table_t *table = &bataid->table; 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate /* special case, if value == 0, no need to apply masks */ 94*7c478bd9Sstevel@tonic-gate if (value == 0) { 95*7c478bd9Sstevel@tonic-gate /* masked value will always be 0 for this case */ 96*7c478bd9Sstevel@tonic-gate filter_list = 97*7c478bd9Sstevel@tonic-gate table->masked_values[0].filter_list; 98*7c478bd9Sstevel@tonic-gate if ((num_found = ipgpc_mark_found(bataid->info.mask, 99*7c478bd9Sstevel@tonic-gate filter_list, fid_table)) == -1) { 100*7c478bd9Sstevel@tonic-gate return (-1); /* signifies a memory error */ 101*7c478bd9Sstevel@tonic-gate } 102*7c478bd9Sstevel@tonic-gate return (num_found); 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate /* apply each mask to the value and do the look up in the ba table */ 106*7c478bd9Sstevel@tonic-gate for (p = table->masks; p != NULL; p = p->next) { 107*7c478bd9Sstevel@tonic-gate masked_value = (uint8_t)(p->id) & value; 108*7c478bd9Sstevel@tonic-gate if (bataid->table.masked_values[masked_value].info == 0) { 109*7c478bd9Sstevel@tonic-gate /* masked_value has 0 filters associated with it */ 110*7c478bd9Sstevel@tonic-gate continue; 111*7c478bd9Sstevel@tonic-gate } 112*7c478bd9Sstevel@tonic-gate filter_list = 113*7c478bd9Sstevel@tonic-gate table->masked_values[masked_value].filter_list; 114*7c478bd9Sstevel@tonic-gate if ((ret = ipgpc_mark_found(bataid->info.mask, filter_list, 115*7c478bd9Sstevel@tonic-gate fid_table)) == -1) { 116*7c478bd9Sstevel@tonic-gate return (-1); /* signifies a memory error */ 117*7c478bd9Sstevel@tonic-gate } 118*7c478bd9Sstevel@tonic-gate num_found += ret; /* increment num_found */ 119*7c478bd9Sstevel@tonic-gate } 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate return (num_found); 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate /* 125*7c478bd9Sstevel@tonic-gate * ba_remove(bataid, filter_id, value, mask) 126*7c478bd9Sstevel@tonic-gate * 127*7c478bd9Sstevel@tonic-gate * removes filter_id from bataid->table->masked_values[mask & value] 128*7c478bd9Sstevel@tonic-gate * mask is removed from bataid->table->masks if refcnt == 0 for that list 129*7c478bd9Sstevel@tonic-gate */ 130*7c478bd9Sstevel@tonic-gate void 131*7c478bd9Sstevel@tonic-gate ba_remove(ba_table_id_t *bataid, int filter_id, uint8_t value, uint8_t mask) 132*7c478bd9Sstevel@tonic-gate { 133*7c478bd9Sstevel@tonic-gate uint8_t masked_value = value & mask; 134*7c478bd9Sstevel@tonic-gate ba_table_t *table = &bataid->table; 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate /* dontcares are not inserted */ 137*7c478bd9Sstevel@tonic-gate if (mask == 0) { 138*7c478bd9Sstevel@tonic-gate --bataid->stats.num_dontcare; 139*7c478bd9Sstevel@tonic-gate return; 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate if (ipgpc_list_remove(&table->masked_values[masked_value].filter_list, 143*7c478bd9Sstevel@tonic-gate filter_id) == B_TRUE) { 144*7c478bd9Sstevel@tonic-gate /* update stats */ 145*7c478bd9Sstevel@tonic-gate --table->masked_values[masked_value].info; 146*7c478bd9Sstevel@tonic-gate --bataid->stats.num_inserted; 147*7c478bd9Sstevel@tonic-gate /* 148*7c478bd9Sstevel@tonic-gate * check to see if removing this entry will result in 149*7c478bd9Sstevel@tonic-gate * don't cares only inserted in the table 150*7c478bd9Sstevel@tonic-gate */ 151*7c478bd9Sstevel@tonic-gate if (bataid->stats.num_inserted <= 0) { 152*7c478bd9Sstevel@tonic-gate bataid->info.dontcareonly = B_TRUE; 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate /* remove mask if refcnt == 0 */ 155*7c478bd9Sstevel@tonic-gate (void) ipgpc_list_remove(&table->masks, mask); 156*7c478bd9Sstevel@tonic-gate } 157*7c478bd9Sstevel@tonic-gate } 158