* Switch @rt nhop/weigh to the ones specified in @rnd. * Conditionally set rt_expire if set in @info. * Returns 0 on success. */
| 1097 | * Returns 0 on success. |
| 1098 | */ |
| 1099 | int |
| 1100 | change_route_nhop(struct rib_head *rnh, struct rtentry *rt, |
| 1101 | struct rt_addrinfo *info, struct route_nhop_data *rnd, |
| 1102 | struct rib_cmd_info *rc) |
| 1103 | { |
| 1104 | struct nhop_object *nh_orig; |
| 1105 | |
| 1106 | RIB_WLOCK_ASSERT(rnh); |
| 1107 | |
| 1108 | nh_orig = rt->rt_nhop; |
| 1109 | |
| 1110 | if (rnd->rnd_nhop != NULL) { |
| 1111 | /* Changing expiration & nexthop & weight to a new one */ |
| 1112 | rt_set_expire_info(rt, info); |
| 1113 | rt->rt_nhop = rnd->rnd_nhop; |
| 1114 | rt->rt_weight = rnd->rnd_weight; |
| 1115 | if (rt->rt_expire > 0) |
| 1116 | tmproutes_update(rnh, rt); |
| 1117 | } else { |
| 1118 | /* Route deletion requested. */ |
| 1119 | struct sockaddr *ndst, *netmask; |
| 1120 | struct radix_node *rn; |
| 1121 | |
| 1122 | ndst = (struct sockaddr *)rt_key(rt); |
| 1123 | netmask = info->rti_info[RTAX_NETMASK]; |
| 1124 | rn = rnh->rnh_deladdr(ndst, netmask, &rnh->head); |
| 1125 | if (rn == NULL) |
| 1126 | return (ESRCH); |
| 1127 | rt = RNTORT(rn); |
| 1128 | rt->rte_flags &= ~RTF_UP; |
| 1129 | } |
| 1130 | |
| 1131 | /* Finalize notification */ |
| 1132 | rnh->rnh_gen++; |
| 1133 | if (rnd->rnd_nhop == NULL) |
| 1134 | rnh->rnh_prefixes--; |
| 1135 | |
| 1136 | rc->rc_cmd = (rnd->rnd_nhop != NULL) ? RTM_CHANGE : RTM_DELETE; |
| 1137 | rc->rc_rt = rt; |
| 1138 | rc->rc_nh_old = nh_orig; |
| 1139 | rc->rc_nh_new = rnd->rnd_nhop; |
| 1140 | rc->rc_nh_weight = rnd->rnd_weight; |
| 1141 | |
| 1142 | rib_notify(rnh, RIB_NOTIFY_IMMEDIATE, rc); |
| 1143 | |
| 1144 | return (0); |
| 1145 | } |
| 1146 | |
| 1147 | /* |
| 1148 | * Conditionally update route nhop/weight IFF data in @nhd_orig is |
no test coverage detected