/*
* sppp.h - Solaris STREAMS PPP multiplexing pseudo-driver definitions
*
* 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
* documentation is hereby granted, provided that the above copyright
* notice appears in all copies.
*
* SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
*
* Copyright (c) 1994 The Australian National University.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, provided that the above copyright
* notice appears in all copies. This software is provided without any
* warranty, express or implied. The Australian National University
* makes no representations about the suitability of this software for
* any purpose.
*
* IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
* PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
* THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
* OR MODIFICATIONS.
*
* This driver is derived from the original SVR4 STREAMS PPP driver
* originally written by Paul Mackerras <paul.mackerras@cs.anu.edu.au>.
*
* Adi Masputra <adi.masputra@sun.com> rewrote and restructured the code
* for improved performance and scalability.
*
* $Id: sppp.h,v 1.0 2000/05/08 01:10:12 masputra Exp $
*/
#ifndef __SPPP_H
#define __SPPP_H
#include <sys/dlpi.h>
#include <net/ppp_defs.h>
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(ETHERTYPE_IP)
#define ETHERTYPE_IP 0x800
#endif
#if !defined(ETHERTYPE_IPV6)
#define ETHERTYPE_IPV6 0x86dd
#endif
#if !defined(ETHERTYPE_PPP)
#define ETHERTYPE_PPP 0x880b
#endif
#if !defined(ETHERTYPE_ALLSAP)
#define ETHERTYPE_ALLSAP 0
#endif
#if !defined(PPP_ALLSAP)
#define PPP_ALLSAP PPP_ALLSTATIONS
#endif
/*
* DLPI handler (function table item).
*/
struct sppp_dlpi_pinfo_t {
int pi_minlen; /* minimum primitive length */
int pi_state; /* acceptable starting state */
int (*pi_funcp)(); /* function() to call */
};
#ifndef DL_MAXPRIM
#define DL_MAXPRIM DL_GET_STATISTICS_ACK
#endif
/*
* Per-attachment kstats.
*/
typedef struct sppp_kstats {
kstat_named_t allocbfail;
kstat_named_t rbytes;
kstat_named_t ierrors;
kstat_named_t ierrors_lower;
kstat_named_t ioctlsfwd;
kstat_named_t ioctlsfwdok;
kstat_named_t ioctlsfwderr;
kstat_named_t ipackets;
kstat_named_t ipackets_ctl;
kstat_named_t iqdropped;
kstat_named_t irunts;
kstat_named_t itoolongs;
kstat_named_t lsneedup;
kstat_named_t lsdown;
kstat_named_t mctlsfwd;
kstat_named_t mctlsfwderr;
kstat_named_t mctlsknown;
kstat_named_t mctlsunknown;
kstat_named_t obytes;
kstat_named_t oerrors;
kstat_named_t oerrors_lower;
kstat_named_t opackets;
kstat_named_t opackets_ctl;
kstat_named_t oqdropped;
kstat_named_t otoolongs;
kstat_named_t orunts;
/* 64 bit entries */
kstat_named_t ipackets64;
kstat_named_t opackets64;
kstat_named_t rbytes64;
kstat_named_t obytes64;
} sppp_kstats_t;
/*
* Same order as above. Note that for netstat -i to work, there needs
* to be "ipackets", "opackets", "ierrors", and "oerrors" kstat named
* variables.
*/
#define SPPP_KSTATS_NAMES \
"allocbfail", "rbytes", "ierrors", "ierrors_lower", "ioctlsfwd", \
"ioctlsfwdok", "ioctlsfwderr", "ipackets", "ipkts_ctl", \
"ipkts_qdropped", "ipkts_runts", "ipkts_toolong", "lsneedup", \
"lsdown", "mctlsfwd", "mctlsfwderr", "mctlsknown", "mctlsunknown", \
"obytes", "oerrors", "oerrors_lower", "opackets", "opkts_ctl", \
"opkts_qdropped", "opkts_toolong", "opkts_runts"
#define SPPP_KSTATS64_NAMES \
"ipackets64", "opackets64", "rbytes64", "obytes64"
/*
* dl_addr_length needs to be equal to the absolute value of dl_sap_length,
* in order for IP to derive a default setting for IFF_POINTOPOINT flag.
*/
typedef t_uscalar_t spppreqsap_t;
#define SPPP_SAPL sizeof (spppreqsap_t)
#define SPPP_ADDRL SPPP_SAPL
/*
* Per-Stream instance state information.
*
* Each instance is dynamically allocated at open() and free'd at close().
* Each per-Stream instance points to at most one per-attachment structure
* using the sps_ppa field. All instances are threaded together into one
* list of active instances ordered on minor device number, using the
* sps_nextmn field.
*/
typedef struct spppstr {
/*
* Note that EX_st_nextmn field should never be referenced other
* than by the routines manipulating the global upper streams list,
* by first obtaining exclusive access at the outer perimeter.
*/
struct spppstr *sps_nextmn; /* next minor in global list */
/*
* These fields are common to all upper streams. If this stream
* is attached to a ppa, then the sps_ppa field will point to the
* ppa structure associated with this particular upper stream.
*/
minor_t sps_mn_id; /* minor device number of this stream */
queue_t *sps_rq; /* pointer to the read queue */
uint32_t sps_flags; /* miscellaneous flags */
uint32_t sps_ioc_id; /* last ioctl ID for this stream */
struct sppa *sps_ppa; /* pointer to ppa structure */
/*
* sps_nextsib is protected by the ppa's sibling lock (ppa_sib_lock),
* and access made to it should only be done by first ensuring that
* the sps_ppa field is valid, i.e., this stream has been attached.
*/
struct spppstr *sps_nextsib; /* next stream of same ppa (sibling) */
/*
* These fields are common to all non-control streams, i.e., those
* in which a PPPIO_NEWPPA has not been issued on. Non-control
* streams are valid candidates for network streams, and they can
* only be considered network streams (ones which carry IP packets)
* if they are attached and bound. The only mandatory requirement
* for control stream is that its sps_npmode field should always
* be equal to NPMODE_PASS, as we obviously will never block the
* control stream from sending or receiving packets.
*/
t_scalar_t sps_sap; /* bound sap */
spppreqsap_t sps_req_sap; /* requested sap */
enum NPmode sps_npmode; /* network protocol mode */
/*
* sps_dlstate is only valid for network streams in which DLPI
* is intended to be used to transfer network-layer data. It is set
* to DL_UNATTACHED for all other streams.
*/
t_uscalar_t sps_dlstate; /* current DLPI state */
mblk_t *sps_hangup; /* preallocated M_HANGUP message */
zoneid_t sps_zoneid; /* zone in which we were opened */
} spppstr_t;
/*
* Values for sps_flags, and their descriptions.
*/
/* 0x00000001 unused */
#define SPS_CONTROL 0x00000002 /* stream is a control stream */
#define SPS_FASTPATH 0x00000004 /* stream uses IP fastpath */
#define SPS_PROMISC 0x00000008 /* stream is promiscuous */
#define SPS_RAWDATA 0x00000010 /* raw M_DATA, no DLPI header */
#define SPS_PIOATTACH 0x00000020 /* attached using PPPIO_ATTACH */
#define SPS_KDEBUG 0x00000040 /* stream has kdebug turned on */
#define SPS_CACHED 0x00000080 /* network stream pointer is cached */
#define SPS_IOCQ 0x00000100 /* queue ioctls */
#define IS_SPS_CONTROL(x) \
((x)->sps_flags & SPS_CONTROL)
#define IS_SPS_FASTPATH(x) \
((x)->sps_flags & SPS_FASTPATH)
#define IS_SPS_PROMISC(x) \
((x)->sps_flags & SPS_PROMISC)
#define IS_SPS_RAWDATA(x) \
((x)->sps_flags & SPS_RAWDATA)
#define IS_SPS_PIOATTACH(x) \
((x)->sps_flags & SPS_PIOATTACH)
#define IS_SPS_KDEBUG(x) \
((x)->sps_flags & SPS_KDEBUG)
#define IS_SPS_CACHED(x) \
((x)->sps_flags & SPS_CACHED)
#define IS_SPS_IOCQ(x) \
((x)->sps_flags & SPS_IOCQ)
/*
* Bit format (octal based) string for cmn_err, which represents the flags.
*/
#define SPS_FLAGS_STR \
"\020" \
"\1priv" \
"\2control" \
"\3fastpath" \
"\4promisc" \
"\5rawdata" \
"\6pioattach" \
"\7kdebug" \
"\10cached"
/*
* Per-Attachment instance state information.
*
* Each instance is dynamically allocated on first attach (PPPIO_NEWPPA).
* Allocation of this structure is only done once per control stream. A ppa
* instance may be shared by two or more upper streams, and it is always
* linked to the upper stream marked as the control stream (SPS_CONTROL)
* via the ppa_ctl field. Non-control streams are linked to ppa_streams.
*/
typedef struct sppa {
/*
* Note that EX_st_nextppa field should only be accessed (walked)
* by the ppa manipulation routines, i.e, those which affect
* the global ppa list, e.g: open, close, new_ppa, and XX_attach_upper.
*/
struct sppa *ppa_nextppa; /* next attachment instance */
/*
* ppa_sib_lock guards the linkages between all upper streams related
* to this ppa. Walking the sps_nextsib of any upper streams should
* be done by first holding this lock.
*/
krwlock_t ppa_sib_lock; /* lock for sibling upper streams */
uint32_t ppa_flags; /* miscellaneous flags */
int32_t ppa_refcnt; /* upper stream reference count */
uint32_t ppa_ppa_id; /* unique attachment id */
spppstr_t *ppa_streams; /* list of all non-control streams */
spppstr_t *ppa_ctl; /* back pointer to control stream */
queue_t *ppa_lower_wq; /* pointer to lower write queue */
uint16_t ppa_mru; /* link layer maximum receive unit */
uint16_t ppa_mtu; /* link layer maximum transmit unit */
hrtime_t ppa_lasttx; /* last transmit time for a packet */
hrtime_t ppa_lastrx; /* last receive time for a packet */
int32_t ppa_promicnt; /* promiscous stream count */
/*
* ppa_sta_lock mutex guards the statistic fields of this ppa, since
* this structure is shared by upper streams of the same ppa.
*/
kmutex_t ppa_sta_lock; /* mutex to lock structure */
struct ppp_stats64 ppa_stats; /* legacy stats structure */
uint32_t ppa_allocbfail; /* memory allocation failure count */
uint32_t ppa_ierr_low; /* errors from below during receive */
uint32_t ppa_ioctlsfwd; /* total ioctl forwarded down */
uint32_t ppa_ioctlsfwdok; /* and the reply sent upward */
uint32_t ppa_ioctlsfwderr; /* or discarded replies */
uint32_t ppa_ipkt_ctl; /* received control pkts */
uint32_t ppa_iqdropped; /* msg dropped due to putq error */
uint32_t ppa_irunts; /* packet rcvd is too short */
uint32_t ppa_itoolongs; /* packet rcvd is larger than MRU */
uint32_t ppa_lsneedup; /* total LINKSTAT_NEEDUP msg sent up */
uint32_t ppa_lsdown; /* total LINKSTAT_DOWN msg sent up */
uint32_t ppa_mctlsfwd; /* total M_{PC}PROTO forwarded down */
uint32_t ppa_mctlsfwderr; /* and discarded count */
uint32_t ppa_mctlsknown; /* total known M_CTL messages */
uint32_t ppa_mctlsunknown; /* total unknown M_CTL messages */
uint32_t ppa_oerr_low; /* errors from below during transmit */
uint32_t ppa_opkt_ctl; /* transmitted control pkts */
uint32_t ppa_oqdropped; /* msg dropped due to putq error */
uint32_t ppa_orunts; /* packet sent is too short */
uint32_t ppa_otoolongs; /* packet sent is larger than MTU */
kstat_t *ppa_kstats; /* pointer to kstats structure */
/*
* We keep the following pointers for performance reasons. Instead
* of walking the list of attached upper streams to find the
* destination upper stream everytime we need to send a packet up,
* we keep them here for easy access.
*/
spppstr_t *ppa_ip_cache; /* ptr to PPP_IP upper stream */
spppstr_t *ppa_ip6_cache; /* ptr to PPP_IPV6 upper stream */
kmutex_t ppa_npmutex; /* protects the 2 fields below */
uint32_t ppa_npflag; /* network protocols blocked */
uint32_t ppa_holdpkts[3]; /* # of packets blocked per np */
zoneid_t ppa_zoneid; /* zone where PPA is in use */
} sppa_t;
/* bit position (in ppa_npflag) for each ppp_protocol that can be blocked */
#define NP_IP 1
#define NP_IPV6 2
/*
* Values for ppa_flags, and their descriptions.
*/
#define PPA_LASTMOD 0x00000001 /* last PPP entity on the stream */
#define PPA_TIMESTAMP 0x00000002 /* time-stamp each packet */
#define IS_PPA_LASTMOD(x) \
((x)->ppa_flags & PPA_LASTMOD)
#define IS_PPA_TIMESTAMP(x) \
((x)->ppa_flags & PPA_TIMESTAMP)
/*
* Bit format (octal based) string for cmn_err, which represents the flags.
*/
#define PPA_FLAGS_STR \
"\020" \
"\1lastmod" \
"\2timestamp"
/*
* General macros.
*/
#define SPDEBUG printf
/*
* Function declarations.
*/
extern int sppp_close(queue_t *);
extern mblk_t *sppp_dladdud(spppstr_t *, mblk_t *, t_scalar_t, boolean_t);
extern void sppp_dlpi_pinfoinit(void);
extern void sppp_dlprsendup(spppstr_t *, mblk_t *, t_scalar_t, boolean_t);
extern void sppp_lrput(queue_t *, mblk_t *);
extern void sppp_lrsrv(queue_t *);
extern void sppp_lwsrv(queue_t *);
extern int sppp_mproto(queue_t *, mblk_t *, spppstr_t *);
extern int sppp_open(queue_t *, dev_t *, int, int, cred_t *);
extern void sppp_uwput(queue_t *, mblk_t *);
extern void sppp_uwsrv(queue_t *);
extern void sppp_remove_ppa(spppstr_t *sps);
extern sppa_t *sppp_find_ppa(uint32_t ppa_id);
extern sppa_t *sppp_create_ppa(uint32_t ppa_id, zoneid_t zoneid);
#ifdef __cplusplus
}
#endif
#endif /* __SPPP_H */