* The vmove flag, if set, indicates that we are called from a callpath * that is moving an interface to a different vnet instance. * * The shutdown flag, if set, indicates that we are called in the * process of shutting down a vnet instance. Currently only the * vnet_if_return SYSUNINIT function sets it. Note: we can be called * on a vnet instance shutdown without this flag being set, e.g.
| 1141 | * the cloned interfaces are destoyed as first thing of teardown. |
| 1142 | */ |
| 1143 | static int |
| 1144 | if_detach_internal(struct ifnet *ifp, int vmove, struct if_clone **ifcp) |
| 1145 | { |
| 1146 | struct ifaddr *ifa; |
| 1147 | int i; |
| 1148 | struct domain *dp; |
| 1149 | #ifdef VIMAGE |
| 1150 | bool shutdown; |
| 1151 | |
| 1152 | shutdown = VNET_IS_SHUTTING_DOWN(ifp->if_vnet); |
| 1153 | #endif |
| 1154 | |
| 1155 | /* |
| 1156 | * At this point we know the interface still was on the ifnet list |
| 1157 | * and we removed it so we are in a stable state. |
| 1158 | */ |
| 1159 | epoch_wait_preempt(net_epoch_preempt); |
| 1160 | |
| 1161 | /* |
| 1162 | * Ensure all pending EPOCH(9) callbacks have been executed. This |
| 1163 | * fixes issues about late destruction of multicast options |
| 1164 | * which lead to leave group calls, which in turn access the |
| 1165 | * belonging ifnet structure: |
| 1166 | */ |
| 1167 | epoch_drain_callbacks(net_epoch_preempt); |
| 1168 | |
| 1169 | /* |
| 1170 | * In any case (destroy or vmove) detach us from the groups |
| 1171 | * and remove/wait for pending events on the taskq. |
| 1172 | * XXX-BZ in theory an interface could still enqueue a taskq change? |
| 1173 | */ |
| 1174 | if_delgroups(ifp); |
| 1175 | |
| 1176 | taskqueue_drain(taskqueue_swi, &ifp->if_linktask); |
| 1177 | taskqueue_drain(taskqueue_swi, &ifp->if_addmultitask); |
| 1178 | |
| 1179 | /* |
| 1180 | * Check if this is a cloned interface or not. Must do even if |
| 1181 | * shutting down as a if_vmove_reclaim() would move the ifp and |
| 1182 | * the if_clone_addgroup() will have a corrupted string overwise |
| 1183 | * from a gibberish pointer. |
| 1184 | */ |
| 1185 | if (vmove && ifcp != NULL) |
| 1186 | *ifcp = if_clone_findifc(ifp); |
| 1187 | |
| 1188 | if_down(ifp); |
| 1189 | |
| 1190 | #ifdef VIMAGE |
| 1191 | /* |
| 1192 | * On VNET shutdown abort here as the stack teardown will do all |
| 1193 | * the work top-down for us. |
| 1194 | */ |
| 1195 | if (shutdown) { |
| 1196 | /* Give interface users the chance to clean up. */ |
| 1197 | EVENTHANDLER_INVOKE(ifnet_departure_event, ifp); |
| 1198 | |
| 1199 | /* |
| 1200 | * In case of a vmove we are done here without error. |
no test coverage detected