344 mblk_t *nmp;
345 mod_hash_key_t key;
346 uint_t npacket;
347 boolean_t accepted;
348 dls_rx_t ds_rx, nds_rx;
349 void *ds_rx_arg, *nds_rx_arg;
350 uint16_t vid;
351 int err, rval;
352
353 /*
354 * Walk the packet chain.
355 */
356 for (; mp != NULL; mp = nextp) {
357 /*
358 * Wipe the accepted state.
359 */
360 accepted = B_FALSE;
361
362 DLS_PREPARE_PKT(dlp->dl_mh, mp, &mhi, err);
363 if (err != 0) {
364 atomic_add_32(&(dlp->dl_unknowns), 1);
365 nextp = mp->b_next;
366 mp->b_next = NULL;
367 freemsg(mp);
368 continue;
369 }
370
371 /*
372 * Grab the longest sub-chain we can process as a single
373 * unit.
374 */
375 nextp = i_dls_link_subchain(dlp, mp, &mhi, &npacket);
376 ASSERT(npacket != 0);
377
378 vid = VLAN_ID(mhi.mhi_tci);
379
380 if (mhi.mhi_istagged) {
381 /*
382 * If it is tagged traffic, send it upstream to
383 * all dld_str_t which are attached to the physical
384 * link and bound to SAP 0x8100.
518 */
519 if (dsp->ds_vlan_mph != NULL) {
520 uint8_t prim_addr[MAXMACADDRLEN];
521 size_t addr_length = dsp->ds_mip->mi_addr_length;
522
523 if (!(mhi.mhi_istagged))
524 goto drop;
525 ASSERT(dsp->ds_mh != NULL);
526 mac_unicast_primary_get(dsp->ds_mh, (uint8_t *)prim_addr);
527 if (memcmp(mhi.mhi_daddr, prim_addr, addr_length) != 0)
528 goto drop;
529
530 if (!dls_accept(dsp, &mhi, &ds_rx, &ds_rx_arg))
531 goto drop;
532
533 ds_rx(ds_rx_arg, NULL, mp, &mhi);
534 return;
535 }
536
537 drop:
538 atomic_add_32(&dlp->dl_unknowns, 1);
539 freemsg(mp);
540 }
541
542 /* ARGSUSED */
543 void
544 dls_rx_promisc(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
545 boolean_t loopback)
546 {
547 dld_str_t *dsp = arg;
548 dls_link_t *dlp = dsp->ds_dlp;
549 mac_header_info_t mhi;
550 dls_rx_t ds_rx;
551 void *ds_rx_arg;
552 int err;
553 dls_head_t *dhp;
554 mod_hash_key_t key;
555
556 DLS_PREPARE_PKT(dlp->dl_mh, mp, &mhi, err);
557 if (err != 0)
558 goto drop;
559
560 /*
561 * In order to filter out sap pkt that no dls channel listens, search
562 * the hash table trying to find a dld_str_t eligible to receive the pkt
563 */
564 if ((dsp->ds_promisc & DLS_PROMISC_SAP) == 0) {
565 key = MAKE_KEY(mhi.mhi_bindsap);
566 if (mod_hash_find(dsp->ds_dlp->dl_str_hash, key,
567 (mod_hash_val_t *)&dhp) != 0)
568 goto drop;
569 }
570
571 if (!dls_accept_promisc(dsp, &mhi, &ds_rx, &ds_rx_arg, loopback))
572 goto drop;
573
574 ds_rx(ds_rx_arg, NULL, mp, &mhi);
575 return;
576
577 drop:
578 atomic_add_32(&dlp->dl_unknowns, 1);
579 freemsg(mp);
580 }
581
582 static void
583 i_dls_link_destroy(dls_link_t *dlp)
584 {
585 ASSERT(dlp->dl_nactive == 0);
586 ASSERT(dlp->dl_impl_count == 0);
587 ASSERT(dlp->dl_zone_ref == 0);
588
589 /*
590 * Free the structure back to the cache.
591 */
592 if (dlp->dl_mch != NULL)
593 mac_client_close(dlp->dl_mch, 0);
594
595 if (dlp->dl_mh != NULL) {
596 ASSERT(MAC_PERIM_HELD(dlp->dl_mh));
597 mac_close(dlp->dl_mh);
598 }
715 (mod_hash_val_t *)&dlp)) == 0)
716 goto done;
717
718 ASSERT(err == MH_ERR_NOTFOUND);
719 if (!create)
720 return (ENOENT);
721
722 /*
723 * We didn't find anything so we need to create one.
724 */
725 if ((err = i_dls_link_create(name, &dlp)) != 0)
726 return (err);
727
728 /*
729 * Insert the dls_link_t.
730 */
731 err = mod_hash_insert(i_dls_link_hash, (mod_hash_key_t)dlp->dl_name,
732 (mod_hash_val_t)dlp);
733 ASSERT(err == 0);
734
735 atomic_add_32(&i_dls_link_count, 1);
736 ASSERT(i_dls_link_count != 0);
737
738 done:
739 ASSERT(MAC_PERIM_HELD(dlp->dl_mh));
740 /*
741 * Bump the reference count and hand back the reference.
742 */
743 dlp->dl_ref++;
744 *dlpp = dlp;
745 return (0);
746 }
747
748 int
749 dls_link_hold_create(const char *name, dls_link_t **dlpp)
750 {
751 return (dls_link_hold_common(name, dlpp, B_TRUE));
752 }
753
754 int
755 dls_link_hold(const char *name, dls_link_t **dlpp)
802
803 void
804 dls_link_rele(dls_link_t *dlp)
805 {
806 mod_hash_val_t val;
807
808 ASSERT(MAC_PERIM_HELD(dlp->dl_mh));
809 /*
810 * Check if there are any more references.
811 */
812 if (--dlp->dl_ref == 0) {
813 (void) mod_hash_remove(i_dls_link_hash,
814 (mod_hash_key_t)dlp->dl_name, &val);
815 ASSERT(dlp == (dls_link_t *)val);
816
817 /*
818 * Destroy the dls_link_t.
819 */
820 i_dls_link_destroy(dlp);
821 ASSERT(i_dls_link_count > 0);
822 atomic_add_32(&i_dls_link_count, -1);
823 }
824 }
825
826 int
827 dls_link_rele_by_name(const char *name)
828 {
829 dls_link_t *dlp;
830
831 if (mod_hash_find(i_dls_link_hash, (mod_hash_key_t)name,
832 (mod_hash_val_t *)&dlp) != 0)
833 return (ENOENT);
834
835 ASSERT(MAC_PERIM_HELD(dlp->dl_mh));
836
837 /*
838 * Must fail detach if mac client is busy.
839 */
840 ASSERT(dlp->dl_ref > 0 && dlp->dl_mch != NULL);
841 if (mac_link_has_flows(dlp->dl_mch))
842 return (ENOTEMPTY);
|
344 mblk_t *nmp;
345 mod_hash_key_t key;
346 uint_t npacket;
347 boolean_t accepted;
348 dls_rx_t ds_rx, nds_rx;
349 void *ds_rx_arg, *nds_rx_arg;
350 uint16_t vid;
351 int err, rval;
352
353 /*
354 * Walk the packet chain.
355 */
356 for (; mp != NULL; mp = nextp) {
357 /*
358 * Wipe the accepted state.
359 */
360 accepted = B_FALSE;
361
362 DLS_PREPARE_PKT(dlp->dl_mh, mp, &mhi, err);
363 if (err != 0) {
364 atomic_inc_32(&(dlp->dl_unknowns));
365 nextp = mp->b_next;
366 mp->b_next = NULL;
367 freemsg(mp);
368 continue;
369 }
370
371 /*
372 * Grab the longest sub-chain we can process as a single
373 * unit.
374 */
375 nextp = i_dls_link_subchain(dlp, mp, &mhi, &npacket);
376 ASSERT(npacket != 0);
377
378 vid = VLAN_ID(mhi.mhi_tci);
379
380 if (mhi.mhi_istagged) {
381 /*
382 * If it is tagged traffic, send it upstream to
383 * all dld_str_t which are attached to the physical
384 * link and bound to SAP 0x8100.
518 */
519 if (dsp->ds_vlan_mph != NULL) {
520 uint8_t prim_addr[MAXMACADDRLEN];
521 size_t addr_length = dsp->ds_mip->mi_addr_length;
522
523 if (!(mhi.mhi_istagged))
524 goto drop;
525 ASSERT(dsp->ds_mh != NULL);
526 mac_unicast_primary_get(dsp->ds_mh, (uint8_t *)prim_addr);
527 if (memcmp(mhi.mhi_daddr, prim_addr, addr_length) != 0)
528 goto drop;
529
530 if (!dls_accept(dsp, &mhi, &ds_rx, &ds_rx_arg))
531 goto drop;
532
533 ds_rx(ds_rx_arg, NULL, mp, &mhi);
534 return;
535 }
536
537 drop:
538 atomic_inc_32(&dlp->dl_unknowns);
539 freemsg(mp);
540 }
541
542 /* ARGSUSED */
543 void
544 dls_rx_promisc(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
545 boolean_t loopback)
546 {
547 dld_str_t *dsp = arg;
548 dls_link_t *dlp = dsp->ds_dlp;
549 mac_header_info_t mhi;
550 dls_rx_t ds_rx;
551 void *ds_rx_arg;
552 int err;
553 dls_head_t *dhp;
554 mod_hash_key_t key;
555
556 DLS_PREPARE_PKT(dlp->dl_mh, mp, &mhi, err);
557 if (err != 0)
558 goto drop;
559
560 /*
561 * In order to filter out sap pkt that no dls channel listens, search
562 * the hash table trying to find a dld_str_t eligible to receive the pkt
563 */
564 if ((dsp->ds_promisc & DLS_PROMISC_SAP) == 0) {
565 key = MAKE_KEY(mhi.mhi_bindsap);
566 if (mod_hash_find(dsp->ds_dlp->dl_str_hash, key,
567 (mod_hash_val_t *)&dhp) != 0)
568 goto drop;
569 }
570
571 if (!dls_accept_promisc(dsp, &mhi, &ds_rx, &ds_rx_arg, loopback))
572 goto drop;
573
574 ds_rx(ds_rx_arg, NULL, mp, &mhi);
575 return;
576
577 drop:
578 atomic_inc_32(&dlp->dl_unknowns);
579 freemsg(mp);
580 }
581
582 static void
583 i_dls_link_destroy(dls_link_t *dlp)
584 {
585 ASSERT(dlp->dl_nactive == 0);
586 ASSERT(dlp->dl_impl_count == 0);
587 ASSERT(dlp->dl_zone_ref == 0);
588
589 /*
590 * Free the structure back to the cache.
591 */
592 if (dlp->dl_mch != NULL)
593 mac_client_close(dlp->dl_mch, 0);
594
595 if (dlp->dl_mh != NULL) {
596 ASSERT(MAC_PERIM_HELD(dlp->dl_mh));
597 mac_close(dlp->dl_mh);
598 }
715 (mod_hash_val_t *)&dlp)) == 0)
716 goto done;
717
718 ASSERT(err == MH_ERR_NOTFOUND);
719 if (!create)
720 return (ENOENT);
721
722 /*
723 * We didn't find anything so we need to create one.
724 */
725 if ((err = i_dls_link_create(name, &dlp)) != 0)
726 return (err);
727
728 /*
729 * Insert the dls_link_t.
730 */
731 err = mod_hash_insert(i_dls_link_hash, (mod_hash_key_t)dlp->dl_name,
732 (mod_hash_val_t)dlp);
733 ASSERT(err == 0);
734
735 atomic_inc_32(&i_dls_link_count);
736 ASSERT(i_dls_link_count != 0);
737
738 done:
739 ASSERT(MAC_PERIM_HELD(dlp->dl_mh));
740 /*
741 * Bump the reference count and hand back the reference.
742 */
743 dlp->dl_ref++;
744 *dlpp = dlp;
745 return (0);
746 }
747
748 int
749 dls_link_hold_create(const char *name, dls_link_t **dlpp)
750 {
751 return (dls_link_hold_common(name, dlpp, B_TRUE));
752 }
753
754 int
755 dls_link_hold(const char *name, dls_link_t **dlpp)
802
803 void
804 dls_link_rele(dls_link_t *dlp)
805 {
806 mod_hash_val_t val;
807
808 ASSERT(MAC_PERIM_HELD(dlp->dl_mh));
809 /*
810 * Check if there are any more references.
811 */
812 if (--dlp->dl_ref == 0) {
813 (void) mod_hash_remove(i_dls_link_hash,
814 (mod_hash_key_t)dlp->dl_name, &val);
815 ASSERT(dlp == (dls_link_t *)val);
816
817 /*
818 * Destroy the dls_link_t.
819 */
820 i_dls_link_destroy(dlp);
821 ASSERT(i_dls_link_count > 0);
822 atomic_dec_32(&i_dls_link_count);
823 }
824 }
825
826 int
827 dls_link_rele_by_name(const char *name)
828 {
829 dls_link_t *dlp;
830
831 if (mod_hash_find(i_dls_link_hash, (mod_hash_key_t)name,
832 (mod_hash_val_t *)&dlp) != 0)
833 return (ENOENT);
834
835 ASSERT(MAC_PERIM_HELD(dlp->dl_mh));
836
837 /*
838 * Must fail detach if mac client is busy.
839 */
840 ASSERT(dlp->dl_ref > 0 && dlp->dl_mch != NULL);
841 if (mac_link_has_flows(dlp->dl_mch))
842 return (ENOTEMPTY);
|