* Tries to create new algo instance based on @fd data. * Returns true on success. */
| 1054 | * Returns true on success. |
| 1055 | */ |
| 1056 | static bool |
| 1057 | rebuild_fd(struct fib_data *fd) |
| 1058 | { |
| 1059 | struct fib_data *fd_new, *fd_tmp; |
| 1060 | struct fib_lookup_module *flm_new = NULL; |
| 1061 | enum flm_op_result result; |
| 1062 | bool need_rebuild = false; |
| 1063 | |
| 1064 | NET_EPOCH_ASSERT(); |
| 1065 | RIB_WLOCK_ASSERT(fd->fd_rh); |
| 1066 | |
| 1067 | need_rebuild = fd->fd_need_rebuild; |
| 1068 | fd->fd_need_rebuild = false; |
| 1069 | fd->fd_force_eval = false; |
| 1070 | fd->fd_num_changes = 0; |
| 1071 | |
| 1072 | /* First, check if we're still OK to use this algo */ |
| 1073 | if (!is_algo_fixed(fd->fd_rh)) |
| 1074 | flm_new = fib_check_best_algo(fd->fd_rh, fd->fd_flm); |
| 1075 | if ((flm_new == NULL) && (!need_rebuild)) { |
| 1076 | /* Keep existing algo, no need to rebuild. */ |
| 1077 | return (true); |
| 1078 | } |
| 1079 | |
| 1080 | if (flm_new == NULL) { |
| 1081 | flm_new = fd->fd_flm; |
| 1082 | fd_tmp = fd; |
| 1083 | } else { |
| 1084 | fd_tmp = NULL; |
| 1085 | FD_PRINTF(LOG_NOTICE, fd, "switching algo to %s", flm_new->flm_name); |
| 1086 | } |
| 1087 | result = setup_fd_instance(flm_new, fd->fd_rh, fd_tmp, &fd_new, true); |
| 1088 | if (fd_tmp == NULL) { |
| 1089 | /* fd_new represents new algo */ |
| 1090 | fib_unref_algo(flm_new); |
| 1091 | } |
| 1092 | if (result != FLM_SUCCESS) { |
| 1093 | FD_PRINTF(LOG_NOTICE, fd, "table rebuild failed"); |
| 1094 | return (false); |
| 1095 | } |
| 1096 | FD_PRINTF(LOG_INFO, fd_new, "switched to new instance"); |
| 1097 | |
| 1098 | /* Remove old instance */ |
| 1099 | schedule_destroy_fd_instance(fd, true); |
| 1100 | |
| 1101 | return (true); |
| 1102 | } |
| 1103 | |
| 1104 | /* |
| 1105 | * Finds algo by name/family. |
no test coverage detected