if_clone.c (239905) | if_clone.c (241610) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org> |
|
2 * Copyright (c) 1980, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. --- 12 unchanged lines hidden (view full) --- 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)if.c 8.5 (Berkeley) 1/9/95 | 3 * Copyright (c) 1980, 1986, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. --- 12 unchanged lines hidden (view full) --- 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * @(#)if.c 8.5 (Berkeley) 1/9/95 |
30 * $FreeBSD: head/sys/net/if_clone.c 239905 2012-08-30 12:18:45Z glebius $ | 31 * $FreeBSD: head/sys/net/if_clone.c 241610 2012-10-16 13:37:54Z glebius $ |
31 */ 32 33#include <sys/param.h> 34#include <sys/malloc.h> 35#include <sys/limits.h> 36#include <sys/lock.h> 37#include <sys/mutex.h> 38#include <sys/kernel.h> 39#include <sys/systm.h> 40#include <sys/types.h> 41#include <sys/socket.h> 42 43#include <net/if.h> 44#include <net/if_clone.h> | 32 */ 33 34#include <sys/param.h> 35#include <sys/malloc.h> 36#include <sys/limits.h> 37#include <sys/lock.h> 38#include <sys/mutex.h> 39#include <sys/kernel.h> 40#include <sys/systm.h> 41#include <sys/types.h> 42#include <sys/socket.h> 43 44#include <net/if.h> 45#include <net/if_clone.h> |
45#if 0 46#include <net/if_dl.h> 47#endif 48#include <net/if_types.h> | |
49#include <net/if_var.h> 50#include <net/radix.h> 51#include <net/route.h> 52#include <net/vnet.h> 53 | 46#include <net/if_var.h> 47#include <net/radix.h> 48#include <net/route.h> 49#include <net/vnet.h> 50 |
51/* Current IF_MAXUNIT expands maximum to 5 characters. */ 52#define IFCLOSIZ (IFNAMSIZ - 5) 53 54/* 55 * Structure describing a `cloning' interface. 56 * 57 * List of locks 58 * (c) const until freeing 59 * (d) driver specific data, may need external protection. 60 * (e) locked by if_cloners_mtx 61 * (i) locked by ifc_mtx mtx 62 */ 63struct if_clone { 64 char ifc_name[IFCLOSIZ]; /* (c) Name of device, e.g. `gif' */ 65 struct unrhdr *ifc_unrhdr; /* (c) alloc_unr(9) header */ 66 int ifc_maxunit; /* (c) maximum unit number */ 67 long ifc_refcnt; /* (i) Reference count. */ 68 LIST_HEAD(, ifnet) ifc_iflist; /* (i) List of cloned interfaces */ 69 struct mtx ifc_mtx; /* Mutex to protect members. */ 70 71 enum { SIMPLE, ADVANCED } ifc_type; /* (c) */ 72 73 /* (c) Driver specific cloning functions. Called with no locks held. */ 74 union { 75 struct { /* advanced cloner */ 76 ifc_match_t *_ifc_match; 77 ifc_create_t *_ifc_create; 78 ifc_destroy_t *_ifc_destroy; 79 } A; 80 struct { /* simple cloner */ 81 ifcs_create_t *_ifcs_create; 82 ifcs_destroy_t *_ifcs_destroy; 83 int _ifcs_minifs; /* minimum ifs */ 84 85 } S; 86 } U; 87#define ifc_match U.A._ifc_match 88#define ifc_create U.A._ifc_create 89#define ifc_destroy U.A._ifc_destroy 90#define ifcs_create U.S._ifcs_create 91#define ifcs_destroy U.S._ifcs_destroy 92#define ifcs_minifs U.S._ifcs_minifs 93 94 LIST_ENTRY(if_clone) ifc_list; /* (e) On list of cloners */ 95}; 96 |
|
54static void if_clone_free(struct if_clone *ifc); 55static int if_clone_createif(struct if_clone *ifc, char *name, size_t len, 56 caddr_t params); 57 | 97static void if_clone_free(struct if_clone *ifc); 98static int if_clone_createif(struct if_clone *ifc, char *name, size_t len, 99 caddr_t params); 100 |
101static int ifc_simple_match(struct if_clone *, const char *); 102static int ifc_simple_create(struct if_clone *, char *, size_t, caddr_t); 103static int ifc_simple_destroy(struct if_clone *, struct ifnet *); 104 |
|
58static struct mtx if_cloners_mtx; 59static VNET_DEFINE(int, if_cloners_count); 60VNET_DEFINE(LIST_HEAD(, if_clone), if_cloners); 61 62#define V_if_cloners_count VNET(if_cloners_count) 63#define V_if_cloners VNET(if_cloners) 64 65#define IF_CLONERS_LOCK_INIT() \ --- 67 unchanged lines hidden (view full) --- 133 */ 134int 135if_clone_create(char *name, size_t len, caddr_t params) 136{ 137 struct if_clone *ifc; 138 139 /* Try to find an applicable cloner for this request */ 140 IF_CLONERS_LOCK(); | 105static struct mtx if_cloners_mtx; 106static VNET_DEFINE(int, if_cloners_count); 107VNET_DEFINE(LIST_HEAD(, if_clone), if_cloners); 108 109#define V_if_cloners_count VNET(if_cloners_count) 110#define V_if_cloners VNET(if_cloners) 111 112#define IF_CLONERS_LOCK_INIT() \ --- 67 unchanged lines hidden (view full) --- 180 */ 181int 182if_clone_create(char *name, size_t len, caddr_t params) 183{ 184 struct if_clone *ifc; 185 186 /* Try to find an applicable cloner for this request */ 187 IF_CLONERS_LOCK(); |
141 LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { 142 if (ifc->ifc_match(ifc, name)) { 143 break; | 188 LIST_FOREACH(ifc, &V_if_cloners, ifc_list) 189 if (ifc->ifc_type == SIMPLE) { 190 if (ifc_simple_match(ifc, name)) 191 break; 192 } else { 193 if (ifc->ifc_match(ifc, name)) 194 break; |
144 } | 195 } |
145 } | |
146#ifdef VIMAGE 147 if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) { 148 CURVNET_SET_QUIET(vnet0); | 196#ifdef VIMAGE 197 if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) { 198 CURVNET_SET_QUIET(vnet0); |
149 LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { 150 if (ifc->ifc_match(ifc, name)) 151 break; 152 } | 199 LIST_FOREACH(ifc, &V_if_cloners, ifc_list) 200 if (ifc->ifc_type == SIMPLE) { 201 if (ifc_simple_match(ifc, name)) 202 break; 203 } else { 204 if (ifc->ifc_match(ifc, name)) 205 break; 206 } |
153 CURVNET_RESTORE(); 154 } 155#endif 156 IF_CLONERS_UNLOCK(); 157 158 if (ifc == NULL) 159 return (EINVAL); 160 --- 7 unchanged lines hidden (view full) --- 168if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params) 169{ 170 int err; 171 struct ifnet *ifp; 172 173 if (ifunit(name) != NULL) 174 return (EEXIST); 175 | 207 CURVNET_RESTORE(); 208 } 209#endif 210 IF_CLONERS_UNLOCK(); 211 212 if (ifc == NULL) 213 return (EINVAL); 214 --- 7 unchanged lines hidden (view full) --- 222if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params) 223{ 224 int err; 225 struct ifnet *ifp; 226 227 if (ifunit(name) != NULL) 228 return (EEXIST); 229 |
176 err = (*ifc->ifc_create)(ifc, name, len, params); | 230 if (ifc->ifc_type == SIMPLE) 231 err = ifc_simple_create(ifc, name, len, params); 232 else 233 err = (*ifc->ifc_create)(ifc, name, len, params); |
177 178 if (!err) { 179 ifp = ifunit(name); 180 if (ifp == NULL) 181 panic("%s: lookup failed for %s", __func__, name); 182 183 if_addgroup(ifp, ifc->ifc_name); 184 --- 24 unchanged lines hidden (view full) --- 209 LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { 210 if (strcmp(ifc->ifc_name, ifp->if_dname) == 0) { 211 break; 212 } 213 } 214#ifdef VIMAGE 215 if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) { 216 CURVNET_SET_QUIET(vnet0); | 234 235 if (!err) { 236 ifp = ifunit(name); 237 if (ifp == NULL) 238 panic("%s: lookup failed for %s", __func__, name); 239 240 if_addgroup(ifp, ifc->ifc_name); 241 --- 24 unchanged lines hidden (view full) --- 266 LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { 267 if (strcmp(ifc->ifc_name, ifp->if_dname) == 0) { 268 break; 269 } 270 } 271#ifdef VIMAGE 272 if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) { 273 CURVNET_SET_QUIET(vnet0); |
217 LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { 218 if (ifc->ifc_match(ifc, name)) 219 break; 220 } | 274 LIST_FOREACH(ifc, &V_if_cloners, ifc_list) 275 if (ifc->type == SIMPLE) { 276 if (ifc_simple_match(ifc, name)) 277 break; 278 } else { 279 if (ifc->ifc_match(ifc, name)) 280 break; 281 } |
221 CURVNET_RESTORE(); 222 } 223#endif 224 IF_CLONERS_UNLOCK(); 225 if (ifc == NULL) { 226 if_rele(ifp); 227 return (EINVAL); 228 } --- 7 unchanged lines hidden (view full) --- 236 * Destroy a clone network interface. 237 */ 238int 239if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp) 240{ 241 int err; 242 struct ifnet *ifcifp; 243 | 282 CURVNET_RESTORE(); 283 } 284#endif 285 IF_CLONERS_UNLOCK(); 286 if (ifc == NULL) { 287 if_rele(ifp); 288 return (EINVAL); 289 } --- 7 unchanged lines hidden (view full) --- 297 * Destroy a clone network interface. 298 */ 299int 300if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp) 301{ 302 int err; 303 struct ifnet *ifcifp; 304 |
244 if (ifc->ifc_destroy == NULL) | 305 if (ifc->ifc_type == ADVANCED && ifc->ifc_destroy == NULL) |
245 return(EOPNOTSUPP); 246 247 /* 248 * Given that the cloned ifnet might be attached to a different 249 * vnet from where its cloner was registered, we have to 250 * switch to the vnet context of the target vnet. 251 */ 252 CURVNET_SET_QUIET(ifp->if_vnet); --- 8 unchanged lines hidden (view full) --- 261 IF_CLONE_UNLOCK(ifc); 262 if (ifcifp == NULL) { 263 CURVNET_RESTORE(); 264 return (ENXIO); /* ifp is not on the list. */ 265 } 266 267 if_delgroup(ifp, ifc->ifc_name); 268 | 306 return(EOPNOTSUPP); 307 308 /* 309 * Given that the cloned ifnet might be attached to a different 310 * vnet from where its cloner was registered, we have to 311 * switch to the vnet context of the target vnet. 312 */ 313 CURVNET_SET_QUIET(ifp->if_vnet); --- 8 unchanged lines hidden (view full) --- 322 IF_CLONE_UNLOCK(ifc); 323 if (ifcifp == NULL) { 324 CURVNET_RESTORE(); 325 return (ENXIO); /* ifp is not on the list. */ 326 } 327 328 if_delgroup(ifp, ifc->ifc_name); 329 |
269 err = (*ifc->ifc_destroy)(ifc, ifp); | 330 if (ifc->ifc_type == SIMPLE) 331 err = ifc_simple_destroy(ifc, ifp); 332 else 333 err = (*ifc->ifc_destroy)(ifc, ifp); |
270 271 if (err != 0) { 272 if_addgroup(ifp, ifc->ifc_name); 273 274 IF_CLONE_LOCK(ifc); 275 IFC_IFLIST_INSERT(ifc, ifp); 276 IF_CLONE_UNLOCK(ifc); 277 } 278 CURVNET_RESTORE(); 279 return (err); 280} 281 | 334 335 if (err != 0) { 336 if_addgroup(ifp, ifc->ifc_name); 337 338 IF_CLONE_LOCK(ifc); 339 IFC_IFLIST_INSERT(ifc, ifp); 340 IF_CLONE_UNLOCK(ifc); 341 } 342 CURVNET_RESTORE(); 343 return (err); 344} 345 |
282/* 283 * Register a network interface cloner. 284 */ 285int 286if_clone_attach(struct if_clone *ifc) | 346static struct if_clone * 347if_clone_alloc(const char *name, int maxunit) |
287{ | 348{ |
288 struct if_clone *ifc1; | 349 struct if_clone *ifc; |
289 | 350 |
290 KASSERT(ifc->ifc_name != NULL, ("%s: no name\n", __func__)); | 351 KASSERT(name != NULL, ("%s: no name\n", __func__)); |
291 | 352 |
353 ifc = malloc(sizeof(struct if_clone), M_CLONE, M_WAITOK | M_ZERO); 354 strncpy(ifc->ifc_name, name, IFCLOSIZ-1); |
|
292 IF_CLONE_LOCK_INIT(ifc); 293 IF_CLONE_ADDREF(ifc); | 355 IF_CLONE_LOCK_INIT(ifc); 356 IF_CLONE_ADDREF(ifc); |
357 ifc->ifc_maxunit = maxunit ? maxunit : IF_MAXUNIT; |
|
294 ifc->ifc_unrhdr = new_unrhdr(0, ifc->ifc_maxunit, &ifc->ifc_mtx); 295 LIST_INIT(&ifc->ifc_iflist); 296 | 358 ifc->ifc_unrhdr = new_unrhdr(0, ifc->ifc_maxunit, &ifc->ifc_mtx); 359 LIST_INIT(&ifc->ifc_iflist); 360 |
361 return (ifc); 362} 363 364static int 365if_clone_attach(struct if_clone *ifc) 366{ 367 struct if_clone *ifc1; 368 |
|
297 IF_CLONERS_LOCK(); 298 LIST_FOREACH(ifc1, &V_if_cloners, ifc_list) 299 if (strcmp(ifc->ifc_name, ifc1->ifc_name) == 0) { 300 IF_CLONERS_UNLOCK(); 301 IF_CLONE_REMREF(ifc); 302 return (EEXIST); 303 } 304 LIST_INSERT_HEAD(&V_if_cloners, ifc, ifc_list); 305 V_if_cloners_count++; 306 IF_CLONERS_UNLOCK(); 307 | 369 IF_CLONERS_LOCK(); 370 LIST_FOREACH(ifc1, &V_if_cloners, ifc_list) 371 if (strcmp(ifc->ifc_name, ifc1->ifc_name) == 0) { 372 IF_CLONERS_UNLOCK(); 373 IF_CLONE_REMREF(ifc); 374 return (EEXIST); 375 } 376 LIST_INSERT_HEAD(&V_if_cloners, ifc, ifc_list); 377 V_if_cloners_count++; 378 IF_CLONERS_UNLOCK(); 379 |
308 if (ifc->ifc_attach != NULL) 309 (*ifc->ifc_attach)(ifc); | 380 return (0); 381} 382 383struct if_clone * 384if_clone_advanced(const char *name, u_int maxunit, ifc_match_t match, 385 ifc_create_t create, ifc_destroy_t destroy) 386{ 387 struct if_clone *ifc; 388 389 ifc = if_clone_alloc(name, maxunit); 390 ifc->ifc_type = ADVANCED; 391 ifc->ifc_match = match; 392 ifc->ifc_create = create; 393 ifc->ifc_destroy = destroy; 394 395 if (if_clone_attach(ifc) != 0) { 396 if_clone_free(ifc); 397 return (NULL); 398 } 399 |
310 EVENTHANDLER_INVOKE(if_clone_event, ifc); 311 | 400 EVENTHANDLER_INVOKE(if_clone_event, ifc); 401 |
312 return (0); | 402 return (ifc); |
313} 314 | 403} 404 |
405struct if_clone * 406if_clone_simple(const char *name, ifcs_create_t create, ifcs_destroy_t destroy, 407 u_int minifs) 408{ 409 struct if_clone *ifc; 410 u_int unit; 411 412 ifc = if_clone_alloc(name, 0); 413 ifc->ifc_type = SIMPLE; 414 ifc->ifcs_create = create; 415 ifc->ifcs_destroy = destroy; 416 ifc->ifcs_minifs = minifs; 417 418 if (if_clone_attach(ifc) != 0) { 419 if_clone_free(ifc); 420 return (NULL); 421 } 422 423 for (unit = 0; unit < minifs; unit++) { 424 char name[IFNAMSIZ]; 425 int error; 426 427 snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit); 428 error = if_clone_createif(ifc, name, IFNAMSIZ, NULL); 429 KASSERT(error == 0, 430 ("%s: failed to create required interface %s", 431 __func__, name)); 432 } 433 434 EVENTHANDLER_INVOKE(if_clone_event, ifc); 435 436 return (ifc); 437} 438 |
|
315/* 316 * Unregister a network interface cloner. 317 */ 318void 319if_clone_detach(struct if_clone *ifc) 320{ | 439/* 440 * Unregister a network interface cloner. 441 */ 442void 443if_clone_detach(struct if_clone *ifc) 444{ |
321 struct ifc_simple_data *ifcs = ifc->ifc_data; | |
322 323 IF_CLONERS_LOCK(); 324 LIST_REMOVE(ifc, ifc_list); 325 V_if_cloners_count--; 326 IF_CLONERS_UNLOCK(); 327 328 /* Allow all simples to be destroyed */ | 445 446 IF_CLONERS_LOCK(); 447 LIST_REMOVE(ifc, ifc_list); 448 V_if_cloners_count--; 449 IF_CLONERS_UNLOCK(); 450 451 /* Allow all simples to be destroyed */ |
329 if (ifc->ifc_attach == ifc_simple_attach) 330 ifcs->ifcs_minifs = 0; | 452 if (ifc->ifc_type == SIMPLE) 453 ifc->ifcs_minifs = 0; |
331 332 /* destroy all interfaces for this cloner */ 333 while (!LIST_EMPTY(&ifc->ifc_iflist)) 334 if_clone_destroyif(ifc, LIST_FIRST(&ifc->ifc_iflist)); 335 336 IF_CLONE_REMREF(ifc); 337} 338 339static void 340if_clone_free(struct if_clone *ifc) 341{ 342 343 KASSERT(LIST_EMPTY(&ifc->ifc_iflist), 344 ("%s: ifc_iflist not empty", __func__)); 345 346 IF_CLONE_LOCK_DESTROY(ifc); 347 delete_unrhdr(ifc->ifc_unrhdr); | 454 455 /* destroy all interfaces for this cloner */ 456 while (!LIST_EMPTY(&ifc->ifc_iflist)) 457 if_clone_destroyif(ifc, LIST_FIRST(&ifc->ifc_iflist)); 458 459 IF_CLONE_REMREF(ifc); 460} 461 462static void 463if_clone_free(struct if_clone *ifc) 464{ 465 466 KASSERT(LIST_EMPTY(&ifc->ifc_iflist), 467 ("%s: ifc_iflist not empty", __func__)); 468 469 IF_CLONE_LOCK_DESTROY(ifc); 470 delete_unrhdr(ifc->ifc_unrhdr); |
471 free(ifc, M_CLONE); |
|
348} 349 350/* 351 * Provide list of interface cloners to userspace. 352 */ 353int 354if_clone_list(struct if_clonereq *ifcr) 355{ --- 122 unchanged lines hidden (view full) --- 478void 479ifc_free_unit(struct if_clone *ifc, int unit) 480{ 481 482 free_unr(ifc->ifc_unrhdr, unit); 483 IF_CLONE_REMREF(ifc); 484} 485 | 472} 473 474/* 475 * Provide list of interface cloners to userspace. 476 */ 477int 478if_clone_list(struct if_clonereq *ifcr) 479{ --- 122 unchanged lines hidden (view full) --- 602void 603ifc_free_unit(struct if_clone *ifc, int unit) 604{ 605 606 free_unr(ifc->ifc_unrhdr, unit); 607 IF_CLONE_REMREF(ifc); 608} 609 |
486void 487ifc_simple_attach(struct if_clone *ifc) 488{ 489 int err; 490 int unit; 491 char name[IFNAMSIZ]; 492 struct ifc_simple_data *ifcs = ifc->ifc_data; 493 494 KASSERT(ifcs->ifcs_minifs - 1 <= ifc->ifc_maxunit, 495 ("%s: %s requested more units than allowed (%d > %d)", 496 __func__, ifc->ifc_name, ifcs->ifcs_minifs, 497 ifc->ifc_maxunit + 1)); 498 499 for (unit = 0; unit < ifcs->ifcs_minifs; unit++) { 500 snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit); 501 err = if_clone_createif(ifc, name, IFNAMSIZ, NULL); 502 KASSERT(err == 0, 503 ("%s: failed to create required interface %s", 504 __func__, name)); 505 } 506} 507 508int | 610static int |
509ifc_simple_match(struct if_clone *ifc, const char *name) 510{ 511 const char *cp; 512 int i; 513 514 /* Match the name */ 515 for (cp = name, i = 0; i < strlen(ifc->ifc_name); i++, cp++) { 516 if (ifc->ifc_name[i] != *cp) --- 4 unchanged lines hidden (view full) --- 521 for (; *cp != '\0'; cp++) { 522 if (*cp < '0' || *cp > '9') 523 return (0); 524 } 525 526 return (1); 527} 528 | 611ifc_simple_match(struct if_clone *ifc, const char *name) 612{ 613 const char *cp; 614 int i; 615 616 /* Match the name */ 617 for (cp = name, i = 0; i < strlen(ifc->ifc_name); i++, cp++) { 618 if (ifc->ifc_name[i] != *cp) --- 4 unchanged lines hidden (view full) --- 623 for (; *cp != '\0'; cp++) { 624 if (*cp < '0' || *cp > '9') 625 return (0); 626 } 627 628 return (1); 629} 630 |
529int | 631static int |
530ifc_simple_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) 531{ 532 char *dp; 533 int wildcard; 534 int unit; 535 int err; | 632ifc_simple_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) 633{ 634 char *dp; 635 int wildcard; 636 int unit; 637 int err; |
536 struct ifc_simple_data *ifcs = ifc->ifc_data; | |
537 538 err = ifc_name2unit(name, &unit); 539 if (err != 0) 540 return (err); 541 542 wildcard = (unit < 0); 543 544 err = ifc_alloc_unit(ifc, &unit); 545 if (err != 0) 546 return (err); 547 | 638 639 err = ifc_name2unit(name, &unit); 640 if (err != 0) 641 return (err); 642 643 wildcard = (unit < 0); 644 645 err = ifc_alloc_unit(ifc, &unit); 646 if (err != 0) 647 return (err); 648 |
548 err = ifcs->ifcs_create(ifc, unit, params); | 649 err = ifc->ifcs_create(ifc, unit, params); |
549 if (err != 0) { 550 ifc_free_unit(ifc, unit); 551 return (err); 552 } 553 554 /* In the wildcard case, we need to update the name. */ 555 if (wildcard) { 556 for (dp = name; *dp != '\0'; dp++); --- 7 unchanged lines hidden (view full) --- 564 panic("if_clone_create(): interface name too long"); 565 } 566 567 } 568 569 return (0); 570} 571 | 650 if (err != 0) { 651 ifc_free_unit(ifc, unit); 652 return (err); 653 } 654 655 /* In the wildcard case, we need to update the name. */ 656 if (wildcard) { 657 for (dp = name; *dp != '\0'; dp++); --- 7 unchanged lines hidden (view full) --- 665 panic("if_clone_create(): interface name too long"); 666 } 667 668 } 669 670 return (0); 671} 672 |
572int | 673static int |
573ifc_simple_destroy(struct if_clone *ifc, struct ifnet *ifp) 574{ 575 int unit; | 674ifc_simple_destroy(struct if_clone *ifc, struct ifnet *ifp) 675{ 676 int unit; |
576 struct ifc_simple_data *ifcs = ifc->ifc_data; | |
577 578 unit = ifp->if_dunit; 579 | 677 678 unit = ifp->if_dunit; 679 |
580 if (unit < ifcs->ifcs_minifs) | 680 if (unit < ifc->ifcs_minifs) |
581 return (EINVAL); 582 | 681 return (EINVAL); 682 |
583 ifcs->ifcs_destroy(ifp); | 683 ifc->ifcs_destroy(ifp); |
584 585 ifc_free_unit(ifc, unit); 586 587 return (0); 588} | 684 685 ifc_free_unit(ifc, unit); 686 687 return (0); 688} |