Home | History | Annotate | Download | only in sppp
      1 /*
      2  * sppp.c - Solaris STREAMS PPP multiplexing pseudo-driver
      3  *
      4  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
      5  * Use is subject to license terms.
      6  *
      7  * Permission to use, copy, modify, and distribute this software and its
      8  * documentation is hereby granted, provided that the above copyright
      9  * notice appears in all copies.
     10  *
     11  * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF
     12  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
     13  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
     14  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT.  SUN SHALL NOT BE LIABLE FOR
     15  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
     16  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
     17  *
     18  * Copyright (c) 1994 The Australian National University.
     19  * All rights reserved.
     20  *
     21  * Permission to use, copy, modify, and distribute this software and its
     22  * documentation is hereby granted, provided that the above copyright
     23  * notice appears in all copies.  This software is provided without any
     24  * warranty, express or implied. The Australian National University
     25  * makes no representations about the suitability of this software for
     26  * any purpose.
     27  *
     28  * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
     29  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     30  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
     31  * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY
     32  * OF SUCH DAMAGE.
     33  *
     34  * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
     35  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
     36  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     37  * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
     38  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
     39  * OR MODIFICATIONS.
     40  *
     41  * This driver is derived from the original SVR4 STREAMS PPP driver
     42  * originally written by Paul Mackerras <paul.mackerras (at) cs.anu.edu.au>.
     43  *
     44  * Adi Masputra <adi.masputra (at) sun.com> rewrote and restructured the code
     45  * for improved performance and scalability.
     46  */
     47 
     48 #define	RCSID	"$Id: sppp.c,v 1.0 2000/05/08 01:10:12 masputra Exp $"
     49 
     50 #include <sys/types.h>
     51 #include <sys/debug.h>
     52 #include <sys/param.h>
     53 #include <sys/stat.h>
     54 #include <sys/stream.h>
     55 #include <sys/stropts.h>
     56 #include <sys/sysmacros.h>
     57 #include <sys/errno.h>
     58 #include <sys/time.h>
     59 #include <sys/cmn_err.h>
     60 #include <sys/kmem.h>
     61 #include <sys/conf.h>
     62 #include <sys/dlpi.h>
     63 #include <sys/ddi.h>
     64 #include <sys/kstat.h>
     65 #include <sys/strsun.h>
     66 #include <sys/ethernet.h>
     67 #include <sys/policy.h>
     68 #include <net/ppp_defs.h>
     69 #include <net/pppio.h>
     70 #include "sppp.h"
     71 #include "s_common.h"
     72 
     73 /*
     74  * This is used to tag official Solaris sources.  Please do not define
     75  * "INTERNAL_BUILD" when building this software outside of Sun Microsystems.
     76  */
     77 #ifdef INTERNAL_BUILD
     78 /* MODINFO is limited to 32 characters. */
     79 const char sppp_module_description[] = "PPP 4.0 mux";
     80 #else /* INTERNAL_BUILD */
     81 const char sppp_module_description[] = "ANU PPP mux";
     82 
     83 /* LINTED */
     84 static const char buildtime[] = "Built " __DATE__ " at " __TIME__
     85 #ifdef DEBUG
     86 " DEBUG"
     87 #endif
     88 "\n";
     89 #endif /* INTERNAL_BUILD */
     90 
     91 static void	sppp_inner_ioctl(queue_t *, mblk_t *);
     92 static void	sppp_outer_ioctl(queue_t *, mblk_t *);
     93 static queue_t	*sppp_send(queue_t *, mblk_t **, spppstr_t *);
     94 static queue_t	*sppp_recv(queue_t *, mblk_t **, spppstr_t *);
     95 static void	sppp_recv_nondata(queue_t *, mblk_t *, spppstr_t *);
     96 static queue_t	*sppp_outpkt(queue_t *, mblk_t **, int, spppstr_t *);
     97 static spppstr_t *sppp_inpkt(queue_t *, mblk_t *, spppstr_t *);
     98 static int	sppp_kstat_update(kstat_t *, int);
     99 static void 	sppp_release_pkts(sppa_t *, uint16_t);
    100 
    101 /*
    102  * sps_list contains the list of active per-stream instance state structures
    103  * ordered on the minor device number (see sppp.h for details). All streams
    104  * opened to this driver are threaded together in this list.
    105  */
    106 static spppstr_t *sps_list = NULL;
    107 /*
    108  * ppa_list contains the list of active per-attachment instance state
    109  * structures ordered on the ppa id number (see sppp.h for details). All of
    110  * the ppa structures created once per PPPIO_NEWPPA ioctl are threaded together
    111  * in this list. There is exactly one ppa structure for a given PPP interface,
    112  * and multiple sps streams (upper streams) may share a ppa by performing
    113  * an attachment explicitly (PPPIO_ATTACH) or implicitly (DL_ATTACH_REQ).
    114  */
    115 static sppa_t *ppa_list = NULL;
    116 
    117 static const char *kstats_names[] = { SPPP_KSTATS_NAMES };
    118 static const char *kstats64_names[] = { SPPP_KSTATS64_NAMES };
    119 
    120 /*
    121  * map proto (which is an IANA defined ppp network protocol) to
    122  * a bit position indicated by NP_* in ppa_npflag
    123  */
    124 static uint32_t
    125 sppp_ppp2np(uint16_t proto)
    126 {
    127 	switch (proto) {
    128 	case PPP_IP:
    129 		return (NP_IP);
    130 	case PPP_IPV6:
    131 		return (NP_IPV6);
    132 	default:
    133 		return (0);
    134 	}
    135 }
    136 
    137 /*
    138  * sppp_open()
    139  *
    140  * MT-Perimeters:
    141  *    exclusive inner, exclusive outer.
    142  *
    143  * Description:
    144  *    Common open procedure for module.
    145  */
    146 /* ARGSUSED */
    147 int
    148 sppp_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *credp)
    149 {
    150 	spppstr_t	*sps;
    151 	spppstr_t	**nextmn;
    152 	minor_t		mn;
    153 
    154 	ASSERT(q != NULL && devp != NULL);
    155 	ASSERT(sflag != MODOPEN);
    156 
    157 	if (q->q_ptr != NULL) {
    158 		return (0);		/* already open */
    159 	}
    160 	if (sflag != CLONEOPEN) {
    161 		return (OPENFAIL);
    162 	}
    163 	/*
    164 	 * The sps list is sorted using the minor number as the key. The
    165 	 * following code walks the list to find the lowest valued minor
    166 	 * number available to be used.
    167 	 */
    168 	mn = 0;
    169 	for (nextmn = &sps_list; (sps = *nextmn) != NULL;
    170 	    nextmn = &sps->sps_nextmn) {
    171 		if (sps->sps_mn_id != mn) {
    172 			break;
    173 		}
    174 		++mn;
    175 	}
    176 	sps = (spppstr_t *)kmem_zalloc(sizeof (spppstr_t), KM_SLEEP);
    177 	ASSERT(sps != NULL);		/* KM_SLEEP must never return NULL */
    178 	sps->sps_nextmn = *nextmn;	/* insert stream in global list */
    179 	*nextmn = sps;
    180 	sps->sps_mn_id = mn;		/* save minor id for this stream */
    181 	sps->sps_rq = q;		/* save read queue pointer */
    182 	sps->sps_sap = -1;		/* no sap bound to stream */
    183 	sps->sps_dlstate = DL_UNATTACHED; /* dlpi state is unattached */
    184 	sps->sps_npmode = NPMODE_DROP;	/* drop all packets initially */
    185 	q->q_ptr = WR(q)->q_ptr = (caddr_t)sps;
    186 	/*
    187 	 * We explicitly disable the automatic queue scheduling for the
    188 	 * write-side to obtain complete control over queuing during transmit.
    189 	 * Packets will be queued at the upper write queue and the service
    190 	 * routine will not be called until it gets scheduled by having the
    191 	 * lower write service routine call the qenable(WR(uq)) for all streams
    192 	 * attached to the same ppa instance.
    193 	 */
    194 	noenable(WR(q));
    195 	*devp = makedevice(getmajor(*devp), mn);
    196 	qprocson(q);
    197 	return (0);
    198 }
    199 
    200 /*
    201  * Free storage used by a PPA.  This is not called until the last PPA
    202  * user closes his connection or reattaches to a different PPA.
    203  */
    204 static void
    205 sppp_free_ppa(sppa_t *ppa)
    206 {
    207 	sppa_t **nextppa;
    208 
    209 	ASSERT(ppa->ppa_refcnt == 1);
    210 	if (ppa->ppa_kstats != NULL) {
    211 		kstat_delete(ppa->ppa_kstats);
    212 		ppa->ppa_kstats = NULL;
    213 	}
    214 	mutex_destroy(&ppa->ppa_sta_lock);
    215 	mutex_destroy(&ppa->ppa_npmutex);
    216 	rw_destroy(&ppa->ppa_sib_lock);
    217 	nextppa = &ppa_list;
    218 	while (*nextppa != NULL) {
    219 		if (*nextppa == ppa) {
    220 			*nextppa = ppa->ppa_nextppa;
    221 			break;
    222 		}
    223 		nextppa = &(*nextppa)->ppa_nextppa;
    224 	}
    225 	kmem_free(ppa, sizeof (*ppa));
    226 }
    227 
    228 /*
    229  * Create a new PPA.  Caller must be exclusive on outer perimeter.
    230  */
    231 sppa_t *
    232 sppp_create_ppa(uint32_t ppa_id)
    233 {
    234 	sppa_t *ppa;
    235 	sppa_t *curppa;
    236 	sppa_t **availppa;
    237 	char unit[32];		/* Unit name */
    238 	const char **cpp;
    239 	kstat_t *ksp;
    240 	kstat_named_t *knt;
    241 
    242 	/*
    243 	 * NOTE: unit *must* be named for the driver
    244 	 * name plus the ppa number so that netstat
    245 	 * can find the statistics.
    246 	 */
    247 	(void) sprintf(unit, "%s" "%d", PPP_DRV_NAME, ppa_id);
    248 	/*
    249 	 * Make sure we can allocate a buffer to
    250 	 * contain the ppa to be sent upstream, as
    251 	 * well as the actual ppa structure and its
    252 	 * associated kstat structure.
    253 	 */
    254 	ppa = (sppa_t *)kmem_zalloc(sizeof (sppa_t),
    255 	    KM_NOSLEEP);
    256 	ksp = kstat_create(PPP_DRV_NAME, ppa_id, unit, "net", KSTAT_TYPE_NAMED,
    257 	    sizeof (sppp_kstats_t) / sizeof (kstat_named_t), 0);
    258 
    259 	if (ppa == NULL || ksp == NULL) {
    260 		if (ppa != NULL) {
    261 			kmem_free(ppa, sizeof (sppa_t));
    262 		}
    263 		if (ksp != NULL) {
    264 			kstat_delete(ksp);
    265 		}
    266 		return (NULL);
    267 	}
    268 	ppa->ppa_kstats = ksp;		/* chain kstat structure */
    269 	ppa->ppa_ppa_id = ppa_id;	/* record ppa id */
    270 	ppa->ppa_mtu = PPP_MAXMTU;	/* 65535-(PPP_HDRLEN+PPP_FCSLEN) */
    271 	ppa->ppa_mru = PPP_MAXMRU;	/* 65000 */
    272 
    273 	mutex_init(&ppa->ppa_sta_lock, NULL, MUTEX_DRIVER, NULL);
    274 	mutex_init(&ppa->ppa_npmutex, NULL, MUTEX_DRIVER, NULL);
    275 	rw_init(&ppa->ppa_sib_lock, NULL, RW_DRIVER, NULL);
    276 
    277 	/*
    278 	 * Prepare and install kstat counters.  Note that for netstat
    279 	 * -i to work, there needs to be "ipackets", "opackets",
    280 	 * "ierrors", and "oerrors" kstat named variables.
    281 	 */
    282 	knt = (kstat_named_t *)ksp->ks_data;
    283 	for (cpp = kstats_names; cpp < kstats_names + Dim(kstats_names);
    284 	    cpp++) {
    285 		kstat_named_init(knt, *cpp, KSTAT_DATA_UINT32);
    286 		knt++;
    287 	}
    288 	for (cpp = kstats64_names; cpp < kstats64_names + Dim(kstats64_names);
    289 	    cpp++) {
    290 		kstat_named_init(knt, *cpp, KSTAT_DATA_UINT64);
    291 		knt++;
    292 	}
    293 	ksp->ks_update = sppp_kstat_update;
    294 	ksp->ks_private = (void *)ppa;
    295 	kstat_install(ksp);
    296 
    297 	/* link to the next ppa and insert into global list */
    298 	availppa = &ppa_list;
    299 	while ((curppa = *availppa) != NULL) {
    300 		if (ppa_id < curppa->ppa_ppa_id)
    301 			break;
    302 		availppa = &curppa->ppa_nextppa;
    303 	}
    304 	ppa->ppa_nextppa = *availppa;
    305 	*availppa = ppa;
    306 	return (ppa);
    307 }
    308 
    309 /*
    310  * sppp_close()
    311  *
    312  * MT-Perimeters:
    313  *    exclusive inner, exclusive outer.
    314  *
    315  * Description:
    316  *    Common close procedure for module.
    317  */
    318 int
    319 sppp_close(queue_t *q)
    320 {
    321 	spppstr_t	*sps;
    322 	spppstr_t	**nextmn;
    323 	spppstr_t	*sib;
    324 	sppa_t		*ppa;
    325 	mblk_t		*mp;
    326 
    327 	ASSERT(q != NULL && q->q_ptr != NULL);
    328 	sps = (spppstr_t *)q->q_ptr;
    329 	qprocsoff(q);
    330 
    331 	ppa = sps->sps_ppa;
    332 	if (ppa == NULL) {
    333 		ASSERT(!IS_SPS_CONTROL(sps));
    334 		goto close_unattached;
    335 	}
    336 	if (IS_SPS_CONTROL(sps)) {
    337 		uint32_t	cnt = 0;
    338 
    339 		ASSERT(ppa != NULL);
    340 		ASSERT(ppa->ppa_ctl == sps);
    341 		ppa->ppa_ctl = NULL;
    342 		/*
    343 		 * STREAMS framework always issues I_UNLINK prior to close,
    344 		 * since we only allow I_LINK under the control stream.
    345 		 * A given ppa structure has at most one lower stream pointed
    346 		 * by the ppa_lower_wq field, because we only allow a single
    347 		 * linkage (I_LINK) to be done on the control stream.
    348 		 */
    349 		ASSERT(ppa->ppa_lower_wq == NULL);
    350 		/*
    351 		 * Walk through all of sibling streams attached to this ppa,
    352 		 * and remove all references to this ppa. We have exclusive
    353 		 * access for the entire driver here, so there's no need
    354 		 * to hold ppa_sib_lock.
    355 		 */
    356 		cnt++;
    357 		sib = ppa->ppa_streams;
    358 		while (sib != NULL) {
    359 			ASSERT(ppa == sib->sps_ppa);
    360 			sib->sps_npmode = NPMODE_DROP;
    361 			sib->sps_flags &= ~(SPS_PIOATTACH | SPS_CACHED);
    362 			/*
    363 			 * There should be a preallocated hangup
    364 			 * message here.  Fetch it and send it up to
    365 			 * the stream head.  This will cause IP to
    366 			 * mark the interface as "down."
    367 			 */
    368 			if ((mp = sib->sps_hangup) != NULL) {
    369 				sib->sps_hangup = NULL;
    370 				/*
    371 				 * M_HANGUP works with IP, but snoop
    372 				 * is lame and requires M_ERROR.  Send
    373 				 * up a clean error code instead.
    374 				 *
    375 				 * XXX if snoop is fixed, fix this, too.
    376 				 */
    377 				MTYPE(mp) = M_ERROR;
    378 				*mp->b_wptr++ = ENXIO;
    379 				putnext(sib->sps_rq, mp);
    380 			}
    381 			qenable(WR(sib->sps_rq));
    382 			cnt++;
    383 			sib = sib->sps_nextsib;
    384 		}
    385 		ASSERT(ppa->ppa_refcnt == cnt);
    386 	} else {
    387 		ASSERT(ppa->ppa_streams != NULL);
    388 		ASSERT(ppa->ppa_ctl != sps);
    389 		mp = NULL;
    390 		if (sps->sps_sap == PPP_IP) {
    391 			ppa->ppa_ip_cache = NULL;
    392 			mp = create_lsmsg(PPP_LINKSTAT_IPV4_UNBOUND);
    393 		} else if (sps->sps_sap == PPP_IPV6) {
    394 			ppa->ppa_ip6_cache = NULL;
    395 			mp = create_lsmsg(PPP_LINKSTAT_IPV6_UNBOUND);
    396 		}
    397 		/* Tell the daemon the bad news. */
    398 		if (mp != NULL && ppa->ppa_ctl != NULL &&
    399 		    (sps->sps_npmode == NPMODE_PASS ||
    400 		    sps->sps_npmode == NPMODE_QUEUE)) {
    401 			putnext(ppa->ppa_ctl->sps_rq, mp);
    402 		} else {
    403 			freemsg(mp);
    404 		}
    405 		/*
    406 		 * Walk through all of sibling streams attached to the
    407 		 * same ppa, and remove this stream from the sibling
    408 		 * streams list. We have exclusive access for the
    409 		 * entire driver here, so there's no need to hold
    410 		 * ppa_sib_lock.
    411 		 */
    412 		sib = ppa->ppa_streams;
    413 		if (sib == sps) {
    414 			ppa->ppa_streams = sps->sps_nextsib;
    415 		} else {
    416 			while (sib->sps_nextsib != NULL) {
    417 				if (sib->sps_nextsib == sps) {
    418 					sib->sps_nextsib = sps->sps_nextsib;
    419 					break;
    420 				}
    421 				sib = sib->sps_nextsib;
    422 			}
    423 		}
    424 		sps->sps_nextsib = NULL;
    425 		freemsg(sps->sps_hangup);
    426 		sps->sps_hangup = NULL;
    427 		/*
    428 		 * Check if this is a promiscous stream. If the SPS_PROMISC bit
    429 		 * is still set, it means that the stream is closed without
    430 		 * ever having issued DL_DETACH_REQ or DL_PROMISCOFF_REQ.
    431 		 * In this case, we simply decrement the promiscous counter,
    432 		 * and it's safe to do it without holding ppa_sib_lock since
    433 		 * we're exclusive (inner and outer) at this point.
    434 		 */
    435 		if (IS_SPS_PROMISC(sps)) {
    436 			ASSERT(ppa->ppa_promicnt > 0);
    437 			ppa->ppa_promicnt--;
    438 		}
    439 	}
    440 	/* If we're the only one left, then delete now. */
    441 	if (ppa->ppa_refcnt <= 1)
    442 		sppp_free_ppa(ppa);
    443 	else
    444 		ppa->ppa_refcnt--;
    445 close_unattached:
    446 	q->q_ptr = WR(q)->q_ptr = NULL;
    447 	for (nextmn = &sps_list; *nextmn != NULL;
    448 	    nextmn = &(*nextmn)->sps_nextmn) {
    449 		if (*nextmn == sps) {
    450 			*nextmn = sps->sps_nextmn;
    451 			break;
    452 		}
    453 	}
    454 	kmem_free(sps, sizeof (spppstr_t));
    455 	return (0);
    456 }
    457 
    458 static void
    459 sppp_ioctl(struct queue *q, mblk_t *mp)
    460 {
    461 	spppstr_t	*sps;
    462 	spppstr_t	*nextsib;
    463 	sppa_t		*ppa;
    464 	struct iocblk	*iop;
    465 	mblk_t		*nmp;
    466 	enum NPmode	npmode;
    467 	struct ppp_idle	*pip;
    468 	struct ppp_stats64 *psp;
    469 	struct ppp_comp_stats *pcsp;
    470 	hrtime_t	hrtime;
    471 	int		sap;
    472 	int		count = 0;
    473 	int		error = EINVAL;
    474 
    475 	sps = (spppstr_t *)q->q_ptr;
    476 	ppa = sps->sps_ppa;
    477 
    478 	iop = (struct iocblk *)mp->b_rptr;
    479 	switch (iop->ioc_cmd) {
    480 	case PPPIO_NPMODE:
    481 		if (!IS_SPS_CONTROL(sps)) {
    482 			break;		/* return EINVAL */
    483 		} else if (iop->ioc_count != 2 * sizeof (uint32_t) ||
    484 		    (mp->b_cont == NULL)) {
    485 			error = EPROTO;
    486 			break;
    487 		}
    488 		ASSERT(ppa != NULL);
    489 		ASSERT(mp->b_cont->b_rptr != NULL);
    490 		ASSERT(sps->sps_npmode == NPMODE_PASS);
    491 		sap = ((uint32_t *)mp->b_cont->b_rptr)[0];
    492 		npmode = (enum NPmode)((uint32_t *)mp->b_cont->b_rptr)[1];
    493 		/*
    494 		 * Walk the sibling streams which belong to the same
    495 		 * ppa, and try to find a stream with matching sap
    496 		 * number.
    497 		 */
    498 		rw_enter(&ppa->ppa_sib_lock, RW_WRITER);
    499 		for (nextsib = ppa->ppa_streams; nextsib != NULL;
    500 		    nextsib = nextsib->sps_nextsib) {
    501 			if (nextsib->sps_sap == sap) {
    502 				break;	/* found it */
    503 			}
    504 		}
    505 		if (nextsib == NULL) {
    506 			rw_exit(&ppa->ppa_sib_lock);
    507 			break;		/* return EINVAL */
    508 		} else {
    509 			nextsib->sps_npmode = npmode;
    510 			if ((nextsib->sps_npmode != NPMODE_QUEUE) &&
    511 			    (WR(nextsib->sps_rq)->q_first != NULL)) {
    512 				qenable(WR(nextsib->sps_rq));
    513 			}
    514 		}
    515 		rw_exit(&ppa->ppa_sib_lock);
    516 		error = 0;	/* return success */
    517 		break;
    518 	case PPPIO_GIDLE:
    519 		if (ppa == NULL) {
    520 			ASSERT(!IS_SPS_CONTROL(sps));
    521 			error = ENOLINK;
    522 			break;
    523 		} else if (!IS_PPA_TIMESTAMP(ppa)) {
    524 			break;		/* return EINVAL */
    525 		}
    526 		if ((nmp = allocb(sizeof (struct ppp_idle),
    527 		    BPRI_MED)) == NULL) {
    528 			mutex_enter(&ppa->ppa_sta_lock);
    529 			ppa->ppa_allocbfail++;
    530 			mutex_exit(&ppa->ppa_sta_lock);
    531 			error = ENOSR;
    532 			break;
    533 		}
    534 		if (mp->b_cont != NULL) {
    535 			freemsg(mp->b_cont);
    536 		}
    537 		mp->b_cont = nmp;
    538 		pip = (struct ppp_idle *)nmp->b_wptr;
    539 		nmp->b_wptr += sizeof (struct ppp_idle);
    540 		/*
    541 		 * Get current timestamp and subtract the tx and rx
    542 		 * timestamps to get the actual idle time to be
    543 		 * returned.
    544 		 */
    545 		hrtime = gethrtime();
    546 		pip->xmit_idle = (hrtime - ppa->ppa_lasttx) / 1000000000ul;
    547 		pip->recv_idle = (hrtime - ppa->ppa_lastrx) / 1000000000ul;
    548 		count = msgsize(nmp);
    549 		error = 0;
    550 		break;		/* return success (error is 0) */
    551 	case PPPIO_GTYPE:
    552 		nmp = allocb(sizeof (uint32_t), BPRI_MED);
    553 		if (nmp == NULL) {
    554 			error = ENOSR;
    555 			break;
    556 		}
    557 		if (mp->b_cont != NULL) {
    558 			freemsg(mp->b_cont);
    559 		}
    560 		mp->b_cont = nmp;
    561 		/*
    562 		 * Let the requestor know that we are the PPP
    563 		 * multiplexer (PPPTYP_MUX).
    564 		 */
    565 		*(uint32_t *)nmp->b_wptr = PPPTYP_MUX;
    566 		nmp->b_wptr += sizeof (uint32_t);
    567 		count = msgsize(nmp);
    568 		error = 0;		/* return success */
    569 		break;
    570 	case PPPIO_GETSTAT64:
    571 		if (ppa == NULL) {
    572 			break;		/* return EINVAL */
    573 		} else if ((ppa->ppa_lower_wq != NULL) &&
    574 		    !IS_PPA_LASTMOD(ppa)) {
    575 			mutex_enter(&ppa->ppa_sta_lock);
    576 			/*
    577 			 * We match sps_ioc_id on the M_IOC{ACK,NAK},
    578 			 * so if the response hasn't come back yet,
    579 			 * new ioctls must be queued instead.
    580 			 */
    581 			if (IS_SPS_IOCQ(sps)) {
    582 				mutex_exit(&ppa->ppa_sta_lock);
    583 				if (!putq(q, mp)) {
    584 					error = EAGAIN;
    585 					break;
    586 				}
    587 				return;
    588 			} else {
    589 				ppa->ppa_ioctlsfwd++;
    590 				/*
    591 				 * Record the ioctl CMD & ID - this will be
    592 				 * used to check the ACK or NAK responses
    593 				 * coming from below.
    594 				 */
    595 				sps->sps_ioc_id = iop->ioc_id;
    596 				sps->sps_flags |= SPS_IOCQ;
    597 				mutex_exit(&ppa->ppa_sta_lock);
    598 			}
    599 			putnext(ppa->ppa_lower_wq, mp);
    600 			return;	/* don't ack or nak the request */
    601 		}
    602 		nmp = allocb(sizeof (*psp), BPRI_MED);
    603 		if (nmp == NULL) {
    604 			mutex_enter(&ppa->ppa_sta_lock);
    605 			ppa->ppa_allocbfail++;
    606 			mutex_exit(&ppa->ppa_sta_lock);
    607 			error = ENOSR;
    608 			break;
    609 		}
    610 		if (mp->b_cont != NULL) {
    611 			freemsg(mp->b_cont);
    612 		}
    613 		mp->b_cont = nmp;
    614 		psp = (struct ppp_stats64 *)nmp->b_wptr;
    615 		/*
    616 		 * Copy the contents of ppp_stats64 structure for this
    617 		 * ppa and return them to the caller.
    618 		 */
    619 		mutex_enter(&ppa->ppa_sta_lock);
    620 		bcopy(&ppa->ppa_stats, psp, sizeof (*psp));
    621 		mutex_exit(&ppa->ppa_sta_lock);
    622 		nmp->b_wptr += sizeof (*psp);
    623 		count = sizeof (*psp);
    624 		error = 0;		/* return success */
    625 		break;
    626 	case PPPIO_GETCSTAT:
    627 		if (ppa == NULL) {
    628 			break;		/* return EINVAL */
    629 		} else if ((ppa->ppa_lower_wq != NULL) &&
    630 		    !IS_PPA_LASTMOD(ppa)) {
    631 			mutex_enter(&ppa->ppa_sta_lock);
    632 			/*
    633 			 * See comments in PPPIO_GETSTAT64 case
    634 			 * in sppp_ioctl().
    635 			 */
    636 			if (IS_SPS_IOCQ(sps)) {
    637 				mutex_exit(&ppa->ppa_sta_lock);
    638 				if (!putq(q, mp)) {
    639 					error = EAGAIN;
    640 					break;
    641 				}
    642 				return;
    643 			} else {
    644 				ppa->ppa_ioctlsfwd++;
    645 				/*
    646 				 * Record the ioctl CMD & ID - this will be
    647 				 * used to check the ACK or NAK responses
    648 				 * coming from below.
    649 				 */
    650 				sps->sps_ioc_id = iop->ioc_id;
    651 				sps->sps_flags |= SPS_IOCQ;
    652 				mutex_exit(&ppa->ppa_sta_lock);
    653 			}
    654 			putnext(ppa->ppa_lower_wq, mp);
    655 			return;	/* don't ack or nak the request */
    656 		}
    657 		nmp = allocb(sizeof (struct ppp_comp_stats), BPRI_MED);
    658 		if (nmp == NULL) {
    659 			mutex_enter(&ppa->ppa_sta_lock);
    660 			ppa->ppa_allocbfail++;
    661 			mutex_exit(&ppa->ppa_sta_lock);
    662 			error = ENOSR;
    663 			break;
    664 		}
    665 		if (mp->b_cont != NULL) {
    666 			freemsg(mp->b_cont);
    667 		}
    668 		mp->b_cont = nmp;
    669 		pcsp = (struct ppp_comp_stats *)nmp->b_wptr;
    670 		nmp->b_wptr += sizeof (struct ppp_comp_stats);
    671 		bzero((caddr_t)pcsp, sizeof (struct ppp_comp_stats));
    672 		count = msgsize(nmp);
    673 		error = 0;		/* return success */
    674 		break;
    675 	}
    676 
    677 	if (error == 0) {
    678 		/* Success; tell the user. */
    679 		miocack(q, mp, count, 0);
    680 	} else {
    681 		/* Failure; send error back upstream. */
    682 		miocnak(q, mp, 0, error);
    683 	}
    684 }
    685 
    686 /*
    687  * sppp_uwput()
    688  *
    689  * MT-Perimeters:
    690  *    shared inner, shared outer.
    691  *
    692  * Description:
    693  *    Upper write-side put procedure. Messages from above arrive here.
    694  */
    695 void
    696 sppp_uwput(queue_t *q, mblk_t *mp)
    697 {
    698 	queue_t		*nextq;
    699 	spppstr_t	*sps;
    700 	sppa_t		*ppa;
    701 	struct iocblk	*iop;
    702 	int		error;
    703 
    704 	ASSERT(q != NULL && q->q_ptr != NULL);
    705 	ASSERT(mp != NULL && mp->b_rptr != NULL);
    706 	sps = (spppstr_t *)q->q_ptr;
    707 	ppa = sps->sps_ppa;
    708 
    709 	switch (MTYPE(mp)) {
    710 	case M_PCPROTO:
    711 	case M_PROTO:
    712 		if (IS_SPS_CONTROL(sps)) {
    713 			ASSERT(ppa != NULL);
    714 			/*
    715 			 * Intentionally change this to a high priority
    716 			 * message so it doesn't get queued up. M_PROTO is
    717 			 * specifically used for signalling between pppd and its
    718 			 * kernel-level component(s), such as ppptun, so we
    719 			 * make sure that it doesn't get queued up behind
    720 			 * data messages.
    721 			 */
    722 			MTYPE(mp) = M_PCPROTO;
    723 			if ((ppa->ppa_lower_wq != NULL) &&
    724 			    canputnext(ppa->ppa_lower_wq)) {
    725 				mutex_enter(&ppa->ppa_sta_lock);
    726 				ppa->ppa_mctlsfwd++;
    727 				mutex_exit(&ppa->ppa_sta_lock);
    728 				putnext(ppa->ppa_lower_wq, mp);
    729 			} else {
    730 				mutex_enter(&ppa->ppa_sta_lock);
    731 				ppa->ppa_mctlsfwderr++;
    732 				mutex_exit(&ppa->ppa_sta_lock);
    733 				freemsg(mp);
    734 			}
    735 		} else {
    736 			(void) sppp_mproto(q, mp, sps);
    737 			return;
    738 		}
    739 		break;
    740 	case M_DATA:
    741 		if ((nextq = sppp_send(q, &mp, sps)) != NULL)
    742 			putnext(nextq, mp);
    743 		break;
    744 	case M_IOCTL:
    745 		error = EINVAL;
    746 		iop = (struct iocblk *)mp->b_rptr;
    747 		switch (iop->ioc_cmd) {
    748 		case DLIOCRAW:
    749 		case DL_IOC_HDR_INFO:
    750 		case PPPIO_ATTACH:
    751 		case PPPIO_DEBUG:
    752 		case PPPIO_DETACH:
    753 		case PPPIO_LASTMOD:
    754 		case PPPIO_MRU:
    755 		case PPPIO_MTU:
    756 		case PPPIO_USETIMESTAMP:
    757 		case PPPIO_BLOCKNP:
    758 		case PPPIO_UNBLOCKNP:
    759 			qwriter(q, mp, sppp_inner_ioctl, PERIM_INNER);
    760 			return;
    761 		case I_LINK:
    762 		case I_UNLINK:
    763 		case PPPIO_NEWPPA:
    764 			qwriter(q, mp, sppp_outer_ioctl, PERIM_OUTER);
    765 			return;
    766 		case PPPIO_NPMODE:
    767 		case PPPIO_GIDLE:
    768 		case PPPIO_GTYPE:
    769 		case PPPIO_GETSTAT64:
    770 		case PPPIO_GETCSTAT:
    771 			/*
    772 			 * These require additional auto variables to
    773 			 * handle, so (for optimization reasons)
    774 			 * they're moved off to a separate function.
    775 			 */
    776 			sppp_ioctl(q, mp);
    777 			return;
    778 		case PPPIO_GETSTAT:
    779 			break;			/* 32 bit interface gone */
    780 		default:
    781 			if (iop->ioc_cr == NULL ||
    782 			    secpolicy_net_config(iop->ioc_cr, B_FALSE) != 0) {
    783 				error = EPERM;
    784 				break;
    785 			} else if ((ppa == NULL) ||
    786 			    (ppa->ppa_lower_wq == NULL)) {
    787 				break;		/* return EINVAL */
    788 			}
    789 			mutex_enter(&ppa->ppa_sta_lock);
    790 			/*
    791 			 * See comments in PPPIO_GETSTAT64 case
    792 			 * in sppp_ioctl().
    793 			 */
    794 			if (IS_SPS_IOCQ(sps)) {
    795 				mutex_exit(&ppa->ppa_sta_lock);
    796 				if (!putq(q, mp)) {
    797 					error = EAGAIN;
    798 					break;
    799 				}
    800 				return;
    801 			} else {
    802 				ppa->ppa_ioctlsfwd++;
    803 				/*
    804 				 * Record the ioctl CMD & ID -
    805 				 * this will be used to check the
    806 				 * ACK or NAK responses coming from below.
    807 				 */
    808 				sps->sps_ioc_id = iop->ioc_id;
    809 				sps->sps_flags |= SPS_IOCQ;
    810 				mutex_exit(&ppa->ppa_sta_lock);
    811 			}
    812 			putnext(ppa->ppa_lower_wq, mp);
    813 			return;		/* don't ack or nak the request */
    814 		}
    815 		/* Failure; send error back upstream. */
    816 		miocnak(q, mp, 0, error);
    817 		break;
    818 	case M_FLUSH:
    819 		if (*mp->b_rptr & FLUSHW) {
    820 			flushq(q, FLUSHDATA);
    821 		}
    822 		if (*mp->b_rptr & FLUSHR) {
    823 			*mp->b_rptr &= ~FLUSHW;
    824 			qreply(q, mp);
    825 		} else {
    826 			freemsg(mp);
    827 		}
    828 		break;
    829 	default:
    830 		freemsg(mp);
    831 		break;
    832 	}
    833 }
    834 
    835 /*
    836  * sppp_uwsrv()
    837  *
    838  * MT-Perimeters:
    839  *    exclusive inner, shared outer.
    840  *
    841  * Description:
    842  *    Upper write-side service procedure. Note that this procedure does
    843  *    not get called when a message is placed on our write-side queue, since
    844  *    automatic queue scheduling has been turned off by noenable() when
    845  *    the queue was opened. We do this on purpose, as we explicitly control
    846  *    the write-side queue. Therefore, this procedure gets called when
    847  *    the lower write service procedure qenable() the upper write stream queue.
    848  */
    849 void
    850 sppp_uwsrv(queue_t *q)
    851 {
    852 	spppstr_t	*sps;
    853 	sppa_t		*ppa;
    854 	mblk_t		*mp;
    855 	queue_t		*nextq;
    856 	struct iocblk	*iop;
    857 
    858 	ASSERT(q != NULL && q->q_ptr != NULL);
    859 	sps = (spppstr_t *)q->q_ptr;
    860 
    861 	while ((mp = getq(q)) != NULL) {
    862 		if (MTYPE(mp) == M_IOCTL) {
    863 			ppa = sps->sps_ppa;
    864 			if ((ppa == NULL) || (ppa->ppa_lower_wq == NULL)) {
    865 				miocnak(q, mp, 0, EINVAL);
    866 				continue;
    867 			}
    868 
    869 			iop = (struct iocblk *)mp->b_rptr;
    870 			mutex_enter(&ppa->ppa_sta_lock);
    871 			/*
    872 			 * See comments in PPPIO_GETSTAT64 case
    873 			 * in sppp_ioctl().
    874 			 */
    875 			if (IS_SPS_IOCQ(sps)) {
    876 				mutex_exit(&ppa->ppa_sta_lock);
    877 				if (putbq(q, mp) == 0)
    878 					miocnak(q, mp, 0, EAGAIN);
    879 				break;
    880 			} else {
    881 				ppa->ppa_ioctlsfwd++;
    882 				sps->sps_ioc_id = iop->ioc_id;
    883 				sps->sps_flags |= SPS_IOCQ;
    884 				mutex_exit(&ppa->ppa_sta_lock);
    885 				putnext(ppa->ppa_lower_wq, mp);
    886 			}
    887 		} else if ((nextq =
    888 		    sppp_outpkt(q, &mp, msgdsize(mp), sps)) == NULL) {
    889 			if (mp != NULL) {
    890 				if (putbq(q, mp) == 0)
    891 					freemsg(mp);
    892 				break;
    893 			}
    894 		} else {
    895 			putnext(nextq, mp);
    896 		}
    897 	}
    898 }
    899 
    900 void
    901 sppp_remove_ppa(spppstr_t *sps)
    902 {
    903 	spppstr_t *nextsib;
    904 	sppa_t *ppa = sps->sps_ppa;
    905 
    906 	rw_enter(&ppa->ppa_sib_lock, RW_WRITER);
    907 	if (ppa->ppa_refcnt <= 1) {
    908 		rw_exit(&ppa->ppa_sib_lock);
    909 		sppp_free_ppa(ppa);
    910 	} else {
    911 		nextsib = ppa->ppa_streams;
    912 		if (nextsib == sps) {
    913 			ppa->ppa_streams = sps->sps_nextsib;
    914 		} else {
    915 			while (nextsib->sps_nextsib != NULL) {
    916 				if (nextsib->sps_nextsib == sps) {
    917 					nextsib->sps_nextsib =
    918 					    sps->sps_nextsib;
    919 					break;
    920 				}
    921 				nextsib = nextsib->sps_nextsib;
    922 			}
    923 		}
    924 		ppa->ppa_refcnt--;
    925 		/*
    926 		 * And if this stream was marked as promiscuous
    927 		 * (SPS_PROMISC), then we need to update the
    928 		 * promiscuous streams count. This should only happen
    929 		 * when DL_DETACH_REQ is issued prior to marking the
    930 		 * stream as non-promiscuous, through
    931 		 * DL_PROMISCOFF_REQ request.
    932 		 */
    933 		if (IS_SPS_PROMISC(sps)) {
    934 			ASSERT(ppa->ppa_promicnt > 0);
    935 			ppa->ppa_promicnt--;
    936 		}
    937 		rw_exit(&ppa->ppa_sib_lock);
    938 	}
    939 	sps->sps_nextsib = NULL;
    940 	sps->sps_ppa = NULL;
    941 	freemsg(sps->sps_hangup);
    942 	sps->sps_hangup = NULL;
    943 }
    944 
    945 sppa_t *
    946 sppp_find_ppa(uint32_t ppa_id)
    947 {
    948 	sppa_t *ppa;
    949 
    950 	for (ppa = ppa_list; ppa != NULL; ppa = ppa->ppa_nextppa) {
    951 		if (ppa->ppa_ppa_id == ppa_id) {
    952 			break;	/* found the ppa */
    953 		}
    954 	}
    955 	return (ppa);
    956 }
    957 
    958 /*
    959  * sppp_inner_ioctl()
    960  *
    961  * MT-Perimeters:
    962  *    exclusive inner, shared outer
    963  *
    964  * Description:
    965  *    Called by sppp_uwput as a result of receiving ioctls which require
    966  *    an exclusive access at the inner perimeter.
    967  */
    968 static void
    969 sppp_inner_ioctl(queue_t *q, mblk_t *mp)
    970 {
    971 	spppstr_t	*sps;
    972 	sppa_t		*ppa;
    973 	struct iocblk	*iop;
    974 	mblk_t		*nmp;
    975 	int		error = EINVAL;
    976 	int		count = 0;
    977 	int		dbgcmd;
    978 	int		mru, mtu;
    979 	uint32_t	ppa_id;
    980 	hrtime_t	hrtime;
    981 	uint16_t	proto;
    982 
    983 	ASSERT(q != NULL && q->q_ptr != NULL);
    984 	ASSERT(mp != NULL && mp->b_rptr != NULL);
    985 
    986 	sps = (spppstr_t *)q->q_ptr;
    987 	ppa = sps->sps_ppa;
    988 	iop = (struct iocblk *)mp->b_rptr;
    989 	switch (iop->ioc_cmd) {
    990 	case DLIOCRAW:
    991 		if (IS_SPS_CONTROL(sps)) {
    992 			break;		/* return EINVAL */
    993 		}
    994 		sps->sps_flags |= SPS_RAWDATA;
    995 		error = 0;		/* return success */
    996 		break;
    997 	case DL_IOC_HDR_INFO:
    998 		if (IS_SPS_CONTROL(sps)) {
    999 			break;		/* return EINVAL */
   1000 		} else if ((mp->b_cont == NULL) ||
   1001 		    *((t_uscalar_t *)mp->b_cont->b_rptr) != DL_UNITDATA_REQ ||
   1002 		    (MBLKL(mp->b_cont) < (sizeof (dl_unitdata_req_t) +
   1003 		    SPPP_ADDRL))) {
   1004 			error = EPROTO;
   1005 			break;
   1006 		} else if (ppa == NULL) {
   1007 			error = ENOLINK;
   1008 			break;
   1009 		}
   1010 		if ((nmp = allocb(PPP_HDRLEN, BPRI_MED)) == NULL) {
   1011 			mutex_enter(&ppa->ppa_sta_lock);
   1012 			ppa->ppa_allocbfail++;
   1013 			mutex_exit(&ppa->ppa_sta_lock);
   1014 			error = ENOMEM;
   1015 			break;
   1016 		}
   1017 		*(uchar_t *)nmp->b_wptr++ = PPP_ALLSTATIONS;
   1018 		*(uchar_t *)nmp->b_wptr++ = PPP_UI;
   1019 		*(uchar_t *)nmp->b_wptr++ = sps->sps_sap >> 8;
   1020 		*(uchar_t *)nmp->b_wptr++ = sps->sps_sap & 0xff;
   1021 		ASSERT(MBLKL(nmp) == PPP_HDRLEN);
   1022 
   1023 		linkb(mp, nmp);
   1024 		sps->sps_flags |= SPS_FASTPATH;
   1025 		error = 0;		/* return success */
   1026 		count = msgsize(nmp);
   1027 		break;
   1028 	case PPPIO_ATTACH:
   1029 		if (IS_SPS_CONTROL(sps) || IS_SPS_PIOATTACH(sps) ||
   1030 		    (sps->sps_dlstate != DL_UNATTACHED) ||
   1031 		    (iop->ioc_count != sizeof (uint32_t))) {
   1032 			break;		/* return EINVAL */
   1033 		} else if (mp->b_cont == NULL) {
   1034 			error = EPROTO;
   1035 			break;
   1036 		}
   1037 		ASSERT(mp->b_cont->b_rptr != NULL);
   1038 		/* If there's something here, it's detached. */
   1039 		if (ppa != NULL) {
   1040 			sppp_remove_ppa(sps);
   1041 		}
   1042 		ppa_id = *(uint32_t *)mp->b_cont->b_rptr;
   1043 		ppa = sppp_find_ppa(ppa_id);
   1044 		/*
   1045 		 * If we can't find it, then it's either because the requestor
   1046 		 * has supplied a wrong ppa_id to be attached to, or because
   1047 		 * the control stream for the specified ppa_id has been closed
   1048 		 * before we get here.
   1049 		 */
   1050 		if (ppa == NULL) {
   1051 			error = ENOENT;
   1052 			break;
   1053 		}
   1054 		/*
   1055 		 * Preallocate the hangup message so that we're always
   1056 		 * able to send this upstream in the event of a
   1057 		 * catastrophic failure.
   1058 		 */
   1059 		if ((sps->sps_hangup = allocb(1, BPRI_MED)) == NULL) {
   1060 			error = ENOSR;
   1061 			break;
   1062 		}
   1063 		/*
   1064 		 * There are two ways to attach a stream to a ppa: one is
   1065 		 * through DLPI (DL_ATTACH_REQ) and the other is through
   1066 		 * PPPIO_ATTACH. This is why we need to distinguish whether or
   1067 		 * not a stream was allocated via PPPIO_ATTACH, so that we can
   1068 		 * properly detach it when we receive PPPIO_DETACH ioctl
   1069 		 * request.
   1070 		 */
   1071 		sps->sps_flags |= SPS_PIOATTACH;
   1072 		sps->sps_ppa = ppa;
   1073 		/*
   1074 		 * Add this stream to the head of the list of sibling streams
   1075 		 * which belong to the same ppa as specified.
   1076 		 */
   1077 		rw_enter(&ppa->ppa_sib_lock, RW_WRITER);
   1078 		ppa->ppa_refcnt++;
   1079 		sps->sps_nextsib = ppa->ppa_streams;
   1080 		ppa->ppa_streams = sps;
   1081 		rw_exit(&ppa->ppa_sib_lock);
   1082 		error = 0;		/* return success */
   1083 		break;
   1084 	case PPPIO_BLOCKNP:
   1085 	case PPPIO_UNBLOCKNP:
   1086 		if (iop->ioc_cr == NULL ||
   1087 		    secpolicy_net_config(iop->ioc_cr, B_FALSE) != 0) {
   1088 			error = EPERM;
   1089 			break;
   1090 		}
   1091 		error = miocpullup(mp, sizeof (uint16_t));
   1092