* Conditionally update route nhop/weight IFF data in @nhd_orig is * consistent with the current route data. * Nexthop in @nhd_new is consumed. */
| 1150 | * Nexthop in @nhd_new is consumed. |
| 1151 | */ |
| 1152 | int |
| 1153 | change_route_conditional(struct rib_head *rnh, struct rtentry *rt, |
| 1154 | struct rt_addrinfo *info, struct route_nhop_data *rnd_orig, |
| 1155 | struct route_nhop_data *rnd_new, struct rib_cmd_info *rc) |
| 1156 | { |
| 1157 | struct rtentry *rt_new; |
| 1158 | int error = 0; |
| 1159 | |
| 1160 | RIB_WLOCK(rnh); |
| 1161 | |
| 1162 | rt_new = (struct rtentry *)rnh->rnh_lookup(info->rti_info[RTAX_DST], |
| 1163 | info->rti_info[RTAX_NETMASK], &rnh->head); |
| 1164 | |
| 1165 | if (rt_new == NULL) { |
| 1166 | if (rnd_orig->rnd_nhop == NULL) |
| 1167 | error = add_route_nhop(rnh, rt, info, rnd_new, rc); |
| 1168 | else { |
| 1169 | /* |
| 1170 | * Prefix does not exist, which was not our assumption. |
| 1171 | * Update @rnd_orig with the new data and return |
| 1172 | */ |
| 1173 | rnd_orig->rnd_nhop = NULL; |
| 1174 | rnd_orig->rnd_weight = 0; |
| 1175 | error = EAGAIN; |
| 1176 | } |
| 1177 | } else { |
| 1178 | /* Prefix exists, try to update */ |
| 1179 | if (rnd_orig->rnd_nhop == rt_new->rt_nhop) { |
| 1180 | /* |
| 1181 | * Nhop/mpath group hasn't changed. Flip |
| 1182 | * to the new precalculated one and return |
| 1183 | */ |
| 1184 | error = change_route_nhop(rnh, rt_new, info, rnd_new, rc); |
| 1185 | } else { |
| 1186 | /* Update and retry */ |
| 1187 | rnd_orig->rnd_nhop = rt_new->rt_nhop; |
| 1188 | rnd_orig->rnd_weight = rt_new->rt_weight; |
| 1189 | error = EAGAIN; |
| 1190 | } |
| 1191 | } |
| 1192 | |
| 1193 | RIB_WUNLOCK(rnh); |
| 1194 | |
| 1195 | if (error == 0) { |
| 1196 | rib_notify(rnh, RIB_NOTIFY_DELAYED, rc); |
| 1197 | |
| 1198 | if (rnd_orig->rnd_nhop != NULL) |
| 1199 | nhop_free_any(rnd_orig->rnd_nhop); |
| 1200 | |
| 1201 | } else { |
| 1202 | if (rnd_new->rnd_nhop != NULL) |
| 1203 | nhop_free_any(rnd_new->rnd_nhop); |
| 1204 | } |
| 1205 | |
| 1206 | return (error); |
| 1207 | } |
| 1208 | |
| 1209 | /* |
no test coverage detected