Lines Matching +full:ref +full:- +full:weight

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
91 uint32_t a_idx = w_a->nh->nh_priv->nh_idx; in wn_cmp_idx()
92 uint32_t b_idx = w_b->nh->nh_priv->nh_idx; in wn_cmp_idx()
95 return (-1); in wn_cmp_idx()
103 * Perform in-place sorting for array of nexthops in @wn.
114 * In order to determine the minimum weight difference in the array
123 wn[0].storage = wn[0].weight; in sort_weightened_nhops_weights()
125 uint32_t weight = wn[i].weight; // read from 'weight' as it's not reordered in sort_weightened_nhops_weights() local
126 /* Move all weights > weight 1 position right */ in sort_weightened_nhops_weights()
127 for (j = i - 1; j >= 0 && wn[j].storage > weight; j--) in sort_weightened_nhops_weights()
129 wn[j + 1].storage = weight; in sort_weightened_nhops_weights()
137 * Assumes @wn is sorted by weight ascending and each weight is > 0.
141 * note: (i, X) pair means (nhop=i, weight=X):
142 * (1, 1) (2, 2) -> 3 slots [1, 2, 2]
143 * (1, 100), (2, 200) -> 3 slots [1, 2, 2]
144 * (1, 100), (2, 200), (3, 400) -> 7 slots [1, 2, 2, 3, 3, 3]
161 ((wn[i].storage - last < xmin) || xmin == 0)) { in calc_min_mpath_slots_fast()
162 xmin = wn[i].storage - last; in calc_min_mpath_slots_fast()
171 if ((wn[i].weight % xmin) != 0) in calc_min_mpath_slots_fast()
180 * set of weights while maintaining weight coefficients.
182 * Assume @wn is sorted by weight ascending and each weight is > 0.
242 dst = dst_priv->nhg; in compile_nhgrp()
245 for (i = 0; i < dst_priv->nhg_nh_count; i++) in compile_nhgrp()
246 remaining_sum += x[i].weight; in compile_nhgrp()
250 for (i = 0; i < dst_priv->nhg_nh_count; i++) { in compile_nhgrp()
253 nh_weight = (uint64_t)x[i].weight; in compile_nhgrp()
258 remaining_sum -= x[i].weight; in compile_nhgrp()
259 remaining_slots -= nh_slots; in compile_nhgrp()
267 while (nh_slots-- > 0) in compile_nhgrp()
268 dst->nhops[slot_idx++] = x[i].nh; in compile_nhgrp()
301 nhg->nhg_size = nhgrp_size; in alloc_nhgrp()
302 nhg->nhg_flags = MPF_MULTIPATH; in alloc_nhgrp()
305 nhg_priv->nhg_nh_count = num_nhops; in alloc_nhgrp()
306 refcount_init(&nhg_priv->nhg_refcount, 1); in alloc_nhgrp()
309 refcount_init(&nhg_priv->nhg_linked, 2); in alloc_nhgrp()
311 nhg_priv->nhg = nhg; in alloc_nhgrp()
312 memcpy(&nhg_priv->nhg_nh_weights[0], wn, in alloc_nhgrp()
318 compile_nhgrp(nhg_priv, wn, nhg->nhg_size); in alloc_nhgrp()
330 old = refcount_acquire(&nhg_priv->nhg_refcount); in nhgrp_ref_object()
343 if (!refcount_release(&nhg_priv->nhg_refcount)) in nhgrp_free()
373 if (refcount_release_if_not_last(&nhg_priv->nhg_linked)) { in nhgrp_free()
374 ctl = nhg_priv->nh_control; in nhgrp_free()
382 MPASS((nhg_priv->nhg_idx == 0)); in nhgrp_free()
383 MPASS((nhg_priv->nhg_refcount == 0)); in nhgrp_free()
387 NET_EPOCH_CALL(destroy_nhgrp_epoch, &nhg_priv->nhg_epoch_ctx); in nhgrp_free()
397 free(nhg_priv->nhg, M_NHOP); in destroy_nhgrp_int()
405 FIB_NH_LOG(LOG_DEBUG2, nhg_priv->nhg_nh_weights[0].nh, in destroy_nhgrp()
406 "destroying %s", nhgrp_print_buf(nhg_priv->nhg, in destroy_nhgrp()
431 for (int i = 0; i < nhg_priv->nhg_nh_count; i++) { in ref_nhgrp_nhops()
432 if (nhop_try_ref_object(nhg_priv->nhg_nh_weights[i].nh) != 0) in ref_nhgrp_nhops()
436 * Failed to ref the nexthop, b/c it's deleted. in ref_nhgrp_nhops()
440 nhop_free(nhg_priv->nhg_nh_weights[j].nh); in ref_nhgrp_nhops()
451 for (int i = 0; i < nhg_priv->nhg_nh_count; i++) in free_nhgrp_nhops()
452 nhop_free(nhg_priv->nhg_nh_weights[i].nh); in free_nhgrp_nhops()
458 * Returns unlinked nhgrp object on success or NULL and non-zero perror.
473 ctl = rh->nh_control; in nhgrp_alloc()
480 if (ctl->gr_head.hash_size == 0) { in nhgrp_alloc()
492 if (wn[i].nh->nh_priv->nh_control != ctl) { in nhgrp_alloc()
496 if (wn[i].nh->nh_priv->nh_idx == last_id) { in nhgrp_alloc()
500 last_id = wn[i].nh->nh_priv->nh_idx; in nhgrp_alloc()
507 nhg_priv->nh_control = ctl; in nhgrp_alloc()
510 return (nhg_priv->nhg); in nhgrp_alloc()
515 * Returns the referenced group or NULL and non-zero @perror.
521 struct nh_control *ctl = key->nh_control; in nhgrp_get_nhgrp()
526 * Free originally-created group. As it hasn't been linked in nhgrp_get_nhgrp()
532 return (nhg_priv->nhg); in nhgrp_get_nhgrp()
570 nhg = nhgrp_alloc(ctl->ctl_rh->rib_fibnum, ctl->ctl_rh->rib_family, in get_nhgrp()
603 curr_nhops = src_priv->nhg_nh_count; in append_nhops()
607 sz = (src_priv->nhg_nh_count + num_nhops) * (sizeof(struct weightened_nhop)); in append_nhops()
620 memcpy(pnhops, src_priv->nhg_nh_weights, in append_nhops()
648 struct nh_control *ctl = rh->nh_control; in nhgrp_get_group()
654 *pnhg = nhg_priv->nhg; in nhgrp_get_group()
670 struct nh_control *ctl = rh->nh_control; in nhgrp_get_filtered_group()
678 sz = src_priv->nhg_nh_count * (sizeof(struct weightened_nhop)); in nhgrp_get_filtered_group()
690 for (i = 0; i < src_priv->nhg_nh_count; i++) { in nhgrp_get_filtered_group()
691 if (flt_func(rt, src_priv->nhg_nh_weights[i].nh, flt_data)) in nhgrp_get_filtered_group()
693 memcpy(&pnhops[num_nhops++], &src_priv->nhg_nh_weights[i], in nhgrp_get_filtered_group()
698 rnd->rnd_nhgrp = NULL; in nhgrp_get_filtered_group()
699 rnd->rnd_weight = 0; in nhgrp_get_filtered_group()
701 rnd->rnd_nhop = pnhops[0].nh; in nhgrp_get_filtered_group()
702 rnd->rnd_weight = pnhops[0].weight; in nhgrp_get_filtered_group()
703 if (nhop_try_ref_object(rnd->rnd_nhop) == 0) in nhgrp_get_filtered_group()
708 rnd->rnd_nhgrp = mp_priv->nhg; in nhgrp_get_filtered_group()
709 rnd->rnd_weight = 0; in nhgrp_get_filtered_group()
720 * to-be-added nhop @wn_add.
727 struct nh_control *ctl = rh->nh_control; in nhgrp_get_addition_group()
732 if (rnd_orig->rnd_nhop == NULL) { in nhgrp_get_addition_group()
735 if (nhop_try_ref_object(rnd_new->rnd_nhop) == 0) in nhgrp_get_addition_group()
740 wn[0].nh = rnd_add->rnd_nhop; in nhgrp_get_addition_group()
741 wn[0].weight = rnd_add->rnd_weight; in nhgrp_get_addition_group()
743 if (!NH_IS_NHGRP(rnd_orig->rnd_nhop)) { in nhgrp_get_addition_group()
744 /* Simple merge of 2 non-multipath nexthops */ in nhgrp_get_addition_group()
745 wn[1].nh = rnd_orig->rnd_nhop; in nhgrp_get_addition_group()
746 wn[1].weight = rnd_orig->rnd_weight; in nhgrp_get_addition_group()
749 /* Get new nhop group with @rt->rt_nhop as an additional nhop */ in nhgrp_get_addition_group()
750 nhg_priv = append_nhops(ctl, rnd_orig->rnd_nhgrp, &wn[0], 1, in nhgrp_get_addition_group()
756 rnd_new->rnd_nhgrp = nhg_priv->nhg; in nhgrp_get_addition_group()
757 rnd_new->rnd_weight = 0; in nhgrp_get_addition_group()
771 KASSERT(((nhg->nhg_flags & MPF_MULTIPATH) != 0), ("nhop is not mpath")); in nhgrp_get_nhops()
774 *pnum_nhops = nhg_priv->nhg_nh_count; in nhgrp_get_nhops()
776 return (nhg_priv->nhg_nh_weights); in nhgrp_get_nhops()
784 KASSERT(((nhg->nhg_flags & MPF_MULTIPATH) != 0), ("nhop is not mpath")); in nhgrp_set_uidx()
788 nhg_priv->nhg_uidx = uidx; in nhgrp_set_uidx()
796 KASSERT(((nhg->nhg_flags & MPF_MULTIPATH) != 0), ("nhop is not mpath")); in nhgrp_get_uidx()
799 return (nhg_priv->nhg_uidx); in nhgrp_get_uidx()
812 int off = snprintf(buf, bufsize, "nhg#%u/sz=%u:[", nhg_priv->nhg_idx, in nhgrp_print_buf()
813 nhg_priv->nhg_nh_count); in nhgrp_print_buf()
815 for (int i = 0; i < nhg_priv->nhg_nh_count; i++) { in nhgrp_print_buf()
816 const struct weightened_nhop *wn = &nhg_priv->nhg_nh_weights[i]; in nhgrp_print_buf()
817 int len = snprintf(&buf[off], bufsize - off, "#%u:%u,", in nhgrp_print_buf()
818 wn->nh->nh_priv->nh_idx, wn->weight); in nhgrp_print_buf()
820 int len = snprintf(&buf[off], bufsize - off, "..."); in nhgrp_print_buf()
827 off--; // remove last "," in nhgrp_print_buf()
829 snprintf(&buf[off], bufsize - off, "]"); in nhgrp_print_buf()
845 nhg = nhg_priv->nhg; in dump_nhgrp_entry()
850 sz += sizeof(struct nhgrp_nhop_external) * nhg_priv->nhg_nh_count; in dump_nhgrp_entry()
853 sz += sizeof(struct nhgrp_nhop_external) * nhg->nhg_size; in dump_nhgrp_entry()
860 rtm->rtm_msglen = sz; in dump_nhgrp_entry()
861 rtm->rtm_version = RTM_VERSION; in dump_nhgrp_entry()
862 rtm->rtm_type = RTM_GET; in dump_nhgrp_entry()
866 nhge->nhg_idx = nhg_priv->nhg_idx; in dump_nhgrp_entry()
867 nhge->nhg_refcount = nhg_priv->nhg_refcount; in dump_nhgrp_entry()
871 nhgc->nhgc_type = NHG_C_TYPE_CNHOPS; in dump_nhgrp_entry()
872 nhgc->nhgc_subtype = 0; in dump_nhgrp_entry()
873 nhgc->nhgc_len = sizeof(struct nhgrp_container); in dump_nhgrp_entry()
874 nhgc->nhgc_len += sizeof(struct nhgrp_nhop_external) * nhg_priv->nhg_nh_count; in dump_nhgrp_entry()
875 nhgc->nhgc_count = nhg_priv->nhg_nh_count; in dump_nhgrp_entry()
878 for (int i = 0; i < nhg_priv->nhg_nh_count; i++) { in dump_nhgrp_entry()
879 ext[i].nh_idx = nhg_priv->nhg_nh_weights[i].nh->nh_priv->nh_idx; in dump_nhgrp_entry()
880 ext[i].nh_weight = nhg_priv->nhg_nh_weights[i].weight; in dump_nhgrp_entry()
884 nhgc = (struct nhgrp_container *)(&ext[nhg_priv->nhg_nh_count]); in dump_nhgrp_entry()
885 nhgc->nhgc_type = NHG_C_TYPE_DNHOPS; in dump_nhgrp_entry()
886 nhgc->nhgc_subtype = 0; in dump_nhgrp_entry()
887 nhgc->nhgc_len = sizeof(struct nhgrp_container); in dump_nhgrp_entry()
888 nhgc->nhgc_len += sizeof(struct nhgrp_nhop_external) * nhg->nhg_size; in dump_nhgrp_entry()
889 nhgc->nhgc_count = nhg->nhg_size; in dump_nhgrp_entry()
892 for (int i = 0; i < nhg->nhg_size; i++) { in dump_nhgrp_entry()
893 ext[i].nh_idx = nhg->nhops[i]->nh_priv->nh_idx; in dump_nhgrp_entry()
908 return (nhg_priv->nhg_idx); in nhgrp_get_idx()
914 return (NHGRP_PRIV_CONST(nhg)->nhg_origin); in nhgrp_get_origin()
920 NHGRP_PRIV(nhg)->nhg_origin = origin; in nhgrp_set_origin()
929 ctl = rh->nh_control; in nhgrp_get_count()
932 count = ctl->gr_head.items_count; in nhgrp_get_count()
941 struct nh_control *ctl = rh->nh_control; in nhgrp_dump_sysctl()
948 if (ctl->gr_head.items_count == 0) in nhgrp_dump_sysctl()
961 CHT_SLIST_FOREACH(&ctl->gr_head, mpath, nhg_priv) { in nhgrp_dump_sysctl()