Crossbow - transition to Mercurial 6668161 expose receive rings through aggregations 6741067 aggr locking needs to work with mac perimeter design 6734073 deadlock in aggr if aggregation failed to be created for some reason 6742825 system panicked due to recursive locking in aggr 6746501 deadbeef panic in mac_client_close() 6742712 potential message double free in the aggr driver 6754299 a potential race between aggr_m_tx() and aggr_port_delete()
1 /* 2 * CDDL HEADER START 3 * 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 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * IEEE 802.3ad Link Aggregation - Receive 30 * 31 * Implements the collector function. 32 * Manages the RX resources exposed by a link aggregation group. 33 */ 34 35 #include <sys/sysmacros.h> 36 #include <sys/ddi.h> 37 #include <sys/sunddi.h> 38 #include <sys/strsun.h> 39 #include <sys/strsubr.h> 40 #include <sys/byteorder.h> 41 #include <sys/aggr.h> 42 #include <sys/aggr_impl.h> 43 44 static void 45 aggr_recv_lacp(aggr_port_t *port, mblk_t *mp) 46 { 47 aggr_grp_t *grp = port->lp_grp; 48 49 /* in promiscuous mode, send copy of packet up */ 50 if (grp->lg_promisc) { 51 mblk_t *nmp = copymsg(mp); 52 53 if (nmp != NULL) 54 mac_rx(grp->lg_mh, NULL, nmp); 55 } 56 57 aggr_lacp_rx(port, mp); 58 } 59 60 /* 61 * Callback function invoked by MAC service module when packets are 62 * made available by a MAC port. 63 */ 64 void 65 aggr_recv_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp) 66 { 67 aggr_port_t *port = (aggr_port_t *)arg; 68 aggr_grp_t *grp = port->lp_grp; 69 70 /* 71 * If this message is looped back from the legacy devices, drop 72 * it as the Nemo framework will be responsible for looping it 73 * back by the mac_txloop() function. 74 */ 75 if (mp->b_flag & MSGNOLOOP) { 76 ASSERT(mp->b_next == NULL); 77 freemsg(mp); 78 return; 79 } 80 81 if (grp->lg_lacp_mode == AGGR_LACP_OFF) { 82 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 { 101 /* send up accumulated packets */ 102 last->b_next = NULL; 103 if (port->lp_collector_enabled) 104 mac_rx(grp->lg_mh, mrh, head); 105 else 106 freemsgchain(head); 107 head = cmp->b_next; 108 cmp->b_next = NULL; 109 freemsg(cmp); 110 cmp = head; 111 last = NULL; 112 } 113 continue; 114 } 115 ehp = (struct ether_header *)cmp->b_rptr; 116 117 sap = ntohs(ehp->ether_type); 118 if (sap == ETHERTYPE_SLOW) { 119 /* 120 * LACP or Marker packet. Send up pending 121 * chain, and send LACP/Marker packet 122 * to LACP subsystem. 123 */ 124 if (head == cmp) { 125 /* first packet of chain */ 126 ASSERT(last == NULL); 127 head = cmp->b_next; 128 cmp->b_next = NULL; 129 aggr_recv_lacp(port, cmp); 130 cmp = head; 131 } else { 132 /* previously accumulated packets */ 133 ASSERT(last != NULL); 134 /* send up non-LACP packets */ 135 last->b_next = NULL; 136 if (port->lp_collector_enabled) 137 mac_rx(grp->lg_mh, mrh, head); 138 else 139 freemsgchain(head); 140 /* unlink and pass up LACP packets */ 141 head = cmp->b_next; 142 cmp->b_next = NULL; 143 aggr_recv_lacp(port, cmp); 144 cmp = head; 145 last = NULL; 146 } 147 } else { 148 last = cmp; 149 cmp = cmp->b_next; 150 } 151 } 152 if (head != NULL) { 153 if (port->lp_collector_enabled) 154 mac_rx(grp->lg_mh, mrh, head); 155 else 156 freemsgchain(head); 157 } 158 } 159 } --- EOF ---