dlcosmk.c revision 11042:2d6e217af1b4
1254721Semaste/* 2254721Semaste * CDDL HEADER START 3254721Semaste * 4254721Semaste * The contents of this file are subject to the terms of the 5254721Semaste * Common Development and Distribution License (the "License"). 6254721Semaste * You may not use this file except in compliance with the License. 7254721Semaste * 8254721Semaste * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9254721Semaste * or http://www.opensolaris.org/os/licensing. 10254721Semaste * See the License for the specific language governing permissions 11254721Semaste * and limitations under the License. 12254721Semaste * 13254721Semaste * When distributing Covered Code, include this CDDL HEADER in each 14254721Semaste * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15254721Semaste * If applicable, add the following below this CDDL HEADER, with the 16254721Semaste * fields enclosed by brackets "[]" replaced with your own identifying 17254721Semaste * information: Portions Copyright [yyyy] [name of copyright owner] 18254721Semaste * 19254721Semaste * CDDL HEADER END 20254721Semaste */ 21254721Semaste/* 22254721Semaste * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23254721Semaste * Use is subject to license terms. 24254721Semaste */ 25254721Semaste 26254721Semaste#include <sys/types.h> 27254721Semaste#include <sys/stream.h> 28254721Semaste#include <sys/dlpi.h> 29254721Semaste#include <sys/strsun.h> 30254721Semaste#include <netinet/in.h> 31254721Semaste#include <netinet/ip6.h> 32254721Semaste#include <inet/common.h> 33254721Semaste#include <inet/ip.h> 34254721Semaste#include <inet/ip6.h> 35254721Semaste#include <inet/ip_if.h> 36254721Semaste#include <ipp/dlcosmk/dlcosmk_impl.h> 37254721Semaste 38254721Semaste/* Module to mark the 802.1d user priority field for a given packet */ 39254721Semaste 40254721Semaste/* Debug level */ 41254721Semasteint dlcosmk_debug = 0; 42254721Semaste 43254721Semaste/* 44254721Semaste * Given a packet, this module marks the mblk with the appropriate b_band or 45254721Semaste * dl_max value so that the VLAN driver marks the outgoing frame with the 46254721Semaste * configured 802.1D user_priority value. For non-VLAN devices or for inbound 47254721Semaste * packets, this module does not do anything (i.e. the packet is processed by 48254721Semaste * the next action in the list, if present). 49254721Semaste * This module does not free any mblks or packets in case or errors. 50254721Semaste */ 51254721Semaste 52254721Semasteint 53254721Semastedlcosmk_process(mblk_t **mpp, dlcosmk_data_t *dlcosmk_data, uint32_t ill_index, 54254721Semaste ip_proc_t proc) 55254721Semaste{ 56254721Semaste ill_t *ill = NULL; 57254721Semaste mblk_t *mp; 58254721Semaste 59254721Semaste ASSERT((mpp != NULL) && (*mpp != NULL)); 60254721Semaste mp = *mpp; 61254721Semaste 62254721Semaste /* 63254721Semaste * The action module will receive an M_DATA or an M_CTL followed 64254721Semaste * by an M_DATA. In the latter case skip the M_CTL. 65254721Semaste */ 66254721Semaste if (mp->b_datap->db_type != M_DATA) { 67254721Semaste if ((mp->b_cont == NULL) || 68254721Semaste (mp->b_cont->b_datap->db_type != M_DATA)) { 69254721Semaste atomic_add_64(&dlcosmk_data->epackets, 1); 70254721Semaste dlcosmk0dbg(("dlcosmk_process: no data\n")); 71254721Semaste return (EINVAL); 72254721Semaste } 73254721Semaste } 74254721Semaste 75254721Semaste /* Update global stats */ 76254721Semaste atomic_add_64(&dlcosmk_data->npackets, 1); 77254721Semaste 78254721Semaste /* 79254721Semaste * This should only be called for outgoing packets. For inbound, just 80254721Semaste * send it along. 81254721Semaste */ 82254721Semaste if ((proc == IPP_LOCAL_IN) || (proc == IPP_FWD_IN)) { 83254721Semaste dlcosmk2dbg(("dlcosmk_process:cannot mark incoming packets\n")); 84254721Semaste atomic_add_64(&dlcosmk_data->ipackets, 1); 85254721Semaste return (0); 86254721Semaste } 87254721Semaste 88254721Semaste if ((ill_index == 0) || 89254721Semaste ((ill = ill_lookup_on_ifindex_global_instance(ill_index, 90254721Semaste B_FALSE)) == NULL)) { 91254721Semaste dlcosmk2dbg(("dlcosmk_process:invalid ill index %u\n", 92254721Semaste ill_index)); 93254721Semaste atomic_add_64(&dlcosmk_data->ipackets, 1); 94254721Semaste return (0); 95254721Semaste } 96254721Semaste 97254721Semaste /* 98254721Semaste * Check if the interface supports CoS marking. If not send it to the 99254721Semaste * next action in the chain 100254721Semaste */ 101254721Semaste if (!(ill->ill_flags & ILLF_COS_ENABLED)) { 102254721Semaste dlcosmk2dbg(("dlcosmk_process:ill %u does not support CoS\n", 103254721Semaste ill_index)); 104254721Semaste atomic_add_64(&dlcosmk_data->ipackets, 1); 105254721Semaste ill_refrele(ill); 106254721Semaste return (0); 107254721Semaste } 108254721Semaste ill_refrele(ill); 109254721Semaste 110254721Semaste 111254721Semaste /* 112254721Semaste * Mark the b_band for fastpath messages or dl_priority.dl_max for 113254721Semaste * DL_UNITDATA_REQ messages. For, others just pass it along. 114254721Semaste */ 115254721Semaste switch (DB_TYPE(mp)) { 116254721Semaste case M_PROTO: 117254721Semaste case M_PCPROTO: 118254721Semaste { /* DL_UNITDATA */ 119254721Semaste dl_unitdata_req_t *dlur; 120254721Semaste dlur = (dl_unitdata_req_t *)mp->b_rptr; 121254721Semaste 122254721Semaste /* DL_UNITDATA message?? */ 123254721Semaste if (dlur->dl_primitive == DL_UNITDATA_REQ) { 124254721Semaste dlur->dl_priority.dl_max = 125254721Semaste dlcosmk_data->dl_max; 126254721Semaste } else { 127254721Semaste atomic_add_64(&dlcosmk_data->ipackets, 128254721Semaste 1); 129254721Semaste } 130254721Semaste break; 131254721Semaste } 132254721Semaste case M_DATA: 133254721Semaste /* fastpath message */ 134254721Semaste mp->b_band = dlcosmk_data->b_band; 135254721Semaste break; 136254721Semaste default: 137254721Semaste atomic_add_64(&dlcosmk_data->ipackets, 1); 138254721Semaste break; 139254721Semaste } 140254721Semaste 141254721Semaste return (0); 142254721Semaste} 143254721Semaste