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/sys/aggr_impl.h
+++ new/usr/src/uts/common/sys/aggr_impl.h
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 2010 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + * Copyright 2012 OmniTI Computer Consulting, Inc All rights reserved.
25 + * Copyright 2018 Joyent, Inc.
24 26 */
25 27
26 28 #ifndef _SYS_AGGR_IMPL_H
27 29 #define _SYS_AGGR_IMPL_H
28 30
29 31 #include <sys/types.h>
30 32 #include <sys/cred.h>
31 33 #include <sys/mac_ether.h>
32 34 #include <sys/mac_provider.h>
33 35 #include <sys/mac_client.h>
34 36 #include <sys/mac_client_priv.h>
35 37 #include <sys/aggr_lacp.h>
36 38
37 39 #ifdef __cplusplus
38 40 extern "C" {
39 41 #endif
40 42
41 43 #ifdef _KERNEL
42 44
43 45 #define AGGR_MINOR_CTL 1 /* control interface minor */
44 46
45 47 /* flags for aggr_grp_modify() */
46 48 #define AGGR_MODIFY_POLICY 0x01
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
47 49 #define AGGR_MODIFY_MAC 0x02
48 50 #define AGGR_MODIFY_LACP_MODE 0x04
49 51 #define AGGR_MODIFY_LACP_TIMER 0x08
50 52
51 53 /*
52 54 * Possible value of aggr_rseudo_rx_ring_t.arr_flags. Set when the ring entry
53 55 * in the pseudo RX group is used.
54 56 */
55 57 #define MAC_PSEUDO_RING_INUSE 0x01
56 58
59 +/*
60 + * VLAN filters placed on the Rx pseudo group.
61 + */
62 +typedef struct aggr_vlan {
63 + list_node_t av_link;
64 + uint16_t av_vid; /* VLAN ID */
65 + uint_t av_refs; /* num aggr clients using this VID */
66 +} aggr_vlan_t;
67 +
57 68 typedef struct aggr_unicst_addr_s {
58 69 uint8_t aua_addr[ETHERADDRL];
59 70 struct aggr_unicst_addr_s *aua_next;
60 71 } aggr_unicst_addr_t;
61 72
62 73 typedef struct aggr_pseudo_rx_ring_s {
63 74 mac_ring_handle_t arr_rh; /* filled in by aggr_fill_ring() */
64 75 struct aggr_port_s *arr_port;
65 76 mac_ring_handle_t arr_hw_rh;
66 77 uint_t arr_flags;
67 78 uint64_t arr_gen;
68 79 } aggr_pseudo_rx_ring_t;
69 80
70 81 typedef struct aggr_pseudo_rx_group_s {
71 82 struct aggr_grp_s *arg_grp; /* filled in by aggr_fill_group() */
72 83 mac_group_handle_t arg_gh; /* filled in by aggr_fill_group() */
73 84 aggr_unicst_addr_t *arg_macaddr;
74 85 aggr_pseudo_rx_ring_t arg_rings[MAX_RINGS_PER_GROUP];
75 86 uint_t arg_ring_cnt;
87 + uint_t arg_untagged; /* num clients untagged */
88 + list_t arg_vlans; /* VLANs on this group */
76 89 } aggr_pseudo_rx_group_t;
77 90
78 91 typedef struct aggr_pseudo_tx_ring_s {
79 92 mac_ring_handle_t atr_rh; /* filled in by aggr_fill_ring() */
80 93 struct aggr_port_s *atr_port;
81 94 mac_ring_handle_t atr_hw_rh;
82 95 uint_t atr_flags;
83 96 } aggr_pseudo_tx_ring_t;
84 97
85 98 typedef struct aggr_pseudo_tx_group_s {
86 99 mac_group_handle_t atg_gh; /* filled in by aggr_fill_group() */
87 100 uint_t atg_ring_cnt;
88 101 aggr_pseudo_tx_ring_t atg_rings[MAX_RINGS_PER_GROUP];
89 102 } aggr_pseudo_tx_group_t;
90 103
91 104 /*
92 105 * A link aggregation MAC port.
93 106 * Note that lp_next is protected by the lg_lock of the group the
94 107 * port is part of.
95 108 */
96 109 typedef struct aggr_port_s {
97 110 struct aggr_port_s *lp_next;
98 111 struct aggr_grp_s *lp_grp; /* back ptr to group */
99 112 datalink_id_t lp_linkid;
100 113 uint16_t lp_portid;
101 114 uint8_t lp_addr[ETHERADDRL]; /* port MAC address */
102 115 uint32_t lp_refs; /* refcount */
103 116 aggr_port_state_t lp_state;
104 117 uint32_t lp_started : 1,
105 118 lp_tx_enabled : 1,
106 119 lp_collector_enabled : 1,
107 120 lp_promisc_on : 1,
108 121 lp_no_link_update : 1,
109 122 lp_rx_grp_added : 1,
110 123 lp_tx_grp_added : 1,
111 124 lp_closing : 1,
112 125 lp_pad_bits : 24;
113 126 mac_handle_t lp_mh;
114 127 mac_client_handle_t lp_mch;
115 128 const mac_info_t *lp_mip;
116 129 mac_notify_handle_t lp_mnh;
117 130 uint_t lp_tx_idx; /* idx in group's tx array */
118 131 uint64_t lp_ifspeed;
119 132 link_state_t lp_link_state;
120 133 link_duplex_t lp_link_duplex;
121 134 uint64_t lp_stat[MAC_NSTAT];
122 135 uint64_t lp_ether_stat[ETHER_NSTAT];
123 136 aggr_lacp_port_t lp_lacp; /* LACP state */
124 137 lacp_stats_t lp_lacp_stats;
125 138 uint32_t lp_margin;
126 139 mac_promisc_handle_t lp_mphp;
127 140 mac_unicast_handle_t lp_mah;
128 141
129 142 /* List of non-primary addresses that requires promiscous mode set */
130 143 aggr_unicst_addr_t *lp_prom_addr;
131 144 /* handle of the underlying HW RX group */
132 145 mac_group_handle_t lp_hwgh;
133 146 int lp_tx_ring_cnt;
134 147 /* handles of the underlying HW TX rings */
135 148 mac_ring_handle_t *lp_tx_rings;
136 149 /*
137 150 * Handles of the pseudo TX rings. Each of them maps to
138 151 * corresponding hardware TX ring in lp_tx_rings[]. A
139 152 * pseudo TX ring is presented to aggr primary mac
140 153 * client even when underlying NIC has no TX ring.
141 154 */
142 155 mac_ring_handle_t *lp_pseudo_tx_rings;
143 156 void *lp_tx_notify_mh;
144 157 } aggr_port_t;
145 158
146 159 /*
147 160 * A link aggregation group.
148 161 *
149 162 * The following per-group flags are defined:
150 163 *
151 164 * - lg_addr_fixed: set when the MAC address has been explicitely set
152 165 * when the group was created, or by a m_unicst_set() request.
153 166 * If this flag is not set, the MAC address of the group will be
154 167 * set to the first port that is added to the group.
155 168 *
156 169 * - lg_add_set: used only when lg_addr_fixed is not set. Captures whether
157 170 * the MAC address was initialized according to the members of the group.
158 171 * When set, the lg_port field points to the port from which the
159 172 * MAC address was initialized.
160 173 *
161 174 */
162 175 typedef struct aggr_grp_s {
163 176 datalink_id_t lg_linkid;
164 177 uint16_t lg_key; /* key (group port number) */
165 178 uint32_t lg_refs; /* refcount */
166 179 uint16_t lg_nports; /* number of MAC ports */
167 180 uint8_t lg_addr[ETHERADDRL]; /* group MAC address */
168 181 uint16_t
169 182 lg_closing : 1,
170 183 lg_addr_fixed : 1, /* fixed MAC address? */
171 184 lg_started : 1, /* group started? */
172 185 lg_promisc : 1, /* in promiscuous mode? */
173 186 lg_zcopy : 1,
174 187 lg_vlan : 1,
175 188 lg_force : 1,
176 189 lg_lso : 1,
177 190 lg_pad_bits : 8;
178 191 aggr_port_t *lg_ports; /* list of configured ports */
↓ open down ↓ |
93 lines elided |
↑ open up ↑ |
179 192 aggr_port_t *lg_mac_addr_port;
180 193 mac_handle_t lg_mh;
181 194 zoneid_t lg_zoneid;
182 195 uint_t lg_nattached_ports;
183 196 krwlock_t lg_tx_lock;
184 197 uint_t lg_ntx_ports;
185 198 aggr_port_t **lg_tx_ports; /* array of tx ports */
186 199 uint_t lg_tx_ports_size; /* size of lg_tx_ports */
187 200 uint32_t lg_tx_policy; /* outbound policy */
188 201 uint8_t lg_mac_tx_policy;
189 - uint64_t lg_ifspeed;
190 202 link_state_t lg_link_state;
203 +
204 +
205 + /*
206 + * The lg_stat_lock must be held when accessing these fields.
207 + */
208 + kmutex_t lg_stat_lock;
209 + uint64_t lg_ifspeed;
191 210 link_duplex_t lg_link_duplex;
192 211 uint64_t lg_stat[MAC_NSTAT];
193 212 uint64_t lg_ether_stat[ETHER_NSTAT];
213 +
194 214 aggr_lacp_mode_t lg_lacp_mode; /* off, active, or passive */
195 215 Agg_t aggr; /* 802.3ad data */
196 216 uint32_t lg_hcksum_txflags;
197 217 uint_t lg_max_sdu;
198 218 uint32_t lg_margin;
199 219 mac_capab_lso_t lg_cap_lso;
200 220
201 221 /*
202 222 * The following fields are used by the LACP packets processing.
203 223 * Specifically, as the LACP packets processing is not performance
204 224 * critical, all LACP packets will be handled by a dedicated thread
205 225 * instead of in the mac_rx() call. This is to avoid the dead lock
206 226 * with mac_unicast_remove(), which holding the mac perimeter of the
207 227 * aggr, and wait for the mr_refcnt of the RX ring to drop to zero.
208 228 */
209 229 kmutex_t lg_lacp_lock;
210 230 kcondvar_t lg_lacp_cv;
211 231 mblk_t *lg_lacp_head;
212 232 mblk_t *lg_lacp_tail;
213 233 kthread_t *lg_lacp_rx_thread;
214 234 boolean_t lg_lacp_done;
215 235
216 236 aggr_pseudo_rx_group_t lg_rx_group;
217 237 aggr_pseudo_tx_group_t lg_tx_group;
218 238
219 239 kmutex_t lg_tx_flowctl_lock;
220 240 kcondvar_t lg_tx_flowctl_cv;
221 241 uint_t lg_tx_blocked_cnt;
222 242 mac_ring_handle_t *lg_tx_blocked_rings;
223 243 kthread_t *lg_tx_notify_thread;
224 244 boolean_t lg_tx_notify_done;
225 245
226 246 /*
227 247 * The following fields are used by aggr to wait for all the
228 248 * aggr_port_notify_cb() and aggr_port_timer_thread() to finish
229 249 * before it calls mac_unregister() when the aggr is deleted.
230 250 */
231 251 kmutex_t lg_port_lock;
232 252 kcondvar_t lg_port_cv;
233 253 int lg_port_ref;
234 254 } aggr_grp_t;
235 255
236 256 #define AGGR_GRP_REFHOLD(grp) { \
237 257 atomic_inc_32(&(grp)->lg_refs); \
238 258 ASSERT((grp)->lg_refs != 0); \
239 259 }
240 260
241 261 #define AGGR_GRP_REFRELE(grp) { \
242 262 ASSERT((grp)->lg_refs != 0); \
243 263 membar_exit(); \
244 264 if (atomic_dec_32_nv(&(grp)->lg_refs) == 0) \
245 265 aggr_grp_free(grp); \
246 266 }
247 267
248 268 #define AGGR_PORT_REFHOLD(port) { \
249 269 atomic_inc_32(&(port)->lp_refs); \
250 270 ASSERT((port)->lp_refs != 0); \
251 271 }
252 272
253 273 #define AGGR_PORT_REFRELE(port) { \
254 274 ASSERT((port)->lp_refs != 0); \
255 275 membar_exit(); \
256 276 if (atomic_dec_32_nv(&(port)->lp_refs) == 0) \
257 277 aggr_port_free(port); \
258 278 }
259 279
260 280 extern dev_info_t *aggr_dip;
261 281 extern int aggr_ioc_init(void);
262 282 extern void aggr_ioc_fini(void);
263 283
264 284 typedef int (*aggr_grp_info_new_grp_fn_t)(void *, datalink_id_t, uint32_t,
265 285 uchar_t *, boolean_t, boolean_t, uint32_t, uint32_t, aggr_lacp_mode_t,
266 286 aggr_lacp_timer_t);
267 287 typedef int (*aggr_grp_info_new_port_fn_t)(void *, datalink_id_t, uchar_t *,
268 288 aggr_port_state_t, aggr_lacp_state_t *);
269 289
270 290 extern void aggr_grp_init(void);
271 291 extern void aggr_grp_fini(void);
272 292 extern int aggr_grp_create(datalink_id_t, uint32_t, uint_t, laioc_port_t *,
273 293 uint32_t, boolean_t, boolean_t, uchar_t *, aggr_lacp_mode_t,
274 294 aggr_lacp_timer_t, cred_t *);
275 295 extern int aggr_grp_delete(datalink_id_t, cred_t *);
276 296 extern void aggr_grp_free(aggr_grp_t *);
277 297
278 298 extern int aggr_grp_info(datalink_id_t, void *, aggr_grp_info_new_grp_fn_t,
279 299 aggr_grp_info_new_port_fn_t, cred_t *);
280 300 extern void aggr_grp_notify(aggr_grp_t *, uint32_t);
281 301 extern boolean_t aggr_grp_attach_port(aggr_grp_t *, aggr_port_t *);
282 302 extern boolean_t aggr_grp_detach_port(aggr_grp_t *, aggr_port_t *);
283 303 extern void aggr_grp_port_mac_changed(aggr_grp_t *, aggr_port_t *,
284 304 boolean_t *, boolean_t *);
285 305 extern int aggr_grp_add_ports(datalink_id_t, uint_t, boolean_t,
286 306 laioc_port_t *);
287 307 extern int aggr_grp_rem_ports(datalink_id_t, uint_t, laioc_port_t *);
288 308 extern boolean_t aggr_grp_update_ports_mac(aggr_grp_t *);
289 309 extern int aggr_grp_modify(datalink_id_t, uint8_t, uint32_t, boolean_t,
290 310 const uchar_t *, aggr_lacp_mode_t, aggr_lacp_timer_t);
291 311 extern void aggr_grp_multicst_port(aggr_port_t *, boolean_t);
292 312 extern uint_t aggr_grp_count(void);
293 313 extern void aggr_grp_update_default(aggr_grp_t *);
294 314
295 315 extern void aggr_port_init(void);
296 316 extern void aggr_port_fini(void);
297 317 extern int aggr_port_create(aggr_grp_t *, const datalink_id_t, boolean_t,
298 318 aggr_port_t **);
299 319 extern void aggr_port_delete(aggr_port_t *);
300 320 extern void aggr_port_free(aggr_port_t *);
↓ open down ↓ |
97 lines elided |
↑ open up ↑ |
301 321 extern int aggr_port_start(aggr_port_t *);
302 322 extern void aggr_port_stop(aggr_port_t *);
303 323 extern int aggr_port_promisc(aggr_port_t *, boolean_t);
304 324 extern int aggr_port_unicst(aggr_port_t *);
305 325 extern int aggr_port_multicst(void *, boolean_t, const uint8_t *);
306 326 extern uint64_t aggr_port_stat(aggr_port_t *, uint_t);
307 327 extern boolean_t aggr_port_notify_link(aggr_grp_t *, aggr_port_t *);
308 328 extern void aggr_port_init_callbacks(aggr_port_t *);
309 329
310 330 extern void aggr_recv_cb(void *, mac_resource_handle_t, mblk_t *, boolean_t);
331 +extern void aggr_recv_promisc_cb(void *, mac_resource_handle_t, mblk_t *,
332 + boolean_t);
311 333
312 334 extern void aggr_tx_ring_update(void *, uintptr_t);
313 335 extern void aggr_tx_notify_thread(void *);
314 336 extern void aggr_send_port_enable(aggr_port_t *);
315 337 extern void aggr_send_port_disable(aggr_port_t *);
316 338 extern void aggr_send_update_policy(aggr_grp_t *, uint32_t);
317 339
318 340 extern void aggr_lacp_init(void);
319 341 extern void aggr_lacp_fini(void);
320 342 extern void aggr_lacp_init_port(aggr_port_t *);
321 343 extern void aggr_lacp_init_grp(aggr_grp_t *);
322 344 extern void aggr_lacp_set_mode(aggr_grp_t *, aggr_lacp_mode_t,
323 345 aggr_lacp_timer_t);
324 346 extern void aggr_lacp_update_mode(aggr_grp_t *, aggr_lacp_mode_t);
325 347 extern void aggr_lacp_update_timer(aggr_grp_t *, aggr_lacp_timer_t);
326 348 extern void aggr_lacp_rx_enqueue(aggr_port_t *, mblk_t *);
327 349 extern void aggr_lacp_port_attached(aggr_port_t *);
328 350 extern void aggr_lacp_port_detached(aggr_port_t *);
329 351 extern void aggr_port_lacp_set_mode(aggr_grp_t *, aggr_port_t *);
330 352
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
331 353 extern void aggr_lacp_rx_thread(void *);
332 354 extern void aggr_recv_lacp(aggr_port_t *, mac_resource_handle_t, mblk_t *);
333 355
334 356 extern void aggr_grp_port_hold(aggr_port_t *);
335 357 extern void aggr_grp_port_rele(aggr_port_t *);
336 358 extern void aggr_grp_port_wait(aggr_grp_t *);
337 359
338 360 extern int aggr_port_addmac(aggr_port_t *, const uint8_t *);
339 361 extern void aggr_port_remmac(aggr_port_t *, const uint8_t *);
340 362
363 +extern int aggr_port_addvlan(aggr_port_t *, uint16_t);
364 +extern int aggr_port_remvlan(aggr_port_t *, uint16_t);
365 +
341 366 extern mblk_t *aggr_ring_tx(void *, mblk_t *);
342 367 extern mblk_t *aggr_find_tx_ring(void *, mblk_t *,
343 368 uintptr_t, mac_ring_handle_t *);
344 369
345 370 #endif /* _KERNEL */
346 371
347 372 #ifdef __cplusplus
348 373 }
349 374 #endif
350 375
351 376 #endif /* _SYS_AGGR_IMPL_H */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX