Print this page
5045 use atomic_{inc,dec}_* instead of atomic_add_*


 258             PROJID_MASK);
 259         /* IF_INDEX selector structure */
 260         insert_ipgpc_table_list_info(IF_IDX, if_table, IPGPC_UNSPECIFIED,
 261             IF_MASK);
 262         /* DIR selector structure */
 263         insert_ipgpc_table_list_info(DIR_IDX, dir_table, IPGPC_UNSPECIFIED,
 264             DIR_MASK);
 265 }
 266 
 267 static void
 268 initialize_ba_tables(void)
 269 {
 270         /* DS (ToS/Traffic Class) field structure */
 271         ipgpc_ds_table_id.info.mask = DS_MASK;
 272         ipgpc_ds_table_id.info.dontcareonly = B_TRUE;
 273 }
 274 
 275 static void
 276 element_node_ref(element_node_t *element)
 277 {
 278         atomic_add_32(&element->element_refcnt, 1);
 279         ASSERT(element->element_refcnt > 1);
 280 }
 281 
 282 static void
 283 element_node_unref(element_node_t *element)
 284 {
 285         ASSERT(element->element_refcnt > 0);
 286         if (atomic_add_32_nv(&element->element_refcnt, -1) == 0) {
 287                 kmem_cache_free(element_node_cache, element);
 288         }
 289 }
 290 
 291 /* ARGSUSED1 */
 292 static int
 293 element_node_cache_constructor(void *buf, void *cdrarg, int kmflags)
 294 {
 295         element_node_t *node = buf;
 296 
 297         node->element_ref = element_node_ref;
 298         node->element_unref = element_node_unref;
 299         return (0);
 300 }
 301 
 302 /* prime values to be used for hashing of filter and class tables */
 303 #define IPGPC_PRIMES()  {0, 0, 0, 5, 11, 23, 47, 89, 191, 383, 503, 761, \
 304                         1009, 1531, 2003, 2503, 3067, 3511, 4001, 5003, 6143, \
 305                         10007, 12281, 15013, 20011, 24571, 49139, 98299, \
 306                         100003, 196597, 393209, 786431, 1000003, 1251409, \


