* Decompose multipath cmd info @rc into a list of add/del/change * single-path operations, calling @cb callback for each operation. * Assumes at least one of the nexthops in @rc is multipath. */
| 344 | * Assumes at least one of the nexthops in @rc is multipath. |
| 345 | */ |
| 346 | void |
| 347 | rib_decompose_notification(struct rib_cmd_info *rc, route_notification_t *cb, |
| 348 | void *cbdata) |
| 349 | { |
| 350 | struct weightened_nhop *wn; |
| 351 | uint32_t num_nhops; |
| 352 | struct rib_cmd_info rc_new; |
| 353 | |
| 354 | rc_new = *rc; |
| 355 | DPRINTF("cb=%p cmd=%d nh_old=%p nh_new=%p", |
| 356 | cb, rc->cmd, rc->nh_old, rc->nh_new); |
| 357 | switch (rc->rc_cmd) { |
| 358 | case RTM_ADD: |
| 359 | if (!NH_IS_NHGRP(rc->rc_nh_new)) |
| 360 | return; |
| 361 | wn = nhgrp_get_nhops((struct nhgrp_object *)rc->rc_nh_new, &num_nhops); |
| 362 | for (uint32_t i = 0; i < num_nhops; i++) { |
| 363 | rc_new.rc_nh_new = wn[i].nh; |
| 364 | rc_new.rc_nh_weight = wn[i].weight; |
| 365 | cb(&rc_new, cbdata); |
| 366 | } |
| 367 | break; |
| 368 | case RTM_DELETE: |
| 369 | if (!NH_IS_NHGRP(rc->rc_nh_old)) |
| 370 | return; |
| 371 | wn = nhgrp_get_nhops((struct nhgrp_object *)rc->rc_nh_old, &num_nhops); |
| 372 | for (uint32_t i = 0; i < num_nhops; i++) { |
| 373 | rc_new.rc_nh_old = wn[i].nh; |
| 374 | rc_new.rc_nh_weight = wn[i].weight; |
| 375 | cb(&rc_new, cbdata); |
| 376 | } |
| 377 | break; |
| 378 | case RTM_CHANGE: |
| 379 | if (!NH_IS_NHGRP(rc->rc_nh_old) && !NH_IS_NHGRP(rc->rc_nh_new)) |
| 380 | return; |
| 381 | decompose_change_notification(rc, cb, cbdata); |
| 382 | break; |
| 383 | } |
| 384 | } |
| 385 | #endif |
no test coverage detected