/* * 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 * or http://www.opensolaris.org/os/licensing. * 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 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include #include #include #include #include #include #include #include #include #include #include /* Module to mark the 802.1d user priority field for a given packet */ /* Debug level */ int dlcosmk_debug = 0; /* * Given a packet, this module marks the mblk with the appropriate b_band or * dl_max value so that the VLAN driver marks the outgoing frame with the * configured 802.1D user_priority value. For non-VLAN devices or for inbound * packets, this module does not do anything (i.e. the packet is processed by * the next action in the list, if present). * This module does not free any mblks or packets in case or errors. */ int dlcosmk_process(mblk_t **mpp, dlcosmk_data_t *dlcosmk_data, uint32_t ill_index, ip_proc_t proc) { ill_t *ill = NULL; mblk_t *mp; ASSERT((mpp != NULL) && (*mpp != NULL)); mp = *mpp; /* * The action module will receive an M_DATA or an M_CTL followed * by an M_DATA. In the latter case skip the M_CTL. */ if (mp->b_datap->db_type != M_DATA) { if ((mp->b_cont == NULL) || (mp->b_cont->b_datap->db_type != M_DATA)) { atomic_add_64(&dlcosmk_data->epackets, 1); dlcosmk0dbg(("dlcosmk_process: no data\n")); return (EINVAL); } } /* Update global stats */ atomic_add_64(&dlcosmk_data->npackets, 1); /* * This should only be called for outgoing packets. For inbound, just * send it along. */ if ((proc == IPP_LOCAL_IN) || (proc == IPP_FWD_IN)) { dlcosmk2dbg(("dlcosmk_process:cannot mark incoming packets\n")); atomic_add_64(&dlcosmk_data->ipackets, 1); return (0); } if ((ill_index == 0) || ((ill = ill_lookup_on_ifindex_global_instance(ill_index, B_FALSE, NULL, NULL, NULL, NULL)) == NULL)) { dlcosmk2dbg(("dlcosmk_process:invalid ill index %u\n", ill_index)); atomic_add_64(&dlcosmk_data->ipackets, 1); return (0); } /* * Check if the interface supports CoS marking. If not send it to the * next action in the chain */ if (!(ill->ill_flags & ILLF_COS_ENABLED)) { dlcosmk2dbg(("dlcosmk_process:ill %u does not support CoS\n", ill_index)); atomic_add_64(&dlcosmk_data->ipackets, 1); ill_refrele(ill); return (0); } ill_refrele(ill); /* * Mark the b_band for fastpath messages or dl_priority.dl_max for * DL_UNITDATA_REQ messages. For, others just pass it along. */ switch (DB_TYPE(mp)) { case M_PROTO: case M_PCPROTO: { /* DL_UNITDATA */ dl_unitdata_req_t *dlur; dlur = (dl_unitdata_req_t *)mp->b_rptr; /* DL_UNITDATA message?? */ if (dlur->dl_primitive == DL_UNITDATA_REQ) { dlur->dl_priority.dl_max = dlcosmk_data->dl_max; } else { atomic_add_64(&dlcosmk_data->ipackets, 1); } break; } case M_DATA: /* fastpath message */ mp->b_band = dlcosmk_data->b_band; break; default: atomic_add_64(&dlcosmk_data->ipackets, 1); break; } return (0); }