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.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * IEEE 802.3ad Link Aggregation - Receive
29 * Implements the collector function.
30 * Manages the RX resources exposed by a link aggregation group.
33 #include <sys/sysmacros.h>
35 #include <sys/sunddi.h>
36 #include <sys/strsun.h>
37 #include <sys/strsubr.h>
38 #include <sys/byteorder.h>
40 #include <sys/aggr_impl.h>
43 aggr_mac_rx(mac_handle_t lg_mh
, mac_resource_handle_t mrh
, mblk_t
*mp
)
46 mac_rx(lg_mh
, mrh
, mp
);
48 aggr_pseudo_rx_ring_t
*ring
= (aggr_pseudo_rx_ring_t
*)mrh
;
49 mac_rx_ring(lg_mh
, ring
->arr_rh
, mp
, ring
->arr_gen
);
54 aggr_recv_lacp(aggr_port_t
*port
, mac_resource_handle_t mrh
, mblk_t
*mp
)
56 aggr_grp_t
*grp
= port
->lp_grp
;
58 /* in promiscuous mode, send copy of packet up */
59 if (grp
->lg_promisc
) {
60 mblk_t
*nmp
= copymsg(mp
);
63 aggr_mac_rx(grp
->lg_mh
, mrh
, nmp
);
66 aggr_lacp_rx_enqueue(port
, mp
);
70 * Callback function invoked by MAC service module when packets are
71 * made available by a MAC port.
75 aggr_recv_cb(void *arg
, mac_resource_handle_t mrh
, mblk_t
*mp
,
78 aggr_port_t
*port
= (aggr_port_t
*)arg
;
79 aggr_grp_t
*grp
= port
->lp_grp
;
81 if (grp
->lg_lacp_mode
== AGGR_LACP_OFF
) {
82 aggr_mac_rx(grp
->lg_mh
, mrh
, mp
);
84 mblk_t
*cmp
, *last
, *head
;
85 struct ether_header
*ehp
;
88 /* filter out slow protocol packets (LACP & Marker) */
92 if (MBLKL(cmp
) < sizeof (struct ether_header
)) {
93 /* packet too short */
95 /* no packets accumulated */
101 /* send up accumulated packets */
103 if (port
->lp_collector_enabled
) {
104 aggr_mac_rx(grp
->lg_mh
, mrh
,
117 ehp
= (struct ether_header
*)cmp
->b_rptr
;
119 sap
= ntohs(ehp
->ether_type
);
120 if (sap
== ETHERTYPE_SLOW
) {
122 * LACP or Marker packet. Send up pending
123 * chain, and send LACP/Marker packet
127 /* first packet of chain */
128 ASSERT(last
== NULL
);
131 aggr_recv_lacp(port
, mrh
, cmp
);
134 /* previously accumulated packets */
135 ASSERT(last
!= NULL
);
136 /* send up non-LACP packets */
138 if (port
->lp_collector_enabled
) {
139 aggr_mac_rx(grp
->lg_mh
, mrh
,
144 /* unlink and pass up LACP packets */
147 aggr_recv_lacp(port
, mrh
, cmp
);
157 if (port
->lp_collector_enabled
)
158 aggr_mac_rx(grp
->lg_mh
, mrh
, head
);