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
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * IEEE 802.3ad Link Aggregation - Receive
28 *
29 * Implements the collector function.
30 * Manages the RX resources exposed by a link aggregation group.
31 */
32
33 #include <sys/sysmacros.h>
34 #include <sys/ddi.h>
35 #include <sys/sunddi.h>
36 #include <sys/strsun.h>
37 #include <sys/strsubr.h>
38 #include <sys/byteorder.h>
39 #include <sys/aggr.h>
40 #include <sys/aggr_impl.h>
41
42 static void
43 aggr_mac_rx(mac_handle_t lg_mh, mac_resource_handle_t mrh, mblk_t *mp)
51 }
52
53 void
54 aggr_recv_lacp(aggr_port_t *port, mac_resource_handle_t mrh, mblk_t *mp)
55 {
56 aggr_grp_t *grp = port->lp_grp;
57
58 /* in promiscuous mode, send copy of packet up */
59 if (grp->lg_promisc) {
60 mblk_t *nmp = copymsg(mp);
61
62 if (nmp != NULL)
63 aggr_mac_rx(grp->lg_mh, mrh, nmp);
64 }
65
66 aggr_lacp_rx_enqueue(port, mp);
67 }
68
69 /*
70 * Callback function invoked by MAC service module when packets are
71 * made available by a MAC port.
72 */
73 /* ARGSUSED */
74 void
75 aggr_recv_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
76 boolean_t loopback)
77 {
78 aggr_port_t *port = (aggr_port_t *)arg;
79 aggr_grp_t *grp = port->lp_grp;
80
81 if (grp->lg_lacp_mode == AGGR_LACP_OFF) {
82 aggr_mac_rx(grp->lg_mh, mrh, mp);
83 } else {
84 mblk_t *cmp, *last, *head;
85 struct ether_header *ehp;
86 uint16_t sap;
87
88 /* filter out slow protocol packets (LACP & Marker) */
89 last = NULL;
90 head = cmp = mp;
91 while (cmp != NULL) {
92 if (MBLKL(cmp) < sizeof (struct ether_header)) {
93 /* packet too short */
94 if (head == cmp) {
95 /* no packets accumulated */
96 head = cmp->b_next;
97 cmp->b_next = NULL;
98 freemsg(cmp);
99 cmp = head;
100 } else {
143 }
144 /* unlink and pass up LACP packets */
145 head = cmp->b_next;
146 cmp->b_next = NULL;
147 aggr_recv_lacp(port, mrh, cmp);
148 cmp = head;
149 last = NULL;
150 }
151 } else {
152 last = cmp;
153 cmp = cmp->b_next;
154 }
155 }
156 if (head != NULL) {
157 if (port->lp_collector_enabled)
158 aggr_mac_rx(grp->lg_mh, mrh, head);
159 else
160 freemsgchain(head);
161 }
162 }
163 }
|
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
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 OmniTI Computer Consulting, Inc All rights reserved.
25 */
26
27 /*
28 * IEEE 802.3ad Link Aggregation - Receive
29 *
30 * Implements the collector function.
31 * Manages the RX resources exposed by a link aggregation group.
32 */
33
34 #include <sys/sysmacros.h>
35 #include <sys/ddi.h>
36 #include <sys/sunddi.h>
37 #include <sys/strsun.h>
38 #include <sys/strsubr.h>
39 #include <sys/byteorder.h>
40 #include <sys/aggr.h>
41 #include <sys/aggr_impl.h>
42
43 static void
44 aggr_mac_rx(mac_handle_t lg_mh, mac_resource_handle_t mrh, mblk_t *mp)
52 }
53
54 void
55 aggr_recv_lacp(aggr_port_t *port, mac_resource_handle_t mrh, mblk_t *mp)
56 {
57 aggr_grp_t *grp = port->lp_grp;
58
59 /* in promiscuous mode, send copy of packet up */
60 if (grp->lg_promisc) {
61 mblk_t *nmp = copymsg(mp);
62
63 if (nmp != NULL)
64 aggr_mac_rx(grp->lg_mh, mrh, nmp);
65 }
66
67 aggr_lacp_rx_enqueue(port, mp);
68 }
69
70 /*
71 * Callback function invoked by MAC service module when packets are
72 * made available by a MAC port, both in promisc_on mode and not.
73 */
74 /* ARGSUSED */
75 static void
76 aggr_recv_path_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
77 boolean_t loopback, boolean_t promisc_path)
78 {
79 aggr_port_t *port = (aggr_port_t *)arg;
80 aggr_grp_t *grp = port->lp_grp;
81
82 /* In the case where lp_promisc_on has been turned on to
83 * compensate for insufficient hardware MAC matching and
84 * hardware rings are not in use we will fall back to
85 * using flows for delivery which can result in duplicates
86 * pushed up the stack. Only respect the chosen path.
87 */
88 if (port->lp_promisc_on != promisc_path) {
89 freemsgchain(mp);
90 return;
91 }
92
93 if (grp->lg_lacp_mode == AGGR_LACP_OFF) {
94 aggr_mac_rx(grp->lg_mh, mrh, mp);
95 } else {
96 mblk_t *cmp, *last, *head;
97 struct ether_header *ehp;
98 uint16_t sap;
99
100 /* filter out slow protocol packets (LACP & Marker) */
101 last = NULL;
102 head = cmp = mp;
103 while (cmp != NULL) {
104 if (MBLKL(cmp) < sizeof (struct ether_header)) {
105 /* packet too short */
106 if (head == cmp) {
107 /* no packets accumulated */
108 head = cmp->b_next;
109 cmp->b_next = NULL;
110 freemsg(cmp);
111 cmp = head;
112 } else {
155 }
156 /* unlink and pass up LACP packets */
157 head = cmp->b_next;
158 cmp->b_next = NULL;
159 aggr_recv_lacp(port, mrh, cmp);
160 cmp = head;
161 last = NULL;
162 }
163 } else {
164 last = cmp;
165 cmp = cmp->b_next;
166 }
167 }
168 if (head != NULL) {
169 if (port->lp_collector_enabled)
170 aggr_mac_rx(grp->lg_mh, mrh, head);
171 else
172 freemsgchain(head);
173 }
174 }
175 }
176
177 /* ARGSUSED */
178 void
179 aggr_recv_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
180 boolean_t loopback)
181 {
182 aggr_recv_path_cb(arg, mrh, mp, loopback, B_FALSE);
183 }
184
185 /* ARGSUSED */
186 void
187 aggr_recv_promisc_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
188 boolean_t loopback)
189 {
190 aggr_recv_path_cb(arg, mrh, mp, loopback, B_TRUE);
191 }
|