Print this page
11490 SRS ring polling disabled for VLANs
11491 Want DLS bypass for VLAN traffic
11492 add VLVF bypass to ixgbe core
2869 duplicate packets with vnics over aggrs
11489 DLS stat delete and aggr kstat can deadlock
Portions contributed by: Theo Schlossnagle <jesus@omniti.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Dan McDonald <danmcd@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/aggr/aggr_recv.c
+++ new/usr/src/uts/common/io/aggr/aggr_recv.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + * Copyright 2012 OmniTI Computer Consulting, Inc All rights reserved.
24 25 */
25 26
26 27 /*
27 28 * IEEE 802.3ad Link Aggregation - Receive
28 29 *
29 30 * Implements the collector function.
30 31 * Manages the RX resources exposed by a link aggregation group.
31 32 */
32 33
33 34 #include <sys/sysmacros.h>
34 35 #include <sys/ddi.h>
35 36 #include <sys/sunddi.h>
36 37 #include <sys/strsun.h>
37 38 #include <sys/strsubr.h>
38 39 #include <sys/byteorder.h>
39 40 #include <sys/aggr.h>
40 41 #include <sys/aggr_impl.h>
41 42
42 43 static void
43 44 aggr_mac_rx(mac_handle_t lg_mh, mac_resource_handle_t mrh, mblk_t *mp)
44 45 {
45 46 if (mrh == NULL) {
46 47 mac_rx(lg_mh, mrh, mp);
47 48 } else {
48 49 aggr_pseudo_rx_ring_t *ring = (aggr_pseudo_rx_ring_t *)mrh;
49 50 mac_rx_ring(lg_mh, ring->arr_rh, mp, ring->arr_gen);
50 51 }
51 52 }
52 53
53 54 void
54 55 aggr_recv_lacp(aggr_port_t *port, mac_resource_handle_t mrh, mblk_t *mp)
55 56 {
56 57 aggr_grp_t *grp = port->lp_grp;
57 58
58 59 /* in promiscuous mode, send copy of packet up */
59 60 if (grp->lg_promisc) {
60 61 mblk_t *nmp = copymsg(mp);
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
61 62
62 63 if (nmp != NULL)
63 64 aggr_mac_rx(grp->lg_mh, mrh, nmp);
64 65 }
65 66
66 67 aggr_lacp_rx_enqueue(port, mp);
67 68 }
68 69
69 70 /*
70 71 * Callback function invoked by MAC service module when packets are
71 - * made available by a MAC port.
72 + * made available by a MAC port, both in promisc_on mode and not.
72 73 */
73 74 /* ARGSUSED */
74 -void
75 -aggr_recv_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
76 - boolean_t loopback)
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)
77 78 {
78 79 aggr_port_t *port = (aggr_port_t *)arg;
79 80 aggr_grp_t *grp = port->lp_grp;
80 81
82 + /*
83 + * In the case where lp_promisc_on has been turned on to
84 + * compensate for insufficient hardware MAC matching and
85 + * hardware rings are not in use we will fall back to
86 + * using flows for delivery which can result in duplicates
87 + * pushed up the stack. Only respect the chosen path.
88 + */
89 + if (port->lp_promisc_on != promisc_path) {
90 + freemsgchain(mp);
91 + return;
92 + }
93 +
81 94 if (grp->lg_lacp_mode == AGGR_LACP_OFF) {
82 95 aggr_mac_rx(grp->lg_mh, mrh, mp);
83 96 } else {
84 97 mblk_t *cmp, *last, *head;
85 98 struct ether_header *ehp;
86 99 uint16_t sap;
87 100
88 101 /* filter out slow protocol packets (LACP & Marker) */
89 102 last = NULL;
90 103 head = cmp = mp;
91 104 while (cmp != NULL) {
92 105 if (MBLKL(cmp) < sizeof (struct ether_header)) {
93 106 /* packet too short */
94 107 if (head == cmp) {
95 108 /* no packets accumulated */
96 109 head = cmp->b_next;
97 110 cmp->b_next = NULL;
98 111 freemsg(cmp);
99 112 cmp = head;
100 113 } else {
101 114 /* send up accumulated packets */
102 115 last->b_next = NULL;
103 116 if (port->lp_collector_enabled) {
104 117 aggr_mac_rx(grp->lg_mh, mrh,
105 118 head);
106 119 } else {
107 120 freemsgchain(head);
108 121 }
109 122 head = cmp->b_next;
110 123 cmp->b_next = NULL;
111 124 freemsg(cmp);
112 125 cmp = head;
113 126 last = NULL;
114 127 }
115 128 continue;
116 129 }
117 130 ehp = (struct ether_header *)cmp->b_rptr;
118 131
119 132 sap = ntohs(ehp->ether_type);
120 133 if (sap == ETHERTYPE_SLOW) {
121 134 /*
122 135 * LACP or Marker packet. Send up pending
123 136 * chain, and send LACP/Marker packet
124 137 * to LACP subsystem.
125 138 */
126 139 if (head == cmp) {
127 140 /* first packet of chain */
128 141 ASSERT(last == NULL);
129 142 head = cmp->b_next;
130 143 cmp->b_next = NULL;
131 144 aggr_recv_lacp(port, mrh, cmp);
132 145 cmp = head;
133 146 } else {
134 147 /* previously accumulated packets */
135 148 ASSERT(last != NULL);
136 149 /* send up non-LACP packets */
137 150 last->b_next = NULL;
138 151 if (port->lp_collector_enabled) {
139 152 aggr_mac_rx(grp->lg_mh, mrh,
140 153 head);
141 154 } else {
142 155 freemsgchain(head);
143 156 }
144 157 /* unlink and pass up LACP packets */
145 158 head = cmp->b_next;
146 159 cmp->b_next = NULL;
147 160 aggr_recv_lacp(port, mrh, cmp);
148 161 cmp = head;
149 162 last = NULL;
150 163 }
151 164 } else {
152 165 last = cmp;
↓ open down ↓ |
62 lines elided |
↑ open up ↑ |
153 166 cmp = cmp->b_next;
154 167 }
155 168 }
156 169 if (head != NULL) {
157 170 if (port->lp_collector_enabled)
158 171 aggr_mac_rx(grp->lg_mh, mrh, head);
159 172 else
160 173 freemsgchain(head);
161 174 }
162 175 }
176 +}
177 +
178 +/* ARGSUSED */
179 +void
180 +aggr_recv_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
181 + boolean_t loopback)
182 +{
183 + aggr_recv_path_cb(arg, mrh, mp, loopback, B_FALSE);
184 +}
185 +
186 +/* ARGSUSED */
187 +void
188 +aggr_recv_promisc_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
189 + boolean_t loopback)
190 +{
191 + aggr_recv_path_cb(arg, mrh, mp, loopback, B_TRUE);
163 192 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX