* Allocates new nexthop group for the list of weightened nexthops. * Assume sorted list. * Does NOT reference any nexthops in the group. * Returns group with refcount=1 or NULL. */
| 252 | * Returns group with refcount=1 or NULL. |
| 253 | */ |
| 254 | static struct nhgrp_priv * |
| 255 | alloc_nhgrp(struct weightened_nhop *wn, int num_nhops) |
| 256 | { |
| 257 | uint32_t nhgrp_size; |
| 258 | int flags = M_NOWAIT; |
| 259 | struct nhgrp_object *nhg; |
| 260 | struct nhgrp_priv *nhg_priv; |
| 261 | |
| 262 | nhgrp_size = calc_min_mpath_slots(wn, num_nhops); |
| 263 | if (nhgrp_size == 0) { |
| 264 | /* Zero weights, abort */ |
| 265 | return (NULL); |
| 266 | } |
| 267 | |
| 268 | size_t sz = get_nhgrp_alloc_size(nhgrp_size, num_nhops); |
| 269 | nhg = malloc(sz, M_NHOP, flags | M_ZERO); |
| 270 | if (nhg == NULL) { |
| 271 | return (NULL); |
| 272 | } |
| 273 | |
| 274 | /* Has to be the first to make NHGRP_PRIV() work */ |
| 275 | nhg->nhg_size = nhgrp_size; |
| 276 | DPRINTF("new mpath group: num_nhops: %u", (uint32_t)nhgrp_size); |
| 277 | nhg->nhg_flags = MPF_MULTIPATH; |
| 278 | |
| 279 | nhg_priv = NHGRP_PRIV(nhg); |
| 280 | nhg_priv->nhg_nh_count = num_nhops; |
| 281 | refcount_init(&nhg_priv->nhg_refcount, 1); |
| 282 | |
| 283 | /* Please see nhgrp_free() comments on the initial value */ |
| 284 | refcount_init(&nhg_priv->nhg_linked, 2); |
| 285 | |
| 286 | nhg_priv->nhg = nhg; |
| 287 | memcpy(&nhg_priv->nhg_nh_weights[0], wn, |
| 288 | num_nhops * sizeof(struct weightened_nhop)); |
| 289 | |
| 290 | compile_nhgrp(nhg_priv, wn, nhg->nhg_size); |
| 291 | |
| 292 | return (nhg_priv); |
| 293 | } |
| 294 | |
| 295 | void |
| 296 | nhgrp_ref_object(struct nhgrp_object *nhg) |
no test coverage detected