17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5f12af565Snd99603 * Common Development and Distribution License (the "License"). 6f12af565Snd99603 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22d62bc4baSyz147064 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * IEEE 802.3ad Link Aggregation - Receive 287c478bd9Sstevel@tonic-gate * 297c478bd9Sstevel@tonic-gate * Implements the collector function. 307c478bd9Sstevel@tonic-gate * Manages the RX resources exposed by a link aggregation group. 317c478bd9Sstevel@tonic-gate */ 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 347c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 357c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 367c478bd9Sstevel@tonic-gate #include <sys/strsun.h> 377c478bd9Sstevel@tonic-gate #include <sys/strsubr.h> 387c478bd9Sstevel@tonic-gate #include <sys/byteorder.h> 397c478bd9Sstevel@tonic-gate #include <sys/aggr.h> 407c478bd9Sstevel@tonic-gate #include <sys/aggr_impl.h> 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate static void 43*da14cebeSEric Cheng aggr_mac_rx(mac_handle_t lg_mh, mac_resource_handle_t mrh, mblk_t *mp) 44*da14cebeSEric Cheng { 45*da14cebeSEric Cheng if (mrh == NULL) { 46*da14cebeSEric Cheng mac_rx(lg_mh, mrh, mp); 47*da14cebeSEric Cheng } else { 48*da14cebeSEric Cheng aggr_pseudo_rx_ring_t *ring = (aggr_pseudo_rx_ring_t *)mrh; 49*da14cebeSEric Cheng mac_rx_ring(lg_mh, ring->arr_rh, mp, ring->arr_gen); 50*da14cebeSEric Cheng } 51*da14cebeSEric Cheng } 52*da14cebeSEric Cheng 53*da14cebeSEric Cheng void 54*da14cebeSEric Cheng aggr_recv_lacp(aggr_port_t *port, mac_resource_handle_t mrh, mblk_t *mp) 557c478bd9Sstevel@tonic-gate { 567c478bd9Sstevel@tonic-gate aggr_grp_t *grp = port->lp_grp; 577c478bd9Sstevel@tonic-gate 58d62bc4baSyz147064 /* in promiscuous mode, send copy of packet up */ 597c478bd9Sstevel@tonic-gate if (grp->lg_promisc) { 607c478bd9Sstevel@tonic-gate mblk_t *nmp = copymsg(mp); 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate if (nmp != NULL) 63*da14cebeSEric Cheng aggr_mac_rx(grp->lg_mh, mrh, nmp); 647c478bd9Sstevel@tonic-gate } 657c478bd9Sstevel@tonic-gate 66*da14cebeSEric Cheng aggr_lacp_rx_enqueue(port, mp); 677c478bd9Sstevel@tonic-gate } 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate /* 707c478bd9Sstevel@tonic-gate * Callback function invoked by MAC service module when packets are 717c478bd9Sstevel@tonic-gate * made available by a MAC port. 727c478bd9Sstevel@tonic-gate */ 73*da14cebeSEric Cheng /* ARGSUSED */ 747c478bd9Sstevel@tonic-gate void 75*da14cebeSEric Cheng aggr_recv_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp, 76*da14cebeSEric Cheng boolean_t loopback) 777c478bd9Sstevel@tonic-gate { 787c478bd9Sstevel@tonic-gate aggr_port_t *port = (aggr_port_t *)arg; 797c478bd9Sstevel@tonic-gate aggr_grp_t *grp = port->lp_grp; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate if (grp->lg_lacp_mode == AGGR_LACP_OFF) { 82*da14cebeSEric Cheng aggr_mac_rx(grp->lg_mh, mrh, mp); 837c478bd9Sstevel@tonic-gate } else { 847c478bd9Sstevel@tonic-gate mblk_t *cmp, *last, *head; 857c478bd9Sstevel@tonic-gate struct ether_header *ehp; 867c478bd9Sstevel@tonic-gate uint16_t sap; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate /* filter out slow protocol packets (LACP & Marker) */ 897c478bd9Sstevel@tonic-gate last = NULL; 907c478bd9Sstevel@tonic-gate head = cmp = mp; 917c478bd9Sstevel@tonic-gate while (cmp != NULL) { 927c478bd9Sstevel@tonic-gate if (MBLKL(cmp) < sizeof (struct ether_header)) { 937c478bd9Sstevel@tonic-gate /* packet too short */ 947c478bd9Sstevel@tonic-gate if (head == cmp) { 957c478bd9Sstevel@tonic-gate /* no packets accumulated */ 967c478bd9Sstevel@tonic-gate head = cmp->b_next; 977c478bd9Sstevel@tonic-gate cmp->b_next = NULL; 987c478bd9Sstevel@tonic-gate freemsg(cmp); 997c478bd9Sstevel@tonic-gate cmp = head; 1007c478bd9Sstevel@tonic-gate } else { 1017c478bd9Sstevel@tonic-gate /* send up accumulated packets */ 1027c478bd9Sstevel@tonic-gate last->b_next = NULL; 103*da14cebeSEric Cheng if (port->lp_collector_enabled) { 104*da14cebeSEric Cheng aggr_mac_rx(grp->lg_mh, mrh, 105*da14cebeSEric Cheng head); 106*da14cebeSEric Cheng } else { 107f12af565Snd99603 freemsgchain(head); 108*da14cebeSEric Cheng } 1097c478bd9Sstevel@tonic-gate head = cmp->b_next; 1107c478bd9Sstevel@tonic-gate cmp->b_next = NULL; 1117c478bd9Sstevel@tonic-gate freemsg(cmp); 1127c478bd9Sstevel@tonic-gate cmp = head; 1137c478bd9Sstevel@tonic-gate last = NULL; 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate continue; 1167c478bd9Sstevel@tonic-gate } 1177c478bd9Sstevel@tonic-gate ehp = (struct ether_header *)cmp->b_rptr; 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate sap = ntohs(ehp->ether_type); 1207c478bd9Sstevel@tonic-gate if (sap == ETHERTYPE_SLOW) { 1217c478bd9Sstevel@tonic-gate /* 1227c478bd9Sstevel@tonic-gate * LACP or Marker packet. Send up pending 1237c478bd9Sstevel@tonic-gate * chain, and send LACP/Marker packet 1247c478bd9Sstevel@tonic-gate * to LACP subsystem. 1257c478bd9Sstevel@tonic-gate */ 1267c478bd9Sstevel@tonic-gate if (head == cmp) { 1277c478bd9Sstevel@tonic-gate /* first packet of chain */ 1287c478bd9Sstevel@tonic-gate ASSERT(last == NULL); 1297c478bd9Sstevel@tonic-gate head = cmp->b_next; 1307c478bd9Sstevel@tonic-gate cmp->b_next = NULL; 131*da14cebeSEric Cheng aggr_recv_lacp(port, mrh, cmp); 1327c478bd9Sstevel@tonic-gate cmp = head; 1337c478bd9Sstevel@tonic-gate } else { 1347c478bd9Sstevel@tonic-gate /* previously accumulated packets */ 1357c478bd9Sstevel@tonic-gate ASSERT(last != NULL); 1367c478bd9Sstevel@tonic-gate /* send up non-LACP packets */ 1377c478bd9Sstevel@tonic-gate last->b_next = NULL; 138*da14cebeSEric Cheng if (port->lp_collector_enabled) { 139*da14cebeSEric Cheng aggr_mac_rx(grp->lg_mh, mrh, 140*da14cebeSEric Cheng head); 141*da14cebeSEric Cheng } else { 142f12af565Snd99603 freemsgchain(head); 143*da14cebeSEric Cheng } 1447c478bd9Sstevel@tonic-gate /* unlink and pass up LACP packets */ 1457c478bd9Sstevel@tonic-gate head = cmp->b_next; 1467c478bd9Sstevel@tonic-gate cmp->b_next = NULL; 147*da14cebeSEric Cheng aggr_recv_lacp(port, mrh, cmp); 1487c478bd9Sstevel@tonic-gate cmp = head; 1497c478bd9Sstevel@tonic-gate last = NULL; 1507c478bd9Sstevel@tonic-gate } 1517c478bd9Sstevel@tonic-gate } else { 1527c478bd9Sstevel@tonic-gate last = cmp; 1537c478bd9Sstevel@tonic-gate cmp = cmp->b_next; 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate if (head != NULL) { 1577c478bd9Sstevel@tonic-gate if (port->lp_collector_enabled) 158*da14cebeSEric Cheng aggr_mac_rx(grp->lg_mh, mrh, head); 1597c478bd9Sstevel@tonic-gate else 160f12af565Snd99603 freemsgchain(head); 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate } 164