154
155 ASSERT(MAC_PERIM_HELD(dsp->ds_mh));
156
157 /*
158 * Check to see the value is legal for the media type.
159 */
160 if (!mac_sap_verify(dsp->ds_mh, sap, &dls_sap))
161 return (EINVAL);
162
163 if (dsp->ds_promisc & DLS_PROMISC_SAP)
164 dls_sap = DLS_SAP_PROMISC;
165
166 /*
167 * Set up the dld_str_t to mark it as able to receive packets.
168 */
169 dsp->ds_sap = sap;
170
171 /*
172 * The MAC layer does the VLAN demultiplexing and will only pass up
173 * untagged packets to non-promiscuous primary MAC clients. In order to
174 * support the binding to the VLAN SAP which is required by DLPI, dls
175 * needs to get a copy of all tagged packets when the client binds to
176 * the VLAN SAP. We do this by registering a separate promiscuous
177 * callback for each dls client binding to that SAP.
178 *
179 * Note: even though there are two promiscuous handles in dld_str_t,
180 * ds_mph is for the regular promiscuous mode, ds_vlan_mph is the handle
181 * to receive VLAN pkt when promiscuous mode is not on. Only one of
182 * them can be non-NULL at the same time, to avoid receiving dup copies
183 * of pkts.
184 */
185 if (sap == ETHERTYPE_VLAN && dsp->ds_promisc == 0) {
186 int err;
187
188 if (dsp->ds_vlan_mph != NULL)
189 return (EINVAL);
190 err = mac_promisc_add(dsp->ds_mch,
191 MAC_CLIENT_PROMISC_ALL, dls_rx_vlan_promisc, dsp,
192 &dsp->ds_vlan_mph, MAC_PROMISC_FLAGS_NO_PHYS);
193
194 if (err == 0 && dsp->ds_nonip &&
195 dsp->ds_dlp->dl_nonip_cnt++ == 0)
196 mac_rx_bypass_disable(dsp->ds_mch);
197
198 return (err);
199 }
200
201 /*
202 * Now bind the dld_str_t by adding it into the hash table in the
203 * dls_link_t.
635 loopback));
636 }
637
638 int
639 dls_mac_active_set(dls_link_t *dlp)
640 {
641 int err = 0;
642
643 /*
644 * First client; add the primary unicast address.
645 */
646 if (dlp->dl_nactive == 0) {
647 /*
648 * First client; add the primary unicast address.
649 */
650 mac_diag_t diag;
651
652 /* request the primary MAC address */
653 if ((err = mac_unicast_add(dlp->dl_mch, NULL,
654 MAC_UNICAST_PRIMARY | MAC_UNICAST_TAG_DISABLE |
655 MAC_UNICAST_DISABLE_TX_VID_CHECK, &dlp->dl_mah, 0,
656 &diag)) != 0) {
657 return (err);
658 }
659
660 /*
661 * Set the function to start receiving packets.
662 */
663 mac_rx_set(dlp->dl_mch, i_dls_link_rx, dlp);
664 }
665 dlp->dl_nactive++;
666 return (0);
667 }
668
669 void
670 dls_mac_active_clear(dls_link_t *dlp)
671 {
672 if (--dlp->dl_nactive == 0) {
673 ASSERT(dlp->dl_mah != NULL);
674 (void) mac_unicast_remove(dlp->dl_mch, dlp->dl_mah);
675 dlp->dl_mah = NULL;
676 mac_rx_clear(dlp->dl_mch);
|
154
155 ASSERT(MAC_PERIM_HELD(dsp->ds_mh));
156
157 /*
158 * Check to see the value is legal for the media type.
159 */
160 if (!mac_sap_verify(dsp->ds_mh, sap, &dls_sap))
161 return (EINVAL);
162
163 if (dsp->ds_promisc & DLS_PROMISC_SAP)
164 dls_sap = DLS_SAP_PROMISC;
165
166 /*
167 * Set up the dld_str_t to mark it as able to receive packets.
168 */
169 dsp->ds_sap = sap;
170
171 /*
172 * The MAC layer does the VLAN demultiplexing and will only pass up
173 * untagged packets to non-promiscuous primary MAC clients. In order to
174 * support binding to the VLAN SAP, which is required by DLPI, DLS
175 * needs to get a copy of all tagged packets when the client binds to
176 * the VLAN SAP. We do this by registering a separate promiscuous
177 * callback for each DLS client binding to that SAP.
178 *
179 * Note: even though there are two promiscuous handles in dld_str_t,
180 * ds_mph is for the regular promiscuous mode, ds_vlan_mph is the handle
181 * to receive VLAN traffic when promiscuous mode is not on. Only one of
182 * them can be non-NULL at the same time, to avoid receiving duplicate
183 * copies of packets.
184 */
185 if (sap == ETHERTYPE_VLAN && dsp->ds_promisc == 0) {
186 int err;
187
188 if (dsp->ds_vlan_mph != NULL)
189 return (EINVAL);
190 err = mac_promisc_add(dsp->ds_mch,
191 MAC_CLIENT_PROMISC_ALL, dls_rx_vlan_promisc, dsp,
192 &dsp->ds_vlan_mph, MAC_PROMISC_FLAGS_NO_PHYS);
193
194 if (err == 0 && dsp->ds_nonip &&
195 dsp->ds_dlp->dl_nonip_cnt++ == 0)
196 mac_rx_bypass_disable(dsp->ds_mch);
197
198 return (err);
199 }
200
201 /*
202 * Now bind the dld_str_t by adding it into the hash table in the
203 * dls_link_t.
635 loopback));
636 }
637
638 int
639 dls_mac_active_set(dls_link_t *dlp)
640 {
641 int err = 0;
642
643 /*
644 * First client; add the primary unicast address.
645 */
646 if (dlp->dl_nactive == 0) {
647 /*
648 * First client; add the primary unicast address.
649 */
650 mac_diag_t diag;
651
652 /* request the primary MAC address */
653 if ((err = mac_unicast_add(dlp->dl_mch, NULL,
654 MAC_UNICAST_PRIMARY | MAC_UNICAST_TAG_DISABLE |
655 MAC_UNICAST_DISABLE_TX_VID_CHECK, &dlp->dl_mah,
656 VLAN_ID_NONE, &diag)) != 0) {
657 return (err);
658 }
659
660 /*
661 * Set the function to start receiving packets.
662 */
663 mac_rx_set(dlp->dl_mch, i_dls_link_rx, dlp);
664 }
665 dlp->dl_nactive++;
666 return (0);
667 }
668
669 void
670 dls_mac_active_clear(dls_link_t *dlp)
671 {
672 if (--dlp->dl_nactive == 0) {
673 ASSERT(dlp->dl_mah != NULL);
674 (void) mac_unicast_remove(dlp->dl_mch, dlp->dl_mah);
675 dlp->dl_mah = NULL;
676 mac_rx_clear(dlp->dl_mch);
|