1119         }
1120         /* check to see if this is a catch all filter, which we reject */
1121         if (fid->insert_map == 0) {
1122                 ipgpc0dbg(("ipgpc_addfilter(): filter %s rejected because " \
1123                     "catch all filters are not supported\n",
1124                     filter->filter_name));
1125                 /* cleanup what we allocated */
1126                 /* remove filter from filter list */
1127                 ipgpc_fid_list[filter_id].info = -1;
1128                 ipgpc_fid_list[filter_id].filter.filter_name[0] = '\0';
1129                 reset_dontcare_stats(); /* need to fixup stats */
1130                 mutex_exit(&ipgpc_fid_list_lock);
1131                 return (EINVAL);
1132         } else {                /* associate filter with class */
1133                 mutex_enter(&ipgpc_cid_list_lock);
1134                 (void) ipgpc_list_insert(&ipgpc_cid_list[class_id].filter_list,
1135                     filter_id);
1136                 mutex_exit(&ipgpc_cid_list_lock);
1137         }
1138         mutex_exit(&ipgpc_fid_list_lock);
1139         atomic_add_long(&ipgpc_num_fltrs, 1);
1140         ipgpc3dbg(("ipgpc_addfilter: adding filter %s", filter->filter_name));
1141         return (0);
1142 }
1143 
1144 /*
1145  * reset_dontcare_stats()
1146  *
1147  * when an insertion fails because zero selectors are specified in a filter
1148  * the number of dontcare's recorded for each selector structure needs to be
1149  * decremented
1150  */
1151 static void
1152 reset_dontcare_stats(void)
1153 {
1154         int i;
1155 
1156         for (i = 0; i < NUM_TRIES; ++i) {
1157                 atomic_add_32(&ipgpc_trie_list[i].stats.num_dontcare, -1);
1158         }
1159         for (i = 0; i < NUM_TABLES; ++i) {
1160                 atomic_add_32(&ipgpc_table_list[i].stats.num_dontcare, -1);
1161         }
1162         atomic_add_32(&ipgpc_ds_table_id.stats.num_dontcare, -1);
1163 }
1164 
1165 /*
1166  * ipgpc_parse_class(out_class, nvlp)
1167  *
1168  * Given a name value pair list, a class structure will be parsed.
1169  * To be a valid class, the class name, originator id and next action name
1170  * must be present. gather_stats is optional, if absent default value is used
1171  */
1172 int
1173 ipgpc_parse_class(ipgpc_class_t *out_class, nvlist_t *nvlp)
1174 {
1175         char *name;
1176         size_t name_len;
1177         uint32_t gather_stats;
1178 
1179         /* parse class name */
1180         if (nvlist_lookup_string(nvlp, CLASSIFIER_CLASS_NAME, &name) != 0) {
1181                 return (EINVAL); /* class name missing, error */
1182         }


1340                 /* create new filter list for new class */
1341                 ipgpc_cid_list[class_id].info = 1;
1342                 ipgpc_cid_list[class_id].aclass = *in_class;
1343                 if (in_class->gather_stats == B_TRUE) {
1344                         /* init kstat entry */
1345                         if ((rc = class_statinit(in_class, class_id)) != 0) {
1346                                 ipgpc_cid_list[class_id].info = -1;
1347                                 ipgpc0dbg(("insertcid: "
1348                                     "class_statinit failed with error %d", rc));
1349                                 mutex_exit(&ipgpc_cid_list_lock);
1350                                 return (rc);
1351                         }
1352                 } else {
1353                         ipgpc_cid_list[class_id].cl_stats = NULL;
1354                 }
1355                 ipgpc3dbg(("insertcid: adding class %s",
1356                     in_class->class_name));
1357                 bcopy(in_class->class_name,
1358                     ipgpc_cid_list[class_id].aclass.class_name, MAXNAMELEN);
1359                 ipgpc_cid_list[class_id].filter_list = NULL;
1360                 atomic_add_long(&ipgpc_num_cls, 1);
1361         } else {
1362                 ipgpc0dbg(("insertcid: class name lookup error %d", err));
1363                 mutex_exit(&ipgpc_cid_list_lock);
1364                 return (err);
1365         }
1366         mutex_exit(&ipgpc_cid_list_lock);
1367         *out_class_id = class_id;
1368         return (err);
1369 }
1370 
1371 /*
1372  * common_removefilter(in_filter_id, fid)
1373  *
1374  * removes in_filter_id from each of the common selector structures
1375  */
1376 static void
1377 common_removefilter(int in_filter_id, fid_t *fid)
1378 {
1379         /* start trie removes */
1380         t_remove(&ipgpc_trie_list[IPGPC_TRIE_SPORTID], in_filter_id,


1487                 break;
1488         case IPGPC_V6_FLTR:
1489                 common_removefilter(filter_id, fid);
1490                 v6_removefilter(filter_id, fid);
1491                 break;
1492         default:
1493                 ipgpc0dbg(("ipgpc_removefilter(): invalid filter type %d",
1494                     fid->filter.filter_type));
1495                 mutex_exit(&ipgpc_fid_list_lock);
1496                 return (EINVAL);
1497         }
1498         /* remove filter from filter list */
1499         ipgpc_fid_list[filter_id].info = -1;
1500         ipgpc_fid_list[filter_id].insert_map = 0;
1501         ipgpc_fid_list[filter_id].filter.filter_name[0] = '\0';
1502         ipgpc_filter_destructor(&ipgpc_fid_list[filter_id].filter);
1503         mutex_exit(&ipgpc_fid_list_lock);
1504         /* remove filter id from class' list of filters */
1505         remove_from_cid_filter_list(ipgpc_fid_list[filter_id].class_id,
1506             filter_id);
1507         atomic_add_long(&ipgpc_num_fltrs, -1);
1508         return (0);
1509 }
1510 
1511 /*
1512  * removecid(in_class_id)
1513  *
1514  * removes the cid entry from the cid list and frees allocated structures
1515  */
1516 static void
1517 removecid(int in_class_id)
1518 {
1519         ipgpc_cid_list[in_class_id].info = -1;
1520         ipgpc_cid_list[in_class_id].aclass.class_name[0] = '\0';
1521         ipgpc_cid_list[in_class_id].aclass.next_action = -1;
1522         /* delete kstat entry */
1523         if (ipgpc_cid_list[in_class_id].cl_stats != NULL) {
1524                 ipp_stat_destroy(ipgpc_cid_list[in_class_id].cl_stats);
1525                 ipgpc_cid_list[in_class_id].cl_stats = NULL;
1526         }
1527         /* decrement total number of classes loaded */
1528         atomic_add_long(&ipgpc_num_cls, -1);
1529 }
1530 
1531 /*
1532  * remove_from_cid_filter_list(in_class_id, in_filter_id)
1533  *
1534  * removes the input filter_id from the filter_list of the class associated
1535  * with the input class_id
1536  */
1537 static void
1538 remove_from_cid_filter_list(int in_class_id, int in_filter_id)
1539 {
1540         cid_t *cid = &ipgpc_cid_list[in_class_id];
1541 
1542         if (cid->filter_list != NULL) {
1543                 (void) ipgpc_list_remove(&cid->filter_list, in_filter_id);
1544         }
1545 }
1546 
1547 /*
1548  * ipgpc_removeclass(class_name)




 258             PROJID_MASK);
 259         /* IF_INDEX selector structure */
 260         insert_ipgpc_table_list_info(IF_IDX, if_table, IPGPC_UNSPECIFIED,
 261             IF_MASK);
 262         /* DIR selector structure */
 263         insert_ipgpc_table_list_info(DIR_IDX, dir_table, IPGPC_UNSPECIFIED,
 264             DIR_MASK);
 265 }
 266 
 267 static void
 268 initialize_ba_tables(void)
 269 {
 270         /* DS (ToS/Traffic Class) field structure */
 271         ipgpc_ds_table_id.info.mask = DS_MASK;
 272         ipgpc_ds_table_id.info.dontcareonly = B_TRUE;
 273 }
 274 
 275 static void
 276 element_node_ref(element_node_t *element)
 277 {
 278         atomic_inc_32(&element->element_refcnt);
 279         ASSERT(element->element_refcnt > 1);
 280 }
 281 
 282 static void
 283 element_node_unref(element_node_t *element)
 284 {
 285         ASSERT(element->element_refcnt > 0);
 286         if (atomic_dec_32_nv(&element->element_refcnt) == 0) {
 287                 kmem_cache_free(element_node_cache, element);
 288         }
 289 }
 290 
 291 /* ARGSUSED1 */
 292 static int
 293 element_node_cache_constructor(void *buf, void *cdrarg, int kmflags)
 294 {
 295         element_node_t *node = buf;
 296 
 297         node->element_ref = element_node_ref;
 298         node->element_unref = element_node_unref;
 299         return (0);
 300 }
 301 
 302 /* prime values to be used for hashing of filter and class tables */
 303 #define IPGPC_PRIMES()  {0, 0, 0, 5, 11, 23, 47, 89, 191, 383, 503, 761, \
 304                         1009, 1531, 2003, 2503, 3067, 3511, 4001, 5003, 6143, \
 305                         10007, 12281, 15013, 20011, 24571, 49139, 98299, \
 306                         100003, 196597, 393209, 786431, 1000003, 1251409, \


1119         }
1120         /* check to see if this is a catch all filter, which we reject */
1121         if (fid->insert_map == 0) {
1122                 ipgpc0dbg(("ipgpc_addfilter(): filter %s rejected because " \
1123                     "catch all filters are not supported\n",
1124                     filter->filter_name));
1125                 /* cleanup what we allocated */
1126                 /* remove filter from filter list */
1127                 ipgpc_fid_list[filter_id].info = -1;
1128                 ipgpc_fid_list[filter_id].filter.filter_name[0] = '\0';
1129                 reset_dontcare_stats(); /* need to fixup stats */
1130                 mutex_exit(&ipgpc_fid_list_lock);
1131                 return (EINVAL);
1132         } else {                /* associate filter with class */
1133                 mutex_enter(&ipgpc_cid_list_lock);
1134                 (void) ipgpc_list_insert(&ipgpc_cid_list[class_id].filter_list,
1135                     filter_id);
1136                 mutex_exit(&ipgpc_cid_list_lock);
1137         }
1138         mutex_exit(&ipgpc_fid_list_lock);
1139         atomic_inc_ulong(&ipgpc_num_fltrs);
1140         ipgpc3dbg(("ipgpc_addfilter: adding filter %s", filter->filter_name));
1141         return (0);
1142 }
1143 
1144 /*
1145  * reset_dontcare_stats()
1146  *
1147  * when an insertion fails because zero selectors are specified in a filter
1148  * the number of dontcare's recorded for each selector structure needs to be
1149  * decremented
1150  */
1151 static void
1152 reset_dontcare_stats(void)
1153 {
1154         int i;
1155 
1156         for (i = 0; i < NUM_TRIES; ++i) {
1157                 atomic_dec_32(&ipgpc_trie_list[i].stats.num_dontcare);
1158         }
1159         for (i = 0; i < NUM_TABLES; ++i) {
1160                 atomic_dec_32(&ipgpc_table_list[i].stats.num_dontcare);
1161         }
1162         atomic_dec_32(&ipgpc_ds_table_id.stats.num_dontcare);
1163 }
1164 
1165 /*
1166  * ipgpc_parse_class(out_class, nvlp)
1167  *
1168  * Given a name value pair list, a class structure will be parsed.
1169  * To be a valid class, the class name, originator id and next action name
1170  * must be present. gather_stats is optional, if absent default value is used
1171  */
1172 int
1173 ipgpc_parse_class(ipgpc_class_t *out_class, nvlist_t *nvlp)
1174 {
1175         char *name;
1176         size_t name_len;
1177         uint32_t gather_stats;
1178 
1179         /* parse class name */
1180         if (nvlist_lookup_string(nvlp, CLASSIFIER_CLASS_NAME, &name) != 0) {
1181                 return (EINVAL); /* class name missing, error */
1182         }


1340                 /* create new filter list for new class */
1341                 ipgpc_cid_list[class_id].info = 1;
1342                 ipgpc_cid_list[class_id].aclass = *in_class;
1343                 if (in_class->gather_stats == B_TRUE) {
1344                         /* init kstat entry */
1345                         if ((rc = class_statinit(in_class, class_id)) != 0) {
1346                                 ipgpc_cid_list[class_id].info = -1;
1347                                 ipgpc0dbg(("insertcid: "
1348                                     "class_statinit failed with error %d", rc));
1349                                 mutex_exit(&ipgpc_cid_list_lock);
1350                                 return (rc);
1351                         }
1352                 } else {
1353                         ipgpc_cid_list[class_id].cl_stats = NULL;
1354                 }
1355                 ipgpc3dbg(("insertcid: adding class %s",
1356                     in_class->class_name));
1357                 bcopy(in_class->class_name,
1358                     ipgpc_cid_list[class_id].aclass.class_name, MAXNAMELEN);
1359                 ipgpc_cid_list[class_id].filter_list = NULL;
1360                 atomic_inc_ulong(&ipgpc_num_cls);
1361         } else {
1362                 ipgpc0dbg(("insertcid: class name lookup error %d", err));
1363                 mutex_exit(&ipgpc_cid_list_lock);
1364                 return (err);
1365         }
1366         mutex_exit(&ipgpc_cid_list_lock);
1367         *out_class_id = class_id;
1368         return (err);
1369 }
1370 
1371 /*
1372  * common_removefilter(in_filter_id, fid)
1373  *
1374  * removes in_filter_id from each of the common selector structures
1375  */
1376 static void
1377 common_removefilter(int in_filter_id, fid_t *fid)
1378 {
1379         /* start trie removes */
1380         t_remove(&ipgpc_trie_list[IPGPC_TRIE_SPORTID], in_filter_id,


1487                 break;
1488         case IPGPC_V6_FLTR:
1489                 common_removefilter(filter_id, fid);
1490                 v6_removefilter(filter_id, fid);
1491                 break;
1492         default:
1493                 ipgpc0dbg(("ipgpc_removefilter(): invalid filter type %d",
1494                     fid->filter.filter_type));
1495                 mutex_exit(&ipgpc_fid_list_lock);
1496                 return (EINVAL);
1497         }
1498         /* remove filter from filter list */
1499         ipgpc_fid_list[filter_id].info = -1;
1500         ipgpc_fid_list[filter_id].insert_map = 0;
1501         ipgpc_fid_list[filter_id].filter.filter_name[0] = '\0';
1502         ipgpc_filter_destructor(&ipgpc_fid_list[filter_id].filter);
1503         mutex_exit(&ipgpc_fid_list_lock);
1504         /* remove filter id from class' list of filters */
1505         remove_from_cid_filter_list(ipgpc_fid_list[filter_id].class_id,
1506             filter_id);
1507         atomic_dec_ulong(&ipgpc_num_fltrs);
1508         return (0);
1509 }
1510 
1511 /*
1512  * removecid(in_class_id)
1513  *
1514  * removes the cid entry from the cid list and frees allocated structures
1515  */
1516 static void
1517 removecid(int in_class_id)
1518 {
1519         ipgpc_cid_list[in_class_id].info = -1;
1520         ipgpc_cid_list[in_class_id].aclass.class_name[0] = '\0';
1521         ipgpc_cid_list[in_class_id].aclass.next_action = -1;
1522         /* delete kstat entry */
1523         if (ipgpc_cid_list[in_class_id].cl_stats != NULL) {
1524                 ipp_stat_destroy(ipgpc_cid_list[in_class_id].cl_stats);
1525                 ipgpc_cid_list[in_class_id].cl_stats = NULL;
1526         }
1527         /* decrement total number of classes loaded */
1528         atomic_dec_ulong(&ipgpc_num_cls);
1529 }
1530 
1531 /*
1532  * remove_from_cid_filter_list(in_class_id, in_filter_id)
1533  *
1534  * removes the input filter_id from the filter_list of the class associated
1535  * with the input class_id
1536  */
1537 static void
1538 remove_from_cid_filter_list(int in_class_id, int in_filter_id)
1539 {
1540         cid_t *cid = &ipgpc_cid_list[in_class_id];
1541 
1542         if (cid->filter_list != NULL) {
1543                 (void) ipgpc_list_remove(&cid->filter_list, in_filter_id);
1544         }
1545 }
1546 
1547 /*
1548  * ipgpc_removeclass(class_name)