aggr_send.c revision c0192a574ab103def0adf824d9e22709b0d0fba9
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* IEEE 802.3ad Link Aggregation - Send code.
*
* Implements the Distributor function.
*/
#include <inet/ipsecesp.h>
#include <sys/aggr_impl.h>
static uint_t
{
struct ether_header *ehp;
/* compute MAC hash */
if (policy & AGGR_POLICY_L2) {
policy &= ~AGGR_POLICY_L2;
}
if (policy == 0)
goto done;
/* skip ethernet header */
struct ether_vlan_header *evhp;
skip_len = sizeof (struct ether_vlan_header);
} else {
skip_len = sizeof (struct ether_header);
}
/* if ethernet header is in its own mblk, skip it */
}
switch (sap) {
case ETHERTYPE_IP: {
if (policy & AGGR_POLICY_L3) {
policy &= ~AGGR_POLICY_L3;
}
break;
}
case ETHERTYPE_IPV6: {
/*
* if ipv6 packet has options, the proto will not be one of the
* ones handled by the ULP processor below, and will return 0
* as the index
*/
if (policy & AGGR_POLICY_L3) {
policy &= ~AGGR_POLICY_L3;
}
break;
}
default:
goto done;
}
if (!(policy & AGGR_POLICY_L4))
goto done;
/* if ip header is in its own mblk, skip it */
}
/* parse ULP header */
switch (proto) {
case IPPROTO_TCP:
case IPPROTO_UDP:
case IPPROTO_ESP:
case IPPROTO_SCTP:
/*
* These Internet Protocols are intentionally designed
* for hashing from the git-go. Port numbers are in the first
* word for transports, SPI is first for ESP.
*/
break;
case IPPROTO_AH: {
/* if ip header is in its own mblk, skip it */
}
goto again;
}
}
done:
}
/*
* Update the TX load balancing policy of the specified group.
*/
void
{
}
/*
* Send function invoked by the MAC service module.
*/
mblk_t *
{
const mac_txinfo_t *mtp;
for (;;) {
if (grp->lg_ntx_ports == 0) {
/*
* We could have returned from aggr_m_start() before
* the ports were actually attached. Drop the chain.
*/
return (NULL);
}
/*
* We store the transmit info pointer locally in case it
* changes between loading mt_fn and mt_arg.
*/
break;
}
break;
}
return (mp);
}
/*
* Enable sending on the specified port.
*/
void
{
/* already enabled or port not yet attached */
return;
}
/*
* Add to group's array of tx ports.
*/
/* current array too small */
KM_SLEEP);
if (grp->lg_tx_ports_size > 0) {
}
}
}
/*
* Disable sending from the specified port.
*/
void
{
if (!port->lp_tx_enabled) {
/* not yet enabled */
return;
}
/* remove from array of attached ports */
} else {
/* not the last entry, replace with last one */
}
grp->lg_ntx_ports--;
}
static uint16_t
{
switch (*nexthdrp) {
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
/* Assumes the headers are identical for hbh and dst */
break;
case IPPROTO_ROUTING:
break;
case IPPROTO_FRAGMENT:
ehdrlen = sizeof (ip6_frag_t);
break;
case IPPROTO_NONE:
/* No next header means we're finished */
default:
return (length);
}
}
return (length);
}