diff options
Diffstat (limited to 'usr/src/uts/common/io/ppp/sppp/sppp.c')
-rw-r--r-- | usr/src/uts/common/io/ppp/sppp/sppp.c | 60 |
1 files changed, 48 insertions, 12 deletions
diff --git a/usr/src/uts/common/io/ppp/sppp/sppp.c b/usr/src/uts/common/io/ppp/sppp/sppp.c index 147cd04a20..c810a37dec 100644 --- a/usr/src/uts/common/io/ppp/sppp/sppp.c +++ b/usr/src/uts/common/io/ppp/sppp/sppp.c @@ -1,7 +1,7 @@ /* * sppp.c - Solaris STREAMS PPP multiplexing pseudo-driver * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Permission to use, copy, modify, and distribute this software and its @@ -65,6 +65,7 @@ #include <sys/strsun.h> #include <sys/ethernet.h> #include <sys/policy.h> +#include <sys/zone.h> #include <net/ppp_defs.h> #include <net/pppio.h> #include "sppp.h" @@ -182,6 +183,7 @@ sppp_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *credp) sps->sps_sap = -1; /* no sap bound to stream */ sps->sps_dlstate = DL_UNATTACHED; /* dlpi state is unattached */ sps->sps_npmode = NPMODE_DROP; /* drop all packets initially */ + sps->sps_zoneid = crgetzoneid(credp); q->q_ptr = WR(q)->q_ptr = (caddr_t)sps; /* * We explicitly disable the automatic queue scheduling for the @@ -229,7 +231,7 @@ sppp_free_ppa(sppa_t *ppa) * Create a new PPA. Caller must be exclusive on outer perimeter. */ sppa_t * -sppp_create_ppa(uint32_t ppa_id) +sppp_create_ppa(uint32_t ppa_id, zoneid_t zoneid) { sppa_t *ppa; sppa_t *curppa; @@ -267,6 +269,7 @@ sppp_create_ppa(uint32_t ppa_id) } ppa->ppa_kstats = ksp; /* chain kstat structure */ ppa->ppa_ppa_id = ppa_id; /* record ppa id */ + ppa->ppa_zoneid = zoneid; /* zone that owns this PPA */ ppa->ppa_mtu = PPP_MAXMTU; /* 65535-(PPP_HDRLEN+PPP_FCSLEN) */ ppa->ppa_mru = PPP_MAXMRU; /* 65000 */ @@ -779,7 +782,7 @@ sppp_uwput(queue_t *q, mblk_t *mp) break; /* 32 bit interface gone */ default: if (iop->ioc_cr == NULL || - secpolicy_net_config(iop->ioc_cr, B_FALSE) != 0) { + secpolicy_ppp_config(iop->ioc_cr) != 0) { error = EPERM; break; } else if ((ppa == NULL) || @@ -1051,6 +1054,11 @@ sppp_inner_ioctl(queue_t *q, mblk_t *mp) error = ENOENT; break; } + if (iop->ioc_cr == NULL || + ppa->ppa_zoneid != crgetzoneid(iop->ioc_cr)) { + error = EPERM; + break; + } /* * Preallocate the hangup message so that we're always * able to send this upstream in the event of a @@ -1084,7 +1092,7 @@ sppp_inner_ioctl(queue_t *q, mblk_t *mp) case PPPIO_BLOCKNP: case PPPIO_UNBLOCKNP: if (iop->ioc_cr == NULL || - secpolicy_net_config(iop->ioc_cr, B_FALSE) != 0) { + secpolicy_ppp_config(iop->ioc_cr) != 0) { error = EPERM; break; } @@ -1116,7 +1124,7 @@ sppp_inner_ioctl(queue_t *q, mblk_t *mp) break; case PPPIO_DEBUG: if (iop->ioc_cr == NULL || - secpolicy_net_config(iop->ioc_cr, B_FALSE) != 0) { + secpolicy_ppp_config(iop->ioc_cr) != 0) { error = EPERM; break; } else if (iop->ioc_count != sizeof (uint32_t)) { @@ -1293,7 +1301,7 @@ sppp_inner_ioctl(queue_t *q, mblk_t *mp) static void sppp_outer_ioctl(queue_t *q, mblk_t *mp) { - spppstr_t *sps; + spppstr_t *sps = q->q_ptr; spppstr_t *nextsib; queue_t *lwq; sppa_t *ppa; @@ -1302,9 +1310,7 @@ sppp_outer_ioctl(queue_t *q, mblk_t *mp) int count = 0; uint32_t ppa_id; mblk_t *nmp; - - ASSERT(q != NULL && q->q_ptr != NULL); - ASSERT(mp != NULL && mp->b_rptr != NULL); + zoneid_t zoneid; sps = (spppstr_t *)q->q_ptr; ppa = sps->sps_ppa; @@ -1340,6 +1346,14 @@ sppp_outer_ioctl(queue_t *q, mblk_t *mp) qenable(WR(nextsib->sps_rq)); } } + + /* + * Also unblock (run once) our lower read-side queue. This is + * where packets received while doing the I_LINK may be + * languishing; see sppp_lrsrv. + */ + qenable(RD(lwq)); + /* * Send useful information down to the modules which are now * linked below this driver (for this particular ppa). Only @@ -1412,7 +1426,7 @@ sppp_outer_ioctl(queue_t *q, mblk_t *mp) * a control stream. */ if (iop->ioc_cr == NULL || - secpolicy_net_config(iop->ioc_cr, B_FALSE) != 0) { + secpolicy_ppp_config(iop->ioc_cr) != 0) { error = EPERM; break; } else if (IS_SPS_CONTROL(sps) || IS_SPS_PIOATTACH(sps) || @@ -1440,9 +1454,11 @@ sppp_outer_ioctl(queue_t *q, mblk_t *mp) */ if (ppa_id == (uint32_t)-1) ppa_id = 0; + zoneid = crgetzoneid(iop->ioc_cr); for (ppa = ppa_list; ppa != NULL; ppa = ppa->ppa_nextppa) { if (ppa_id == (uint32_t)-2) { - if (ppa->ppa_ctl == NULL) + if (ppa->ppa_ctl == NULL && + ppa->ppa_zoneid == zoneid) break; } else { if (ppa_id < ppa->ppa_ppa_id) @@ -1459,7 +1475,7 @@ sppp_outer_ioctl(queue_t *q, mblk_t *mp) /* Clear timestamp and lastmod flags */ ppa->ppa_flags = 0; } else { - ppa = sppp_create_ppa(ppa_id); + ppa = sppp_create_ppa(ppa_id, zoneid); if (ppa == NULL) { error = ENOMEM; break; @@ -1804,6 +1820,26 @@ sppp_lrput(queue_t *q, mblk_t *mp) } /* + * sppp_lrsrv() + * + * MT-Perimeters: + * exclusive inner, shared outer. + * + * Description: + * Lower read-side service procedure. This is run once after the I_LINK + * occurs in order to clean up any packets that came in while we were + * transferring in the lower stream. Otherwise, it's not used. + */ +void +sppp_lrsrv(queue_t *q) +{ + mblk_t *mp; + + while ((mp = getq(q)) != NULL) + sppp_lrput(q, mp); +} + +/* * sppp_recv_nondata() * * MT-Perimeters: |