aggr_send.c revision da14cebe459d3275048785f25bd869cb09b5307f
/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* IEEE 802.3ad Link Aggregation - Send code.
*
* Implements the Distributor function.
*/
#include <inet/ipsec_impl.h>
#include <inet/ipsecesp.h>
#include <sys/aggr_impl.h>
static uint64_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);
/* the vlan tag is the payload, pull up first */
goto done;
}
} else {
}
} else {
skip_len = sizeof (struct ether_header);
}
/* if ethernet header is in its own mblk, skip it */
}
switch (sap) {
case ETHERTYPE_IP: {
goto done;
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
*/
goto done;
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:
return (hash);
}
/*
* Update the TX load balancing policy of the specified group.
*/
void
{
}
/*
* Send function invoked by the MAC service module.
*/
mblk_t *
{
void *mytx_handle;
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);
}
/*
* Bump the active Tx ref count so that the port won't
* be deleted. The reference count will be dropped in mac_tx().
*/
if (mytx_handle == NULL) {
/*
* The port is quiesced.
*/
} else {
/*
* It is fine that the port state changes now.
* Set MAC_TX_NO_HOLD to inform mac_tx() not to bump
* the active Tx ref again. Use hash as the hint so
* to direct traffic to different TX rings. Note below
* bit operation is needed to get the most benefit
* from the mac_tx() hash algorithm.
*/
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);
}