| 961 | |
| 962 | #ifdef ROUTE_MPATH |
| 963 | static int |
| 964 | change_mpath_route(struct rib_head *rnh, struct rt_addrinfo *info, |
| 965 | struct route_nhop_data *rnd_orig, struct rib_cmd_info *rc) |
| 966 | { |
| 967 | int error = 0; |
| 968 | struct nhop_object *nh, *nh_orig, *nh_new; |
| 969 | struct route_nhop_data rnd_new; |
| 970 | |
| 971 | nh = NULL; |
| 972 | nh_orig = rnd_orig->rnd_nhop; |
| 973 | |
| 974 | struct weightened_nhop *wn = NULL, *wn_new; |
| 975 | uint32_t num_nhops; |
| 976 | |
| 977 | wn = nhgrp_get_nhops((struct nhgrp_object *)nh_orig, &num_nhops); |
| 978 | nh_orig = NULL; |
| 979 | for (int i = 0; i < num_nhops; i++) { |
| 980 | if (check_info_match_nhop(info, NULL, wn[i].nh)) { |
| 981 | nh_orig = wn[i].nh; |
| 982 | break; |
| 983 | } |
| 984 | } |
| 985 | |
| 986 | if (nh_orig == NULL) |
| 987 | return (ESRCH); |
| 988 | |
| 989 | error = change_nhop(rnh, info, nh_orig, &nh_new); |
| 990 | if (error != 0) |
| 991 | return (error); |
| 992 | |
| 993 | wn_new = mallocarray(num_nhops, sizeof(struct weightened_nhop), |
| 994 | M_TEMP, M_NOWAIT | M_ZERO); |
| 995 | if (wn_new == NULL) { |
| 996 | nhop_free(nh_new); |
| 997 | return (EAGAIN); |
| 998 | } |
| 999 | |
| 1000 | memcpy(wn_new, wn, num_nhops * sizeof(struct weightened_nhop)); |
| 1001 | for (int i = 0; i < num_nhops; i++) { |
| 1002 | if (wn[i].nh == nh_orig) { |
| 1003 | wn[i].nh = nh_new; |
| 1004 | wn[i].weight = get_info_weight(info, rnd_orig->rnd_weight); |
| 1005 | break; |
| 1006 | } |
| 1007 | } |
| 1008 | |
| 1009 | error = nhgrp_get_group(rnh, wn_new, num_nhops, &rnd_new); |
| 1010 | nhop_free(nh_new); |
| 1011 | free(wn_new, M_TEMP); |
| 1012 | |
| 1013 | if (error != 0) |
| 1014 | return (error); |
| 1015 | |
| 1016 | error = change_route_conditional(rnh, NULL, info, rnd_orig, &rnd_new, rc); |
| 1017 | |
| 1018 | return (error); |
| 1019 | } |
| 1020 | #endif |
no test coverage detected