Print this page
2869 duplicate packets with vnics over aggrs
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 + /* 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 +
81 93 if (grp->lg_lacp_mode == AGGR_LACP_OFF) {
82 94 aggr_mac_rx(grp->lg_mh, mrh, mp);
83 95 } else {
84 96 mblk_t *cmp, *last, *head;
85 97 struct ether_header *ehp;
86 98 uint16_t sap;
87 99
88 100 /* filter out slow protocol packets (LACP & Marker) */
89 101 last = NULL;
90 102 head = cmp = mp;
91 103 while (cmp != NULL) {
92 104 if (MBLKL(cmp) < sizeof (struct ether_header)) {
93 105 /* packet too short */
94 106 if (head == cmp) {
95 107 /* no packets accumulated */
96 108 head = cmp->b_next;
97 109 cmp->b_next = NULL;
98 110 freemsg(cmp);
99 111 cmp = head;
100 112 } else {
101 113 /* send up accumulated packets */
102 114 last->b_next = NULL;
103 115 if (port->lp_collector_enabled) {
104 116 aggr_mac_rx(grp->lg_mh, mrh,
105 117 head);
106 118 } else {
107 119 freemsgchain(head);
108 120 }
109 121 head = cmp->b_next;
110 122 cmp->b_next = NULL;
111 123 freemsg(cmp);
112 124 cmp = head;
113 125 last = NULL;
114 126 }
115 127 continue;
116 128 }
117 129 ehp = (struct ether_header *)cmp->b_rptr;
118 130
119 131 sap = ntohs(ehp->ether_type);
120 132 if (sap == ETHERTYPE_SLOW) {
121 133 /*
122 134 * LACP or Marker packet. Send up pending
123 135 * chain, and send LACP/Marker packet
124 136 * to LACP subsystem.
125 137 */
126 138 if (head == cmp) {
127 139 /* first packet of chain */
128 140 ASSERT(last == NULL);
129 141 head = cmp->b_next;
130 142 cmp->b_next = NULL;
131 143 aggr_recv_lacp(port, mrh, cmp);
132 144 cmp = head;
133 145 } else {
134 146 /* previously accumulated packets */
135 147 ASSERT(last != NULL);
136 148 /* send up non-LACP packets */
137 149 last->b_next = NULL;
138 150 if (port->lp_collector_enabled) {
139 151 aggr_mac_rx(grp->lg_mh, mrh,
140 152 head);
141 153 } else {
142 154 freemsgchain(head);
143 155 }
144 156 /* unlink and pass up LACP packets */
145 157 head = cmp->b_next;
146 158 cmp->b_next = NULL;
147 159 aggr_recv_lacp(port, mrh, cmp);
148 160 cmp = head;
149 161 last = NULL;
150 162 }
151 163 } else {
152 164 last = cmp;
↓ open down ↓ |
62 lines elided |
↑ open up ↑ |
153 165 cmp = cmp->b_next;
154 166 }
155 167 }
156 168 if (head != NULL) {
157 169 if (port->lp_collector_enabled)
158 170 aggr_mac_rx(grp->lg_mh, mrh, head);
159 171 else
160 172 freemsgchain(head);
161 173 }
162 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);
163 191 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX