Lines Matching +full:ch +full:- +full:func

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2014-2025 Yandex LLC
31 * Multi-field value support for ipfw tables.
34 * large multi-field values into u32 indices suitable to be fed
66 static int list_table_values(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
73 #define CHAIN_TO_VI(chain) (CHAIN_TO_TCFG(chain)->valhash)
80 #define VALDATA_START_SIZE 64 /* Allocate 64-items array by default */
84 struct ip_fw_chain *ch; member
101 return (memcmp(((struct table_val_link *)no)->pval, key, 56)); in cmp_table_value()
108 #define _MCPY(f, b) if ((mask & (b)) != 0) { dst->f = src->f; } in mask_table_value()
128 get_value_ptrs(struct ip_fw_chain *ch, struct table_config *tc, int vshared, in get_value_ptrs() argument
135 pval = (struct table_value *)ch->valuestate; in get_value_ptrs()
136 vi = CHAIN_TO_VI(ch); in get_value_ptrs()
140 //pval = (struct table_value *)&tc->ti.data; in get_value_ptrs()
162 pval = da->pval; in update_tvalue()
163 ptv->pval = &pval[ptv->no.kidx]; in update_tvalue()
164 ptv->no.name = (char *)&pval[ptv->no.kidx]; in update_tvalue()
171 * Notifies other running adds on @ch shared storage resize.
179 resize_shared_value_storage(struct ip_fw_chain *ch) in resize_shared_value_storage() argument
189 IPFW_UH_WLOCK_ASSERT(ch); in resize_shared_value_storage()
194 pval = (struct table_value *)ch->valuestate; in resize_shared_value_storage()
195 vi = CHAIN_TO_VI(ch); in resize_shared_value_storage()
196 tcfg = CHAIN_TO_TCFG(ch); in resize_shared_value_storage()
198 val_size = tcfg->val_size * 2; in resize_shared_value_storage()
203 IPFW_UH_WUNLOCK(ch); in resize_shared_value_storage()
210 IPFW_UH_WLOCK(ch); in resize_shared_value_storage()
215 if (tcfg->val_size >= val_size) in resize_shared_value_storage()
218 /* Update pointers and notify everyone we're changing @ch */ in resize_shared_value_storage()
219 pval = (struct table_value *)ch->valuestate; in resize_shared_value_storage()
220 rollback_toperation_state(ch, ch); in resize_shared_value_storage()
223 memcpy(valuestate, pval, sizeof(struct table_value) * tcfg->val_size); in resize_shared_value_storage()
224 ipfw_objhash_bitmap_merge(CHAIN_TO_VI(ch), &new_idx, &new_blocks); in resize_shared_value_storage()
226 IPFW_WLOCK(ch); in resize_shared_value_storage()
228 old_valuestate = ch->valuestate; in resize_shared_value_storage()
229 ch->valuestate = valuestate; in resize_shared_value_storage()
231 ipfw_objhash_bitmap_swap(CHAIN_TO_VI(ch), &new_idx, &new_blocks); in resize_shared_value_storage()
233 val_size_old = tcfg->val_size; in resize_shared_value_storage()
234 tcfg->val_size = val_size; in resize_shared_value_storage()
236 IPFW_WUNLOCK(ch); in resize_shared_value_storage()
239 da.pval = (struct table_value *)ch->valuestate; in resize_shared_value_storage()
260 if (--pval[kidx].refcnt > 0) in unref_table_value()
266 ipfw_objhash_del(vi, &ptvl->no); in unref_table_value()
272 struct ip_fw_chain *ch; member
283 struct ip_fw_chain *ch; in unref_table_value_cb() local
290 ta = fa->ta; in unref_table_value_cb()
291 memset(&fa->tent, 0, sizeof(fa->tent)); in unref_table_value_cb()
292 tent = &fa->tent; in unref_table_value_cb()
293 error = ta->dump_tentry(fa->astate, fa->ti, e, tent); in unref_table_value_cb()
297 ch = fa->ch; in unref_table_value_cb()
299 unref_table_value(CHAIN_TO_VI(ch), in unref_table_value_cb()
300 (struct table_value *)ch->valuestate, tent->v.kidx); in unref_table_value_cb()
309 ipfw_unref_table_values(struct ip_fw_chain *ch, struct table_config *tc, in ipfw_unref_table_values() argument
314 IPFW_UH_WLOCK_ASSERT(ch); in ipfw_unref_table_values()
317 fa.ch = ch; in ipfw_unref_table_values()
322 ta->foreach(astate, ti, unref_table_value_cb, &fa); in ipfw_unref_table_values()
328 * may lead to inconsistencies in on-going table data addition.
331 * and set "modified" field to non-zero value to indicate
337 struct ip_fw_chain *ch; in rollback_table_values() local
343 ch = ts->ch; in rollback_table_values()
345 IPFW_UH_WLOCK_ASSERT(ch); in rollback_table_values()
348 get_value_ptrs(ch, ts->tc, ts->vshared, &pval, &vi); in rollback_table_values()
350 for (i = 0; i < ts->count; i++) { in rollback_table_values()
351 ptei = &ts->tei[i]; in rollback_table_values()
353 if (ptei->value == 0) in rollback_table_values()
356 unref_table_value(vi, pval, ptei->value); in rollback_table_values()
361 * Allocate new value index in either shared or per-table array.
367 alloc_table_vidx(struct ip_fw_chain *ch, struct tableop_state *ts, in alloc_table_vidx() argument
373 IPFW_UH_WLOCK_ASSERT(ch); in alloc_table_vidx()
382 ts->opstate.func(ts->tc, &ts->opstate); in alloc_table_vidx()
383 error = resize_shared_value_storage(ch); in alloc_table_vidx()
384 return (error); /* ts->modified should be set, we will restart */ in alloc_table_vidx()
387 vlimit = ts->ta->vlimit; in alloc_table_vidx()
392 * per-table value array or return error in alloc_table_vidx()
395 if (ts->vshared != 0) { in alloc_table_vidx()
396 /* shared -> per-table */ in alloc_table_vidx()
400 /* per-table. Fail for now. */ in alloc_table_vidx()
413 ipfw_garbage_table_values(struct ip_fw_chain *ch, struct table_config *tc, in ipfw_garbage_table_values() argument
435 * we simply unref all non-zero values. in ipfw_garbage_table_values()
442 get_value_ptrs(ch, tc, 1, &pval, &vi); in ipfw_garbage_table_values()
447 if (ptei->value == 0) { in ipfw_garbage_table_values()
449 * We may be deleting non-existing record. in ipfw_garbage_table_values()
455 if ((ptei->flags & TEI_FLAGS_ADDED) != 0 && rollback == 0) { in ipfw_garbage_table_values()
456 ptei->value = 0; in ipfw_garbage_table_values()
460 unref_table_value(vi, pval, ptei->value); in ipfw_garbage_table_values()
461 ptei->value = 0; in ipfw_garbage_table_values()
473 ipfw_link_table_values(struct ip_fw_chain *ch, struct tableop_state *ts, in ipfw_link_table_values() argument
488 IPFW_UH_WLOCK_ASSERT(ch); in ipfw_link_table_values()
489 get_value_ptrs(ch, ts->tc, ts->vshared, &pval, &vi); in ipfw_link_table_values()
493 vlimit = ts->ta->vlimit; in ipfw_link_table_values()
495 tc = ts->tc; in ipfw_link_table_values()
496 tei = ts->tei; in ipfw_link_table_values()
497 count = ts->count; in ipfw_link_table_values()
500 ptei->value = 0; /* Ensure value is always 0 in the beginning */ in ipfw_link_table_values()
501 mask_table_value(ptei->pvalue, &tval, ts->vmask); in ipfw_link_table_values()
507 if (vlimit > 0 && vlimit <= ptv->no.kidx) in ipfw_link_table_values()
511 ptv->pval->refcnt++; in ipfw_link_table_values()
512 ptei->value = ptv->no.kidx; in ipfw_link_table_values()
516 if (ts->count == found) { in ipfw_link_table_values()
525 add_toperation_state(ch, ts); in ipfw_link_table_values()
528 IPFW_UH_WUNLOCK(ch); in ipfw_link_table_values()
531 * Stage 2: allocate objects for non-existing values. in ipfw_link_table_values()
535 if (ptei->value != 0) in ipfw_link_table_values()
537 if (ptei->ptv != NULL) in ipfw_link_table_values()
539 ptei->ptv = malloc(sizeof(struct table_val_link), M_IPFW, in ipfw_link_table_values()
547 IPFW_UH_WLOCK(ch); in ipfw_link_table_values()
549 del_toperation_state(ch, ts); in ipfw_link_table_values()
550 if (ts->modified != 0) { in ipfw_link_table_values()
559 KASSERT(pval == ch->valuestate, ("resize_storage() notify failure")); in ipfw_link_table_values()
566 mask_table_value(ptei->pvalue, &tval, ts->vmask); in ipfw_link_table_values()
570 ptv->pval->refcnt++; in ipfw_link_table_values()
571 ptei->value = ptv->no.kidx; in ipfw_link_table_values()
576 error = alloc_table_vidx(ch, ts, vi, &vidx, flags); in ipfw_link_table_values()
578 ts->opstate.func(ts->tc, &ts->opstate); in ipfw_link_table_values()
582 if (ts->modified != 0) in ipfw_link_table_values()
586 ptei->value = vidx; in ipfw_link_table_values()
587 ptv = (struct table_val_link *)ptei->ptv; in ipfw_link_table_values()
588 ptei->ptv = NULL; in ipfw_link_table_values()
590 ptv->no.kidx = vidx; in ipfw_link_table_values()
591 ptv->no.name = (char *)&pval[vidx]; in ipfw_link_table_values()
592 ptv->pval = &pval[vidx]; in ipfw_link_table_values()
593 memcpy(ptv->pval, &tval, sizeof(struct table_value)); in ipfw_link_table_values()
595 ipfw_objhash_add(vi, &ptv->no); in ipfw_link_table_values()
611 v.tag = iv->tag; in ipfw_import_table_value_v1()
612 v.pipe = iv->pipe; in ipfw_import_table_value_v1()
613 v.divert = iv->divert; in ipfw_import_table_value_v1()
614 v.skipto = iv->skipto; in ipfw_import_table_value_v1()
615 v.netgraph = iv->netgraph; in ipfw_import_table_value_v1()
616 v.fib = iv->fib; in ipfw_import_table_value_v1()
617 v.nat = iv->nat; in ipfw_import_table_value_v1()
618 v.dscp = iv->dscp; in ipfw_import_table_value_v1()
619 v.nh4 = iv->nh4; in ipfw_import_table_value_v1()
620 v.nh6 = iv->nh6; in ipfw_import_table_value_v1()
621 v.limit = iv->limit; in ipfw_import_table_value_v1()
622 v.zoneid = iv->zoneid; in ipfw_import_table_value_v1()
623 v.mark = iv->mark; in ipfw_import_table_value_v1()
638 iv.tag = v->tag; in ipfw_export_table_value_v1()
639 iv.pipe = v->pipe; in ipfw_export_table_value_v1()
640 iv.divert = v->divert; in ipfw_export_table_value_v1()
641 iv.skipto = v->skipto; in ipfw_export_table_value_v1()
642 iv.netgraph = v->netgraph; in ipfw_export_table_value_v1()
643 iv.fib = v->fib; in ipfw_export_table_value_v1()
644 iv.nat = v->nat; in ipfw_export_table_value_v1()
645 iv.dscp = v->dscp; in ipfw_export_table_value_v1()
646 iv.limit = v->limit; in ipfw_export_table_value_v1()
647 iv.nh4 = v->nh4; in ipfw_export_table_value_v1()
648 iv.nh6 = v->nh6; in ipfw_export_table_value_v1()
649 iv.zoneid = v->zoneid; in ipfw_export_table_value_v1()
650 iv.mark = v->mark; in ipfw_export_table_value_v1()
668 v = (ipfw_table_value *)ipfw_get_sopt_space(da->sd, sizeof(*v)); in dump_tvalue()
671 da->error = ENOMEM; in dump_tvalue()
675 ipfw_export_table_value_v1(ptv->pval, v); in dump_tvalue()
676 v->refcnt = ptv->pval->refcnt; in dump_tvalue()
677 v->kidx = ptv->no.kidx; in dump_tvalue()
690 list_table_values(struct ip_fw_chain *ch, ip_fw3_opheader *op3, in list_table_values() argument
701 if (sd->valsize < olh->size) in list_table_values()
704 IPFW_UH_RLOCK(ch); in list_table_values()
705 vi = CHAIN_TO_VI(ch); in list_table_values()
711 olh->count = count; in list_table_values()
712 olh->objsize = sizeof(ipfw_table_value); in list_table_values()
714 if (size > olh->size) { in list_table_values()
715 olh->size = size; in list_table_values()
716 IPFW_UH_RUNLOCK(ch); in list_table_values()
719 olh->size = size; in list_table_values()
725 da.ch = ch; in list_table_values()
729 IPFW_UH_RUNLOCK(ch); in list_table_values()
735 ipfw_table_value_init(struct ip_fw_chain *ch, int first) in ipfw_table_value_init() argument
739 ch->valuestate = malloc(VALDATA_START_SIZE * sizeof(struct table_value), in ipfw_table_value_init()
742 tcfg = ch->tblcfg; in ipfw_table_value_init()
744 tcfg->val_size = VALDATA_START_SIZE; in ipfw_table_value_init()
745 tcfg->valhash = ipfw_objhash_create(tcfg->val_size, VALDATA_HASH_SIZE); in ipfw_table_value_init()
746 ipfw_objhash_set_funcs(tcfg->valhash, hash_table_value, in ipfw_table_value_init()
762 ipfw_table_value_destroy(struct ip_fw_chain *ch, int last) in ipfw_table_value_destroy() argument
767 free(ch->valuestate, M_IPFW); in ipfw_table_value_destroy()
768 ipfw_objhash_foreach(CHAIN_TO_VI(ch), destroy_value, ch); in ipfw_table_value_destroy()
769 ipfw_objhash_destroy(CHAIN_TO_VI(ch)); in ipfw_table_value_destroy()