dld_drv.c (afdda45f) | dld_drv.c (da14cebe) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 17 unchanged lines hidden (view full) --- 26/* 27 * Data-Link Driver 28 */ 29 30#include <sys/conf.h> 31#include <sys/mkdev.h> 32#include <sys/modctl.h> 33#include <sys/stat.h> | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 17 unchanged lines hidden (view full) --- 26/* 27 * Data-Link Driver 28 */ 29 30#include <sys/conf.h> 31#include <sys/mkdev.h> 32#include <sys/modctl.h> 33#include <sys/stat.h> |
34#include <sys/vlan.h> 35#include <sys/mac.h> | |
36#include <sys/dld_impl.h> 37#include <sys/dls_impl.h> 38#include <sys/softmac.h> | 34#include <sys/dld_impl.h> 35#include <sys/dls_impl.h> 36#include <sys/softmac.h> |
39#include <sys/vlan.h> 40#include <sys/policy.h> | 37#include <sys/mac.h> 38#include <sys/mac_ether.h> 39#include <sys/mac_client.h> 40#include <sys/mac_client_impl.h> 41#include <sys/mac_client_priv.h> |
41#include <inet/common.h> | 42#include <inet/common.h> |
43#include <sys/policy.h> 44#include <sys/priv_names.h> |
|
42 43static void drv_init(void); 44static int drv_fini(void); 45 46static int drv_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 47static int drv_attach(dev_info_t *, ddi_attach_cmd_t); 48static int drv_detach(dev_info_t *, ddi_detach_cmd_t); 49 --- 95 unchanged lines hidden (view full) --- 145/* 146 * Initialize component modules. 147 */ 148static void 149drv_init(void) 150{ 151 drv_secobj_init(); 152 dld_str_init(); | 45 46static void drv_init(void); 47static int drv_fini(void); 48 49static int drv_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 50static int drv_attach(dev_info_t *, ddi_attach_cmd_t); 51static int drv_detach(dev_info_t *, ddi_detach_cmd_t); 52 --- 95 unchanged lines hidden (view full) --- 148/* 149 * Initialize component modules. 150 */ 151static void 152drv_init(void) 153{ 154 drv_secobj_init(); 155 dld_str_init(); |
156 |
|
153 /* 154 * Create a hash table for autopush configuration. 155 */ 156 dld_ap_hashp = mod_hash_create_idhash("dld_autopush_hash", 157 NAUTOPUSH, mod_hash_null_valdtor); 158 159 ASSERT(dld_ap_hashp != NULL); 160 rw_init(&dld_ap_hash_lock, NULL, RW_DRIVER, NULL); --- 13 unchanged lines hidden (view full) --- 174drv_fini(void) 175{ 176 int err; 177 boolean_t exist = B_FALSE; 178 179 rw_enter(&dld_ap_hash_lock, RW_READER); 180 mod_hash_walk(dld_ap_hashp, drv_ap_exist, &exist); 181 rw_exit(&dld_ap_hash_lock); | 157 /* 158 * Create a hash table for autopush configuration. 159 */ 160 dld_ap_hashp = mod_hash_create_idhash("dld_autopush_hash", 161 NAUTOPUSH, mod_hash_null_valdtor); 162 163 ASSERT(dld_ap_hashp != NULL); 164 rw_init(&dld_ap_hash_lock, NULL, RW_DRIVER, NULL); --- 13 unchanged lines hidden (view full) --- 178drv_fini(void) 179{ 180 int err; 181 boolean_t exist = B_FALSE; 182 183 rw_enter(&dld_ap_hash_lock, RW_READER); 184 mod_hash_walk(dld_ap_hashp, drv_ap_exist, &exist); 185 rw_exit(&dld_ap_hash_lock); |
182 | |
183 if (exist) 184 return (EBUSY); 185 186 if ((err = dld_str_fini()) != 0) 187 return (err); 188 189 drv_secobj_fini(); 190 mod_hash_destroy_idhash(dld_ap_hashp); --- 118 unchanged lines hidden (view full) --- 309 return (0); 310} 311 312/* 313 * DLDIOC_ATTR 314 */ 315/* ARGSUSED */ 316static int | 186 if (exist) 187 return (EBUSY); 188 189 if ((err = dld_str_fini()) != 0) 190 return (err); 191 192 drv_secobj_fini(); 193 mod_hash_destroy_idhash(dld_ap_hashp); --- 118 unchanged lines hidden (view full) --- 312 return (0); 313} 314 315/* 316 * DLDIOC_ATTR 317 */ 318/* ARGSUSED */ 319static int |
317drv_ioc_attr(void *karg, intptr_t arg, int mode, cred_t *cred) | 320drv_ioc_attr(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) |
318{ 319 dld_ioc_attr_t *diap = karg; 320 dls_dl_handle_t dlh; | 321{ 322 dld_ioc_attr_t *diap = karg; 323 dls_dl_handle_t dlh; |
321 dls_vlan_t *dvp; | 324 dls_link_t *dlp; |
322 int err; | 325 int err; |
326 mac_perim_handle_t mph; |
|
323 324 if ((err = dls_devnet_hold_tmp(diap->dia_linkid, &dlh)) != 0) 325 return (err); 326 | 327 328 if ((err = dls_devnet_hold_tmp(diap->dia_linkid, &dlh)) != 0) 329 return (err); 330 |
327 if ((err = dls_vlan_hold(dls_devnet_mac(dlh), 328 dls_devnet_vid(dlh), &dvp, B_FALSE, B_FALSE)) != 0) { | 331 if ((err = mac_perim_enter_by_macname( 332 dls_devnet_mac(dlh), &mph)) != 0) { |
329 dls_devnet_rele_tmp(dlh); 330 return (err); 331 } | 333 dls_devnet_rele_tmp(dlh); 334 return (err); 335 } |
332 mac_sdu_get(dvp->dv_dlp->dl_mh, NULL, &diap->dia_max_sdu); | |
333 | 336 |
334 dls_vlan_rele(dvp); | 337 if ((err = dls_link_hold(dls_devnet_mac(dlh), &dlp)) != 0) { 338 mac_perim_exit(mph); 339 dls_devnet_rele_tmp(dlh); 340 return (err); 341 } 342 343 mac_sdu_get(dlp->dl_mh, NULL, &diap->dia_max_sdu); 344 345 dls_link_rele(dlp); 346 mac_perim_exit(mph); |
335 dls_devnet_rele_tmp(dlh); 336 337 return (0); 338} 339 340/* 341 * DLDIOC_PHYS_ATTR 342 */ 343/* ARGSUSED */ 344static int | 347 dls_devnet_rele_tmp(dlh); 348 349 return (0); 350} 351 352/* 353 * DLDIOC_PHYS_ATTR 354 */ 355/* ARGSUSED */ 356static int |
345drv_ioc_phys_attr(void *karg, intptr_t arg, int mode, cred_t *cred) | 357drv_ioc_phys_attr(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) |
346{ 347 dld_ioc_phys_attr_t *dipp = karg; 348 int err; 349 dls_dl_handle_t dlh; 350 dls_dev_handle_t ddh; 351 dev_t phydev; 352 353 /* --- 28 unchanged lines hidden (view full) --- 382 */ 383 (void) snprintf(dipp->dip_dev, MAXLINKNAMELEN, "%s%d", 384 ddi_major_to_name(getmajor(phydev)), getminor(phydev) - 1); 385 386 softmac_rele_device(ddh); 387 return (0); 388} 389 | 358{ 359 dld_ioc_phys_attr_t *dipp = karg; 360 int err; 361 dls_dl_handle_t dlh; 362 dls_dev_handle_t ddh; 363 dev_t phydev; 364 365 /* --- 28 unchanged lines hidden (view full) --- 394 */ 395 (void) snprintf(dipp->dip_dev, MAXLINKNAMELEN, "%s%d", 396 ddi_major_to_name(getmajor(phydev)), getminor(phydev) - 1); 397 398 softmac_rele_device(ddh); 399 return (0); 400} 401 |
402/* ARGSUSED */ 403static int 404drv_ioc_hwgrpget(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) 405{ 406 dld_ioc_hwgrpget_t *hwgrpp = karg; 407 dld_hwgrpinfo_t hwgrp, *hip; 408 mac_handle_t mh = NULL; 409 int i, err, grpnum; 410 uint_t bytes_left; 411 412 hwgrpp->dih_n_groups = 0; 413 err = mac_open_by_linkid(hwgrpp->dih_linkid, &mh); 414 if (err != 0) 415 goto done; 416 417 hip = (dld_hwgrpinfo_t *) 418 ((uchar_t *)arg + sizeof (dld_ioc_hwgrpget_t)); 419 bytes_left = hwgrpp->dih_size; 420 grpnum = mac_hwgrp_num(mh); 421 for (i = 0; i < grpnum; i++) { 422 if (sizeof (dld_hwgrpinfo_t) > bytes_left) { 423 err = ENOSPC; 424 goto done; 425 } 426 427 bzero(&hwgrp, sizeof (hwgrp)); 428 bcopy(mac_name(mh), hwgrp.dhi_link_name, 429 sizeof (hwgrp.dhi_link_name)); 430 mac_get_hwgrp_info(mh, i, &hwgrp.dhi_grp_num, 431 &hwgrp.dhi_n_rings, &hwgrp.dhi_grp_type, 432 &hwgrp.dhi_n_clnts, hwgrp.dhi_clnts); 433 if (copyout(&hwgrp, hip, sizeof (hwgrp)) != 0) { 434 err = EFAULT; 435 goto done; 436 } 437 438 hip++; 439 bytes_left -= sizeof (dld_hwgrpinfo_t); 440 } 441 442done: 443 if (mh != NULL) 444 dld_mac_close(mh); 445 if (err == 0) 446 hwgrpp->dih_n_groups = grpnum; 447 return (err); 448} 449 450/* ARGSUSED */ 451static int 452drv_ioc_macaddrget(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) 453{ 454 dld_ioc_macaddrget_t *magp = karg; 455 dld_macaddrinfo_t mai, *maip; 456 mac_handle_t mh = NULL; 457 int i, err; 458 uint_t bytes_left; 459 boolean_t is_used; 460 461 magp->dig_count = 0; 462 err = mac_open_by_linkid(magp->dig_linkid, &mh); 463 if (err != 0) 464 goto done; 465 466 maip = (dld_macaddrinfo_t *) 467 ((uchar_t *)arg + sizeof (dld_ioc_macaddrget_t)); 468 bytes_left = magp->dig_size; 469 470 for (i = 0; i < mac_addr_factory_num(mh) + 1; i++) { 471 if (sizeof (dld_macaddrinfo_t) > bytes_left) { 472 err = ENOSPC; 473 goto done; 474 } 475 476 bzero(&mai, sizeof (mai)); 477 478 if (i == 0) { 479 /* primary MAC address */ 480 mac_unicast_primary_get(mh, mai.dmi_addr); 481 mai.dmi_addrlen = mac_addr_len(mh); 482 mac_unicast_primary_info(mh, mai.dmi_client_name, 483 &is_used); 484 } else { 485 /* factory MAC address slot */ 486 mac_addr_factory_value(mh, i, mai.dmi_addr, 487 &mai.dmi_addrlen, mai.dmi_client_name, &is_used); 488 } 489 490 mai.dmi_slot = i; 491 if (is_used) 492 mai.dmi_flags |= DLDIOCMACADDR_USED; 493 494 if (copyout(&mai, maip, sizeof (mai)) != 0) { 495 err = EFAULT; 496 goto done; 497 } 498 499 maip++; 500 bytes_left -= sizeof (dld_macaddrinfo_t); 501 } 502 503done: 504 if (mh != NULL) 505 dld_mac_close(mh); 506 if (err == 0) 507 magp->dig_count = mac_addr_factory_num(mh) + 1; 508 return (err); 509} 510 |
|
390/* | 511/* |
391 * DLDIOC_SETPROP | 512 * DLDIOC_SET/GETPROP |
392 */ 393static int | 513 */ 514static int |
394drv_ioc_prop_common(dld_ioc_macprop_t *dipp, intptr_t arg, boolean_t set, | 515drv_ioc_prop_common(dld_ioc_macprop_t *prop, intptr_t arg, boolean_t set, |
395 int mode) 396{ | 516 int mode) 517{ |
397 int err = EINVAL; 398 size_t dsize; 399 dld_ioc_macprop_t *kdipp; 400 dls_dl_handle_t dlh; 401 dls_vlan_t *dvp; 402 datalink_id_t linkid; | 518 int err = EINVAL; 519 dls_dl_handle_t dlh = NULL; 520 dls_link_t *dlp = NULL; 521 mac_perim_handle_t mph = NULL; |
403 mac_prop_t macprop; | 522 mac_prop_t macprop; |
404 uchar_t *cp; 405 struct dlautopush *dlap; 406 dld_ioc_zid_t *dzp; | 523 dld_ioc_macprop_t *kprop; 524 datalink_id_t linkid; 525 uint_t dsize; |
407 | 526 |
527 |
|
408 /* | 528 /* |
409 * We only use pr_valsize from dipp, as the caller only did a | 529 * We only use pr_valsize from prop, as the caller only did a |
410 * copyin() for sizeof (dld_ioc_prop_t), which doesn't cover 411 * the property data. We copyin the full dld_ioc_prop_t | 530 * copyin() for sizeof (dld_ioc_prop_t), which doesn't cover 531 * the property data. We copyin the full dld_ioc_prop_t |
412 * including the data into kdipp down below. | 532 * including the data into kprop down below. |
413 */ | 533 */ |
414 dsize = sizeof (dld_ioc_macprop_t) + dipp->pr_valsize - 1; 415 if (dsize < dipp->pr_valsize) | 534 dsize = sizeof (dld_ioc_macprop_t) + prop->pr_valsize - 1; 535 if (dsize < prop->pr_valsize) |
416 return (EINVAL); 417 418 /* 419 * The property data is variable size, so we need to allocate 420 * a buffer for kernel use as this data was not part of the | 536 return (EINVAL); 537 538 /* 539 * The property data is variable size, so we need to allocate 540 * a buffer for kernel use as this data was not part of the |
421 * dipp allocation and copyin() done by the framework. | 541 * prop allocation and copyin() done by the framework. |
422 */ | 542 */ |
423 if ((kdipp = kmem_alloc(dsize, KM_NOSLEEP)) == NULL) | 543 if ((kprop = kmem_alloc(dsize, KM_NOSLEEP)) == NULL) |
424 return (ENOMEM); | 544 return (ENOMEM); |
425 if (ddi_copyin((void *)arg, kdipp, dsize, mode) != 0) { | 545 546 if (ddi_copyin((void *)arg, kprop, dsize, mode) != 0) { |
426 err = EFAULT; 427 goto done; 428 } 429 | 547 err = EFAULT; 548 goto done; 549 } 550 |
430 linkid = kdipp->pr_linkid; | 551 linkid = kprop->pr_linkid; 552 if ((err = dls_devnet_hold_tmp(linkid, &dlh)) != 0) 553 goto done; |
431 | 554 |
432 switch (dipp->pr_num) { 433 case MAC_PROP_ZONE: | 555 if ((err = mac_perim_enter_by_macname(dls_devnet_mac(dlh), 556 &mph)) != 0) { 557 goto done; 558 } 559 560 switch (kprop->pr_num) { 561 case MAC_PROP_ZONE: { |
434 if (set) { | 562 if (set) { |
435 dzp = (dld_ioc_zid_t *)kdipp->pr_val; | 563 dld_ioc_zid_t *dzp = (dld_ioc_zid_t *)kprop->pr_val; 564 |
436 err = dls_devnet_setzid(dzp->diz_link, dzp->diz_zid); 437 goto done; 438 } else { | 565 err = dls_devnet_setzid(dzp->diz_link, dzp->diz_zid); 566 goto done; 567 } else { |
439 kdipp->pr_perm_flags = MAC_PROP_PERM_RW; 440 cp = (uchar_t *)kdipp->pr_val; 441 err = dls_devnet_getzid(linkid, (zoneid_t *)cp); | 568 kprop->pr_perm_flags = MAC_PROP_PERM_RW; 569 err = dls_devnet_getzid(linkid, 570 (zoneid_t *)kprop->pr_val); |
442 goto done; 443 } | 571 goto done; 572 } |
444 case MAC_PROP_AUTOPUSH: | 573 } 574 case MAC_PROP_AUTOPUSH: { 575 struct dlautopush *dlap = 576 (struct dlautopush *)kprop->pr_val; 577 |
445 if (set) { | 578 if (set) { |
446 if (dipp->pr_valsize != 0) { 447 dlap = (struct dlautopush *)kdipp->pr_val; | 579 if (kprop->pr_valsize != 0) { |
448 err = drv_ioc_setap(linkid, dlap); 449 goto done; 450 } else { 451 err = drv_ioc_clrap(linkid); 452 goto done; 453 } 454 } else { | 580 err = drv_ioc_setap(linkid, dlap); 581 goto done; 582 } else { 583 err = drv_ioc_clrap(linkid); 584 goto done; 585 } 586 } else { |
455 kdipp->pr_perm_flags = MAC_PROP_PERM_RW; 456 dlap = (struct dlautopush *)kdipp->pr_val; | 587 kprop->pr_perm_flags = MAC_PROP_PERM_RW; |
457 err = drv_ioc_getap(linkid, dlap); 458 goto done; 459 } | 588 err = drv_ioc_getap(linkid, dlap); 589 goto done; 590 } |
460 | 591 } |
461 default: 462 break; 463 } 464 | 592 default: 593 break; 594 } 595 |
465 if ((err = dls_devnet_hold_tmp(linkid, &dlh)) != 0) | 596 if ((err = dls_link_hold(dls_devnet_mac(dlh), &dlp)) != 0) |
466 goto done; 467 | 597 goto done; 598 |
468 if ((err = dls_vlan_hold(dls_devnet_mac(dlh), 469 dls_devnet_vid(dlh), &dvp, B_FALSE, B_FALSE)) != 0) { 470 dls_devnet_rele_tmp(dlh); 471 goto done; 472 } | 599 macprop.mp_name = kprop->pr_name; 600 macprop.mp_id = kprop->pr_num; 601 macprop.mp_flags = kprop->pr_flags; |
473 | 602 |
474 macprop.mp_name = kdipp->pr_name; 475 macprop.mp_id = kdipp->pr_num; 476 macprop.mp_flags = kdipp->pr_flags; 477 | |
478 if (set) { | 603 if (set) { |
479 err = mac_set_prop(dvp->dv_dlp->dl_mh, &macprop, 480 kdipp->pr_val, kdipp->pr_valsize); | 604 err = mac_set_prop(dlp->dl_mh, &macprop, kprop->pr_val, 605 kprop->pr_valsize); |
481 } else { | 606 } else { |
482 kdipp->pr_perm_flags = MAC_PROP_PERM_RW; 483 err = mac_get_prop(dvp->dv_dlp->dl_mh, &macprop, 484 kdipp->pr_val, kdipp->pr_valsize, &kdipp->pr_perm_flags); | 607 kprop->pr_perm_flags = MAC_PROP_PERM_RW; 608 err = mac_get_prop(dlp->dl_mh, &macprop, kprop->pr_val, 609 kprop->pr_valsize, &kprop->pr_perm_flags); |
485 } 486 | 610 } 611 |
487 dls_vlan_rele(dvp); 488 dls_devnet_rele_tmp(dlh); | |
489done: 490 if (!set && err == 0 && | 612done: 613 if (!set && err == 0 && |
491 ddi_copyout(kdipp, (void *)arg, dsize, mode) != 0) | 614 ddi_copyout(kprop, (void *)arg, dsize, mode) != 0) |
492 err = EFAULT; | 615 err = EFAULT; |
493 kmem_free(kdipp, dsize); 494 return (err); 495} | |
496 | 616 |
497/* ARGSUSED */ 498static int 499drv_ioc_setprop(void *karg, intptr_t arg, int mode, cred_t *cred) 500{ 501 return (drv_ioc_prop_common(karg, arg, B_TRUE, mode)); 502} | 617 if (dlp != NULL) 618 dls_link_rele(dlp); |
503 | 619 |
504/* ARGSUSED */ 505static int 506drv_ioc_getprop(void *karg, intptr_t arg, int mode, cred_t *cred) 507{ 508 return (drv_ioc_prop_common(karg, arg, B_FALSE, mode)); 509} | 620 if (mph != NULL) { 621 int32_t cpuid; 622 void *mdip = NULL; |
510 | 623 |
511/* 512 * DLDIOC_CREATE_VLAN 513 */ 514/* ARGSUSED */ 515static int 516drv_ioc_create_vlan(void *karg, intptr_t arg, int mode, cred_t *cred) 517{ 518 dld_ioc_create_vlan_t *dicp = karg; | 624 if (dlp != NULL && set && err == 0) { 625 cpuid = mac_client_intr_cpu(dlp->dl_mch); 626 mdip = mac_get_devinfo(dlp->dl_mh); 627 } |
519 | 628 |
520 return (dls_devnet_create_vlan(dicp->dic_vlanid, dicp->dic_linkid, 521 dicp->dic_vid, dicp->dic_force)); | 629 mac_perim_exit(mph); 630 631 if (mdip != NULL) 632 mac_client_set_intr_cpu(mdip, dlp->dl_mch, cpuid); 633 } 634 if (dlh != NULL) 635 dls_devnet_rele_tmp(dlh); 636 637 if (kprop != NULL) 638 kmem_free(kprop, dsize); 639 return (err); |
522} 523 | 640} 641 |
524/* 525 * DLDIOC_DELETE_VLAN 526 */ | |
527/* ARGSUSED */ 528static int | 642/* ARGSUSED */ 643static int |
529drv_ioc_delete_vlan(void *karg, intptr_t arg, int mode, cred_t *cred) | 644drv_ioc_setprop(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) |
530{ | 645{ |
531 dld_ioc_delete_vlan_t *didp = karg; 532 533 return (dls_devnet_destroy_vlan(didp->did_linkid)); | 646 return (drv_ioc_prop_common(karg, arg, B_TRUE, mode)); |
534} 535 | 647} 648 |
536/* 537 * DLDIOC_VLAN_ATTR 538 */ | |
539/* ARGSUSED */ 540static int | 649/* ARGSUSED */ 650static int |
541drv_ioc_vlan_attr(void *karg, intptr_t arg, int mode, cred_t *cred) | 651drv_ioc_getprop(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) |
542{ | 652{ |
543 dld_ioc_vlan_attr_t *divp = karg; 544 dls_dl_handle_t dlh; 545 uint16_t vid; 546 dls_vlan_t *dvp; 547 int err; 548 549 /* 550 * Hold this link to prevent it from being deleted. 551 */ 552 if ((err = dls_devnet_hold_tmp(divp->div_vlanid, &dlh)) != 0) 553 return (err); 554 555 if ((vid = dls_devnet_vid(dlh)) == VLAN_ID_NONE) { 556 dls_devnet_rele_tmp(dlh); 557 return (EINVAL); 558 } 559 560 err = dls_vlan_hold(dls_devnet_mac(dlh), vid, &dvp, B_FALSE, B_FALSE); 561 if (err != 0) { 562 dls_devnet_rele_tmp(dlh); 563 return (err); 564 } 565 566 divp->div_linkid = dls_devnet_linkid(dlh); 567 divp->div_implicit = !dls_devnet_is_explicit(dlh); 568 divp->div_vid = vid; 569 divp->div_force = dvp->dv_force; 570 571 dls_vlan_rele(dvp); 572 dls_devnet_rele_tmp(dlh); 573 return (0); | 653 return (drv_ioc_prop_common(karg, arg, B_FALSE, mode)); |
574} 575 576/* 577 * DLDIOC_RENAME. 578 * 579 * This function handles two cases of link renaming. See more in comments above 580 * dls_datalink_rename(). 581 */ 582/* ARGSUSED */ 583static int | 654} 655 656/* 657 * DLDIOC_RENAME. 658 * 659 * This function handles two cases of link renaming. See more in comments above 660 * dls_datalink_rename(). 661 */ 662/* ARGSUSED */ 663static int |
584drv_ioc_rename(void *karg, intptr_t arg, int mode, cred_t *cred) | 664drv_ioc_rename(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) |
585{ 586 dld_ioc_rename_t *dir = karg; 587 mod_hash_key_t key; 588 mod_hash_val_t val; 589 int err; 590 591 if ((err = dls_devnet_rename(dir->dir_linkid1, dir->dir_linkid2, 592 dir->dir_link)) != 0) --- 121 unchanged lines hidden (view full) --- 714 return (0); 715} 716 717/* 718 * DLDIOC_DOORSERVER 719 */ 720/* ARGSUSED */ 721static int | 665{ 666 dld_ioc_rename_t *dir = karg; 667 mod_hash_key_t key; 668 mod_hash_val_t val; 669 int err; 670 671 if ((err = dls_devnet_rename(dir->dir_linkid1, dir->dir_linkid2, 672 dir->dir_link)) != 0) --- 121 unchanged lines hidden (view full) --- 794 return (0); 795} 796 797/* 798 * DLDIOC_DOORSERVER 799 */ 800/* ARGSUSED */ 801static int |
722drv_ioc_doorserver(void *karg, intptr_t arg, int mode, cred_t *cred) | 802drv_ioc_doorserver(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) |
723{ 724 dld_ioc_door_t *did = karg; 725 726 return (dls_mgmt_door_set(did->did_start_door)); 727} 728 729/* | 803{ 804 dld_ioc_door_t *did = karg; 805 806 return (dls_mgmt_door_set(did->did_start_door)); 807} 808 809/* |
810 * DLDIOC_USAGELOG 811 */ 812/* ARGSUSED */ 813static int 814drv_ioc_usagelog(void *karg, intptr_t arg, int mode, cred_t *cred, 815 int *rvalp) 816{ 817 dld_ioc_usagelog_t *log_info = (dld_ioc_usagelog_t *)karg; 818 819 if (log_info->ul_type < MAC_LOGTYPE_LINK || 820 log_info->ul_type > MAC_LOGTYPE_FLOW) 821 return (EINVAL); 822 823 if (log_info->ul_onoff) 824 mac_start_logusage(log_info->ul_type, log_info->ul_interval); 825 else 826 mac_stop_logusage(log_info->ul_type); 827 return (0); 828} 829 830/* 831 * Process a DLDIOC_ADDFLOW request. 832 */ 833/* ARGSUSED */ 834static int 835drv_ioc_addflow(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) 836{ 837 dld_ioc_addflow_t *afp = karg; 838 839 return (dld_add_flow(afp->af_linkid, afp->af_name, 840 &afp->af_flow_desc, &afp->af_resource_props)); 841} 842 843/* 844 * Process a DLDIOC_REMOVEFLOW request. 845 */ 846/* ARGSUSED */ 847static int 848drv_ioc_removeflow(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) 849{ 850 dld_ioc_removeflow_t *rfp = karg; 851 852 return (dld_remove_flow(rfp->rf_name)); 853} 854 855/* 856 * Process a DLDIOC_MODIFYFLOW request. 857 */ 858/* ARGSUSED */ 859static int 860drv_ioc_modifyflow(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) 861{ 862 dld_ioc_modifyflow_t *mfp = karg; 863 864 return (dld_modify_flow(mfp->mf_name, &mfp->mf_resource_props)); 865} 866 867/* 868 * Process a DLDIOC_WALKFLOW request. 869 */ 870/* ARGSUSED */ 871static int 872drv_ioc_walkflow(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) 873{ 874 dld_ioc_walkflow_t *wfp = karg; 875 876 return (dld_walk_flow(wfp, arg)); 877} 878 879/* |
|
730 * Check for GLDv3 autopush information. There are three cases: 731 * 732 * 1. If devp points to a GLDv3 datalink and it has autopush configuration, 733 * fill dlap in with that information and return 0. 734 * 735 * 2. If devp points to a GLDv3 datalink but it doesn't have autopush 736 * configuration, then replace devp with the physical device (if one 737 * exists) and return 1. This allows stropen() to find the old-school --- 66 unchanged lines hidden (view full) --- 804{ 805 mod_hash_destroy_hash(drv_secobj_hash); 806 kmem_cache_destroy(drv_secobj_cachep); 807 rw_destroy(&drv_secobj_lock); 808} 809 810/* ARGSUSED */ 811static int | 880 * Check for GLDv3 autopush information. There are three cases: 881 * 882 * 1. If devp points to a GLDv3 datalink and it has autopush configuration, 883 * fill dlap in with that information and return 0. 884 * 885 * 2. If devp points to a GLDv3 datalink but it doesn't have autopush 886 * configuration, then replace devp with the physical device (if one 887 * exists) and return 1. This allows stropen() to find the old-school --- 66 unchanged lines hidden (view full) --- 954{ 955 mod_hash_destroy_hash(drv_secobj_hash); 956 kmem_cache_destroy(drv_secobj_cachep); 957 rw_destroy(&drv_secobj_lock); 958} 959 960/* ARGSUSED */ 961static int |
812drv_ioc_secobj_set(void *karg, intptr_t arg, int mode, cred_t *cred) | 962drv_ioc_secobj_set(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) |
813{ 814 dld_ioc_secobj_set_t *ssp = karg; 815 dld_secobj_t *sobjp, *objp; 816 int err; 817 818 sobjp = &ssp->ss_obj; 819 820 if (sobjp->so_class != DLD_SECOBJ_CLASS_WEP && --- 59 unchanged lines hidden (view full) --- 880 statep->ss_objp++; 881 statep->ss_free -= sizeof (dld_secobj_t); 882 statep->ss_count++; 883 return (MH_WALK_CONTINUE); 884} 885 886/* ARGSUSED */ 887static int | 963{ 964 dld_ioc_secobj_set_t *ssp = karg; 965 dld_secobj_t *sobjp, *objp; 966 int err; 967 968 sobjp = &ssp->ss_obj; 969 970 if (sobjp->so_class != DLD_SECOBJ_CLASS_WEP && --- 59 unchanged lines hidden (view full) --- 1030 statep->ss_objp++; 1031 statep->ss_free -= sizeof (dld_secobj_t); 1032 statep->ss_count++; 1033 return (MH_WALK_CONTINUE); 1034} 1035 1036/* ARGSUSED */ 1037static int |
888drv_ioc_secobj_get(void *karg, intptr_t arg, int mode, cred_t *cred) | 1038drv_ioc_secobj_get(void *karg, intptr_t arg, int mode, cred_t *cred, int *rvalp) |
889{ 890 dld_ioc_secobj_get_t *sgp = karg; 891 dld_secobj_t *sobjp, *objp; 892 int err; 893 894 sobjp = &sgp->sg_obj; | 1039{ 1040 dld_ioc_secobj_get_t *sgp = karg; 1041 dld_secobj_t *sobjp, *objp; 1042 int err; 1043 1044 sobjp = &sgp->sg_obj; |
895 | |
896 if (sobjp->so_name[DLD_SECOBJ_NAME_MAX - 1] != '\0') 897 return (EINVAL); 898 899 rw_enter(&drv_secobj_lock, RW_READER); 900 if (sobjp->so_name[0] != '\0') { 901 err = mod_hash_find(drv_secobj_hash, 902 (mod_hash_key_t)sobjp->so_name, (mod_hash_val_t *)&objp); 903 if (err != 0) { --- 23 unchanged lines hidden (view full) --- 927 sgp->sg_count = state.ss_count; 928 } 929 rw_exit(&drv_secobj_lock); 930 return (0); 931} 932 933/* ARGSUSED */ 934static int | 1045 if (sobjp->so_name[DLD_SECOBJ_NAME_MAX - 1] != '\0') 1046 return (EINVAL); 1047 1048 rw_enter(&drv_secobj_lock, RW_READER); 1049 if (sobjp->so_name[0] != '\0') { 1050 err = mod_hash_find(drv_secobj_hash, 1051 (mod_hash_key_t)sobjp->so_name, (mod_hash_val_t *)&objp); 1052 if (err != 0) { --- 23 unchanged lines hidden (view full) --- 1076 sgp->sg_count = state.ss_count; 1077 } 1078 rw_exit(&drv_secobj_lock); 1079 return (0); 1080} 1081 1082/* ARGSUSED */ 1083static int |
935drv_ioc_secobj_unset(void *karg, intptr_t arg, int mode, cred_t *cred) | 1084drv_ioc_secobj_unset(void *karg, intptr_t arg, int mode, cred_t *cred, 1085 int *rvalp) |
936{ 937 dld_ioc_secobj_unset_t *sup = karg; 938 dld_secobj_t *objp; 939 mod_hash_val_t val; 940 int err; 941 942 if (sup->su_name[DLD_SECOBJ_NAME_MAX - 1] != '\0') 943 return (EINVAL); --- 10 unchanged lines hidden (view full) --- 954 (mod_hash_val_t *)&val) == 0); 955 ASSERT(objp == (dld_secobj_t *)val); 956 957 kmem_cache_free(drv_secobj_cachep, objp); 958 rw_exit(&drv_secobj_lock); 959 return (0); 960} 961 | 1086{ 1087 dld_ioc_secobj_unset_t *sup = karg; 1088 dld_secobj_t *objp; 1089 mod_hash_val_t val; 1090 int err; 1091 1092 if (sup->su_name[DLD_SECOBJ_NAME_MAX - 1] != '\0') 1093 return (EINVAL); --- 10 unchanged lines hidden (view full) --- 1104 (mod_hash_val_t *)&val) == 0); 1105 ASSERT(objp == (dld_secobj_t *)val); 1106 1107 kmem_cache_free(drv_secobj_cachep, objp); 1108 rw_exit(&drv_secobj_lock); 1109 return (0); 1110} 1111 |
1112static int 1113drv_check_policy(dld_ioc_info_t *info, cred_t *cred) 1114{ 1115 int i, err = 0; 1116 1117 for (i = 0; info->di_priv[i] != NULL && i < DLD_MAX_PRIV; i++) { 1118 if ((err = secpolicy_dld_ioctl(cred, info->di_priv[i], 1119 "dld ioctl")) != 0) { 1120 break; 1121 } 1122 } 1123 if (err == 0) 1124 return (0); 1125 1126 return (secpolicy_net_config(cred, B_FALSE)); 1127} 1128 |
|
962static dld_ioc_info_t drv_ioc_list[] = { 963 {DLDIOC_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_attr_t), | 1129static dld_ioc_info_t drv_ioc_list[] = { 1130 {DLDIOC_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_attr_t), |
964 drv_ioc_attr}, | 1131 drv_ioc_attr, {NULL}}, |
965 {DLDIOC_PHYS_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_phys_attr_t), | 1132 {DLDIOC_PHYS_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_phys_attr_t), |
966 drv_ioc_phys_attr}, 967 {DLDIOC_SECOBJ_SET, DLDCOPYIN | DLDDLCONFIG, 968 sizeof (dld_ioc_secobj_set_t), drv_ioc_secobj_set}, 969 {DLDIOC_SECOBJ_GET, DLDCOPYINOUT | DLDDLCONFIG, 970 sizeof (dld_ioc_secobj_get_t), drv_ioc_secobj_get}, 971 {DLDIOC_SECOBJ_UNSET, DLDCOPYIN | DLDDLCONFIG, 972 sizeof (dld_ioc_secobj_unset_t), drv_ioc_secobj_unset}, 973 {DLDIOC_CREATE_VLAN, DLDCOPYIN | DLDDLCONFIG, 974 sizeof (dld_ioc_create_vlan_t), drv_ioc_create_vlan}, 975 {DLDIOC_DELETE_VLAN, DLDCOPYIN | DLDDLCONFIG, 976 sizeof (dld_ioc_delete_vlan_t), 977 drv_ioc_delete_vlan}, 978 {DLDIOC_VLAN_ATTR, DLDCOPYINOUT, sizeof (dld_ioc_vlan_attr_t), 979 drv_ioc_vlan_attr}, 980 {DLDIOC_DOORSERVER, DLDCOPYIN | DLDDLCONFIG, sizeof (dld_ioc_door_t), 981 drv_ioc_doorserver}, 982 {DLDIOC_RENAME, DLDCOPYIN | DLDDLCONFIG, sizeof (dld_ioc_rename_t), 983 drv_ioc_rename}, | 1133 drv_ioc_phys_attr, {NULL}}, 1134 {DLDIOC_SECOBJ_SET, DLDCOPYIN, sizeof (dld_ioc_secobj_set_t), 1135 drv_ioc_secobj_set, {PRIV_SYS_DL_CONFIG}}, 1136 {DLDIOC_SECOBJ_GET, DLDCOPYINOUT, sizeof (dld_ioc_secobj_get_t), 1137 drv_ioc_secobj_get, {PRIV_SYS_DL_CONFIG}}, 1138 {DLDIOC_SECOBJ_UNSET, DLDCOPYIN, sizeof (dld_ioc_secobj_unset_t), 1139 drv_ioc_secobj_unset, {PRIV_SYS_DL_CONFIG}}, 1140 {DLDIOC_DOORSERVER, DLDCOPYIN, sizeof (dld_ioc_door_t), 1141 drv_ioc_doorserver, {PRIV_SYS_DL_CONFIG}}, 1142 {DLDIOC_RENAME, DLDCOPYIN, sizeof (dld_ioc_rename_t), 1143 drv_ioc_rename, {PRIV_SYS_DL_CONFIG}}, 1144 {DLDIOC_MACADDRGET, DLDCOPYINOUT, sizeof (dld_ioc_macaddrget_t), 1145 drv_ioc_macaddrget, {PRIV_SYS_DL_CONFIG}}, 1146 {DLDIOC_ADDFLOW, DLDCOPYIN, sizeof (dld_ioc_addflow_t), 1147 drv_ioc_addflow, {PRIV_SYS_DL_CONFIG}}, 1148 {DLDIOC_REMOVEFLOW, DLDCOPYIN, sizeof (dld_ioc_removeflow_t), 1149 drv_ioc_removeflow, {PRIV_SYS_DL_CONFIG}}, 1150 {DLDIOC_MODIFYFLOW, DLDCOPYIN, sizeof (dld_ioc_modifyflow_t), 1151 drv_ioc_modifyflow, {PRIV_SYS_DL_CONFIG}}, 1152 {DLDIOC_WALKFLOW, DLDCOPYINOUT, sizeof (dld_ioc_walkflow_t), 1153 drv_ioc_walkflow, {NULL}}, 1154 {DLDIOC_USAGELOG, DLDCOPYIN, sizeof (dld_ioc_usagelog_t), 1155 drv_ioc_usagelog, {PRIV_SYS_DL_CONFIG}}, 1156 {DLDIOC_SETMACPROP, DLDCOPYIN, sizeof (dld_ioc_macprop_t), 1157 drv_ioc_setprop, {PRIV_SYS_DL_CONFIG}}, |
984 {DLDIOC_GETMACPROP, DLDCOPYIN, sizeof (dld_ioc_macprop_t), | 1158 {DLDIOC_GETMACPROP, DLDCOPYIN, sizeof (dld_ioc_macprop_t), |
985 drv_ioc_getprop}, 986 {DLDIOC_SETMACPROP, DLDCOPYIN | DLDDLCONFIG, sizeof (dld_ioc_macprop_t), 987 drv_ioc_setprop} | 1159 drv_ioc_getprop, {NULL}}, 1160 {DLDIOC_GETHWGRP, DLDCOPYINOUT, sizeof (dld_ioc_hwgrpget_t), 1161 drv_ioc_hwgrpget, {PRIV_SYS_DL_CONFIG}}, |
988}; 989 990typedef struct dld_ioc_modentry { 991 uint16_t dim_modid; /* Top 16 bits of ioctl command */ 992 char *dim_modname; /* Module to be loaded */ 993 dld_ioc_info_t *dim_list; /* array of ioctl structures */ 994 uint_t dim_count; /* number of elements in dim_list */ 995} dld_ioc_modentry_t; --- 89 unchanged lines hidden (view full) --- 1085 break; 1086 } 1087 if (i == dim->dim_count) { 1088 err = ENOTSUP; 1089 goto done; 1090 } 1091 1092 info = &dim->dim_list[i]; | 1162}; 1163 1164typedef struct dld_ioc_modentry { 1165 uint16_t dim_modid; /* Top 16 bits of ioctl command */ 1166 char *dim_modname; /* Module to be loaded */ 1167 dld_ioc_info_t *dim_list; /* array of ioctl structures */ 1168 uint_t dim_count; /* number of elements in dim_list */ 1169} dld_ioc_modentry_t; --- 89 unchanged lines hidden (view full) --- 1259 break; 1260 } 1261 if (i == dim->dim_count) { 1262 err = ENOTSUP; 1263 goto done; 1264 } 1265 1266 info = &dim->dim_list[i]; |
1093 1094 if ((info->di_flags & DLDDLCONFIG) && secpolicy_dl_config(cred) != 0) { 1095 err = EPERM; | 1267 if ((err = drv_check_policy(info, cred)) != 0) |
1096 goto done; | 1268 goto done; |
1097 } | |
1098 1099 sz = info->di_argsize; 1100 if ((buf = kmem_zalloc(sz, KM_NOSLEEP)) == NULL) { 1101 err = ENOMEM; 1102 goto done; 1103 } 1104 1105 if ((info->di_flags & DLDCOPYIN) && 1106 ddi_copyin((void *)arg, buf, sz, mode) != 0) { 1107 err = EFAULT; 1108 goto done; 1109 } 1110 | 1269 1270 sz = info->di_argsize; 1271 if ((buf = kmem_zalloc(sz, KM_NOSLEEP)) == NULL) { 1272 err = ENOMEM; 1273 goto done; 1274 } 1275 1276 if ((info->di_flags & DLDCOPYIN) && 1277 ddi_copyin((void *)arg, buf, sz, mode) != 0) { 1278 err = EFAULT; 1279 goto done; 1280 } 1281 |
1111 err = info->di_func(buf, arg, mode, cred); | 1282 err = info->di_func(buf, arg, mode, cred, rvalp); |
1112 1113 if ((info->di_flags & DLDCOPYOUT) && 1114 ddi_copyout(buf, (void *)arg, sz, mode) != 0 && err == 0) 1115 err = EFAULT; 1116 1117done: 1118 if (buf != NULL) 1119 kmem_free(buf, sz); 1120 if (dip != NULL) 1121 ddi_release_devi(dip); 1122 return (err); 1123} | 1283 1284 if ((info->di_flags & DLDCOPYOUT) && 1285 ddi_copyout(buf, (void *)arg, sz, mode) != 0 && err == 0) 1286 err = EFAULT; 1287 1288done: 1289 if (buf != NULL) 1290 kmem_free(buf, sz); 1291 if (dip != NULL) 1292 ddi_release_devi(dip); 1293 return (err); 1294} |