* Lookup and destroy a clone network interface. */
| 255 | * Lookup and destroy a clone network interface. |
| 256 | */ |
| 257 | int |
| 258 | if_clone_destroy(const char *name) |
| 259 | { |
| 260 | int err; |
| 261 | struct if_clone *ifc; |
| 262 | struct ifnet *ifp; |
| 263 | |
| 264 | ifp = ifunit_ref(name); |
| 265 | if (ifp == NULL) |
| 266 | return (ENXIO); |
| 267 | |
| 268 | /* Find the cloner for this interface */ |
| 269 | IF_CLONERS_LOCK(); |
| 270 | LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { |
| 271 | if (strcmp(ifc->ifc_name, ifp->if_dname) == 0) { |
| 272 | break; |
| 273 | } |
| 274 | } |
| 275 | #ifdef VIMAGE |
| 276 | if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) { |
| 277 | CURVNET_SET_QUIET(vnet0); |
| 278 | LIST_FOREACH(ifc, &V_if_cloners, ifc_list) |
| 279 | if (ifc->ifc_type == SIMPLE) { |
| 280 | if (ifc_simple_match(ifc, name)) |
| 281 | break; |
| 282 | } else { |
| 283 | if (ifc->ifc_match(ifc, name)) |
| 284 | break; |
| 285 | } |
| 286 | CURVNET_RESTORE(); |
| 287 | } |
| 288 | #endif |
| 289 | IF_CLONERS_UNLOCK(); |
| 290 | if (ifc == NULL) { |
| 291 | if_rele(ifp); |
| 292 | return (EINVAL); |
| 293 | } |
| 294 | |
| 295 | err = if_clone_destroyif(ifc, ifp); |
| 296 | if_rele(ifp); |
| 297 | return err; |
| 298 | } |
| 299 | |
| 300 | /* |
| 301 | * Destroy a clone network interface. |
no test coverage detected