summaryrefslogtreecommitdiffstats
path: root/sys/netatm/sigpvc
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1998-09-15 08:23:17 +0000
committerphk <phk@FreeBSD.org>1998-09-15 08:23:17 +0000
commitc3dd1fa899d435ea4bf79897f646a93cb80c94ac (patch)
tree98dfbc96e3c6aa7ff1f322855f6484c4e609819d /sys/netatm/sigpvc
parent9ed6892f4808d56de443849229e151f8f7ad43b0 (diff)
downloadFreeBSD-src-c3dd1fa899d435ea4bf79897f646a93cb80c94ac.zip
FreeBSD-src-c3dd1fa899d435ea4bf79897f646a93cb80c94ac.tar.gz
Add new files for HARP3
Host ATM Research Platform (HARP), Network Computing Services, Inc. This software was developed with the support of the Defense Advanced Research Projects Agency (DARPA).
Diffstat (limited to 'sys/netatm/sigpvc')
-rw-r--r--sys/netatm/sigpvc/sigpvc.h47
-rw-r--r--sys/netatm/sigpvc/sigpvc_if.c953
-rw-r--r--sys/netatm/sigpvc/sigpvc_subr.c181
-rw-r--r--sys/netatm/sigpvc/sigpvc_var.h95
4 files changed, 1276 insertions, 0 deletions
diff --git a/sys/netatm/sigpvc/sigpvc.h b/sys/netatm/sigpvc/sigpvc.h
new file mode 100644
index 0000000..893a682
--- /dev/null
+++ b/sys/netatm/sigpvc/sigpvc.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $Id: sigpvc.h,v 1.2 1997/05/06 22:15:43 mks Exp $
+ *
+ */
+
+/*
+ * PVC-only Signalling Manager
+ * ---------------------------
+ *
+ * Protocol definitions
+ *
+ */
+
+#ifndef _SIGPVC_SIGPVC_H
+#define _SIGPVC_SIGPVC_H
+
+/*
+ * Protocol Variables
+ */
+#define SIGPVC_DOWN_DELAY (15 * ATM_HZ) /* Delay til i/f marked down */
+#define SIGPVC_UP_DELAY (5 * ATM_HZ) /* Delay til i/f marked up */
+
+#endif /* _SIGPVC_SIGPVC_H */
diff --git a/sys/netatm/sigpvc/sigpvc_if.c b/sys/netatm/sigpvc/sigpvc_if.c
new file mode 100644
index 0000000..4208f29
--- /dev/null
+++ b/sys/netatm/sigpvc/sigpvc_if.c
@@ -0,0 +1,953 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $Id: sigpvc_if.c,v 1.13 1998/07/30 22:32:42 mks Exp $
+ *
+ */
+
+/*
+ * PVC-only Signalling Manager
+ * ---------------------------
+ *
+ * External interfaces to SigPVC manager. Includes support for
+ * running as a loadable kernel module.
+ *
+ */
+
+#ifndef lint
+static char *RCSid = "@(#) $Id: sigpvc_if.c,v 1.13 1998/07/30 22:32:42 mks Exp $";
+#endif
+
+#ifndef ATM_SIGPVC_MODULE
+#include "opt_atm.h"
+#endif
+
+#include <netatm/kern_include.h>
+
+#include <netatm/sigpvc/sigpvc.h>
+#include <netatm/sigpvc/sigpvc_var.h>
+
+
+/*
+ * Global variables
+ */
+struct sp_info sigpvc_vcpool = {
+ "sigpvc vcc pool", /* si_name */
+ sizeof(struct sigpvc_vccb), /* si_blksiz */
+ 10, /* si_blkcnt */
+ 50 /* si_maxallow */
+};
+
+/*
+ * Local functions
+ */
+static int sigpvc_start __P((void));
+static int sigpvc_stop __P((void));
+static int sigpvc_attach __P((struct sigmgr *, struct atm_pif *));
+static int sigpvc_detach __P((struct atm_pif *));
+static int sigpvc_setup __P((Atm_connvc *, int *));
+static int sigpvc_release __P((struct vccb *, int *));
+static int sigpvc_free __P((struct vccb *));
+static int sigpvc_ioctl __P((int, caddr_t, caddr_t));
+
+/*
+ * Local variables
+ */
+static int sigpvc_registered = 0;
+static struct sigmgr sigpvc_mgr = {
+ NULL,
+ ATM_SIG_PVC,
+ NULL,
+ sigpvc_attach,
+ sigpvc_detach,
+ sigpvc_setup,
+ NULL,
+ NULL,
+ sigpvc_release,
+ sigpvc_free,
+ sigpvc_ioctl
+};
+
+static struct attr_cause sigpvc_cause = {
+ T_ATM_PRESENT,
+ {
+ T_ATM_ITU_CODING,
+ T_ATM_LOC_USER,
+ T_ATM_CAUSE_UNSPECIFIED_NORMAL,
+ {0, 0, 0, 0}
+ }
+};
+
+
+/*
+ * Initialize sigpvc processing
+ *
+ * This will be called during module loading. We'll just register
+ * the sigpvc protocol descriptor and wait for a SigPVC ATM interface
+ * to come online.
+ *
+ * Arguments:
+ * none
+ *
+ * Returns:
+ * 0 startup was successful
+ * errno startup failed - reason indicated
+ *
+ */
+static int
+sigpvc_start()
+{
+ int err = 0;
+
+ /*
+ * Verify software version
+ */
+ if (atm_version != ATM_VERSION) {
+ log(LOG_ERR, "version mismatch: sigpvc=%d.%d kernel=%d.%d\n",
+ ATM_VERS_MAJ(ATM_VERSION), ATM_VERS_MIN(ATM_VERSION),
+ ATM_VERS_MAJ(atm_version), ATM_VERS_MIN(atm_version));
+ return (EINVAL);
+ }
+
+ /*
+ * Register ourselves with system
+ */
+ err = atm_sigmgr_register(&sigpvc_mgr);
+ if (err == 0)
+ sigpvc_registered = 1;
+
+ return (err);
+}
+
+
+/*
+ * Halt sigpvc processing
+ *
+ * This should be called just prior to unloading the module from
+ * memory. All sigpvc interfaces must be deregistered before the
+ * protocol can be shutdown.
+ *
+ * Arguments:
+ * none
+ *
+ * Returns:
+ * 0 shutdown was successful
+ * errno shutdown failed - reason indicated
+ *
+ */
+static int
+sigpvc_stop()
+{
+ int err = 0;
+ int s = splnet();
+
+ /*
+ * Is protocol even setup?
+ */
+ if (sigpvc_registered) {
+
+ /*
+ * Any protocol instances still registered??
+ */
+ if (sigpvc_mgr.sm_prinst) {
+
+ /* Yes, can't stop now */
+ err = EBUSY;
+ goto done;
+ }
+
+ /*
+ * De-register from system
+ */
+ err = atm_sigmgr_deregister(&sigpvc_mgr);
+ sigpvc_registered = 0;
+
+ /*
+ * Free up our vccb storage pool
+ */
+ atm_release_pool(&sigpvc_vcpool);
+ } else
+ err = ENXIO;
+
+done:
+ (void) splx(s);
+ return (err);
+}
+
+
+/*
+ * Attach a SigPVC-controlled interface
+ *
+ * Each ATM physical interface must be attached with the signalling manager for
+ * the interface's signalling protocol (via the atm_sigmgr_attach function).
+ * This function will handle the attachment for SigPVC-controlled interfaces.
+ * A new sigpvc protocol instance will be created and then we'll just sit
+ * around waiting for connection requests.
+ *
+ * Function must be called at splnet.
+ *
+ * Arguments:
+ * smp pointer to sigpvc signalling manager control block
+ * pip pointer to atm physical interface control block
+ *
+ * Returns:
+ * 0 attach successful
+ * errno attach failed - reason indicated
+ *
+ */
+static int
+sigpvc_attach(smp, pip)
+ struct sigmgr *smp;
+ struct atm_pif *pip;
+{
+ int err = 0;
+ struct sigpvc *pvp = NULL;
+
+ /*
+ * Allocate sigpvc protocol instance control block
+ */
+ pvp = (struct sigpvc *)
+ KM_ALLOC(sizeof(struct sigpvc), M_DEVBUF, M_NOWAIT);
+ if (pvp == NULL) {
+ err = ENOMEM;
+ goto done;
+ }
+ KM_ZERO(pvp, sizeof(struct sigpvc));
+
+ /*
+ * Link instance into manager's chain
+ */
+ LINK2TAIL((struct siginst *)pvp, struct siginst,
+ smp->sm_prinst, si_next);
+
+ /*
+ * Finally, set state and link in interface
+ */
+ pvp->pv_pif = pip;
+ pvp->pv_state = SIGPVC_ACTIVE;
+ pip->pif_sigmgr = smp;
+ pip->pif_siginst = (struct siginst *)pvp;
+
+done:
+ /*
+ * Reset our work if attach fails
+ */
+ if (err) {
+ pip->pif_sigmgr = NULL;
+ pip->pif_siginst = NULL;
+ if (pvp) {
+ UNLINK((struct siginst *)pvp, struct siginst,
+ smp->sm_prinst, si_next);
+ KM_FREE(pvp, sizeof(struct sigpvc), M_DEVBUF);
+ }
+ }
+
+ return (err);
+}
+
+
+/*
+ * Detach a SigPVC-controlled interface
+ *
+ * Each ATM physical interface may be detached from its signalling manager
+ * (via the atm_sigmgr_detach function). This function will handle the
+ * detachment for all SigPVC-controlled interfaces. All circuits will be
+ * immediately terminated.
+ *
+ * Function must be called at splnet.
+ *
+ * Arguments:
+ * pip pointer to atm physical interface control block
+ *
+ * Returns:
+ * 0 detach successful
+ * errno detach failed - reason indicated
+ *
+ */
+static int
+sigpvc_detach(pip)
+ struct atm_pif *pip;
+{
+ struct sigpvc *pvp;
+ struct vccb *vcp, *vnext;
+
+ /*
+ * Get SigPVC protocol instance
+ */
+ pvp = (struct sigpvc *)pip->pif_siginst;
+
+ /*
+ * Terminate all of our VCCs
+ */
+ for (vcp = Q_HEAD(pvp->pv_vccq, struct vccb); vcp; vcp = vnext){
+ u_char oustate;
+
+ vnext = Q_NEXT(vcp, struct vccb, vc_sigelem);
+
+ /*
+ * Close VCC and notify owner
+ */
+ oustate = vcp->vc_ustate;
+ sigpvc_close_vcc(vcp);
+ if (oustate == VCCU_OPEN) {
+ vcp->vc_connvc->cvc_attr.cause = sigpvc_cause;
+ atm_cm_cleared(vcp->vc_connvc);
+ }
+ }
+
+ /*
+ * If there are no vcc's queued, then get rid of the protocol
+ * instance.
+ */
+ if (Q_HEAD(pvp->pv_vccq, struct vccb) == NULL) {
+ struct sigmgr *smp = pip->pif_sigmgr;
+
+ pip->pif_sigmgr = NULL;
+ pip->pif_siginst = NULL;
+ UNLINK((struct siginst *)pvp, struct siginst, smp->sm_prinst,
+ si_next);
+ KM_FREE(pvp, sizeof(struct sigpvc), M_DEVBUF);
+ } else {
+
+ /*
+ * Otherwise, set new state indicating detach in progress.
+ * The protocol instance will be freed during sigpvc_free
+ * processing for the last queued vcc.
+ */
+ pvp->pv_state = SIGPVC_DETACH;
+ }
+
+ return (0);
+}
+
+
+/*
+ * Open a SigPVC ATM Connection
+ *
+ * All service user requests to open a VC connection (via atm_open_connection)
+ * over an ATM interface attached to the SigPVC signalling manager are handled
+ * here. Only PVC requests are allowed.
+ *
+ * Function will be called at splnet.
+ *
+ * Arguments:
+ * cvp pointer to CM's connection VCC
+ * errp location to store an error code if CALL_FAILED is returned
+ *
+ * Returns:
+ * CALL_PROCEEDING - connection establishment is in progress
+ * CALL_FAILED - connection establishment failed
+ * CALL_CONNECTED - connection has been successfully established
+ *
+ */
+static int
+sigpvc_setup(cvp, errp)
+ Atm_connvc *cvp;
+ int *errp;
+{
+ struct sigpvc *pvp =
+ (struct sigpvc *)cvp->cvc_attr.nif->nif_pif->pif_siginst;
+ int ret;
+
+ /*
+ * See what signalling has to say
+ */
+ switch (pvp->pv_state) {
+
+ case SIGPVC_ACTIVE:
+ break;
+
+ default:
+ *errp = ENXIO;
+ ret = CALL_FAILED;
+ goto done;
+ }
+
+ /*
+ * Open requested type of connection
+ */
+ switch (cvp->cvc_attr.called.addr.address_format) {
+
+ case T_ATM_PVC_ADDR:
+ /*
+ * Create a PVC
+ */
+ ret = sigpvc_create_pvc(pvp, cvp, errp);
+ break;
+
+ default:
+ *errp = EPROTONOSUPPORT;
+ ret = CALL_FAILED;
+ }
+
+done:
+ return (ret);
+}
+
+
+/*
+ * Close a SigPVC ATM Connection
+ *
+ * All service user requests to terminate a previously open VC connection
+ * (via the atm_close_connection function), which is running over an interface
+ * attached to the SigPVC signalling manager, are handled here.
+ *
+ * Function will be called at splnet.
+ *
+ * Arguments:
+ * vcp pointer to connection's VC control block
+ * errp location to store an error code if CALL_FAILED is returned
+ *
+ * Returns:
+ * CALL_PROCEEDING - connection termination is in progress
+ * CALL_FAILED - connection termination failed
+ * CALL_CLEARED - connection has been successfully terminated
+ *
+ */
+static int
+sigpvc_release(vcp, errp)
+ struct vccb *vcp;
+ int *errp;
+{
+
+ /*
+ * Make sure VCC is open
+ */
+ if ((vcp->vc_sstate == VCCS_NULL) || (vcp->vc_sstate == VCCS_FREE) ||
+ (vcp->vc_ustate == VCCU_NULL) || (vcp->vc_ustate == VCCU_CLOSED)) {
+ *errp = EALREADY;
+ return (CALL_FAILED);
+ }
+
+ /*
+ * Not much else to do except close the vccb
+ */
+ sigpvc_close_vcc(vcp);
+
+ return (CALL_CLEARED);
+}
+
+
+/*
+ * Free SigPVC ATM Connection Resources
+ *
+ * All service user requests to free the resources of a closed VCC connection
+ * (via the atm_free_connection function), which is running over an interface
+ * attached to the SigPVC signalling manager, are handled here.
+ *
+ * Function will be called at splnet.
+ *
+ * Arguments:
+ * vcp pointer to connection's VCC control block
+ *
+ * Returns:
+ * 0 connection free was successful
+ * errno connection free failed - reason indicated
+ *
+ */
+static int
+sigpvc_free(vcp)
+ struct vccb *vcp;
+{
+ struct atm_pif *pip = vcp->vc_pif;
+ struct sigpvc *pvp = (struct sigpvc *)pip->pif_siginst;
+
+ /*
+ * Make sure VCC has been closed
+ */
+ if ((vcp->vc_ustate != VCCU_CLOSED) || (vcp->vc_sstate != VCCS_FREE))
+ return (EEXIST);
+
+ /*
+ * Remove vccb from protocol queue
+ */
+ DEQUEUE(vcp, struct vccb, vc_sigelem, pvp->pv_vccq);
+
+ /*
+ * Free vccb storage
+ */
+ vcp->vc_ustate = VCCU_NULL;
+ vcp->vc_sstate = VCCS_NULL;
+ atm_free((caddr_t)vcp);
+
+ /*
+ * If we're detaching and this was the last vcc queued,
+ * get rid of the protocol instance
+ */
+ if ((pvp->pv_state == SIGPVC_DETACH) &&
+ (Q_HEAD(pvp->pv_vccq, struct vccb) == NULL)) {
+ struct sigmgr *smp = pip->pif_sigmgr;
+
+ pip->pif_sigmgr = NULL;
+ pip->pif_siginst = NULL;
+ UNLINK((struct siginst *)pvp, struct siginst, smp->sm_prinst,
+ si_next);
+ KM_FREE(pvp, sizeof(struct sigpvc), M_DEVBUF);
+ }
+
+ return (0);
+}
+
+
+/*
+ * Process Signalling Manager PF_ATM ioctls
+ *
+ * Function will be called at splnet.
+ *
+ * Arguments:
+ * code PF_ATM sub-operation code
+ * data pointer to code specific parameter data area
+ * arg1 pointer to code specific argument
+ *
+ * Returns:
+ * 0 request procesed
+ * errno error processing request - reason indicated
+ *
+ */
+static int
+sigpvc_ioctl(code, data, arg1)
+ int code;
+ caddr_t data;
+ caddr_t arg1;
+{
+ struct atmdelreq *adp;
+ struct atminfreq *aip;
+ struct air_vcc_rsp avr;
+ struct sigpvc *pvp;
+ struct vccb *vcp;
+ Atm_connection *cop;
+ caddr_t cp;
+ u_int vpi, vci;
+ int i, space, err = 0;
+
+
+ switch (code) {
+
+ case AIOCS_DEL_PVC:
+ /*
+ * Delete a PVC
+ */
+ adp = (struct atmdelreq *)data;
+ pvp = (struct sigpvc *)arg1;
+
+ /*
+ * Find requested VCC
+ */
+ vpi = adp->adr_pvc_vpi;
+ vci = adp->adr_pvc_vci;
+ for (vcp = Q_HEAD(pvp->pv_vccq, struct vccb); vcp;
+ vcp = Q_NEXT(vcp, struct vccb, vc_sigelem)) {
+ if ((vcp->vc_vpi == vpi) && (vcp->vc_vci == vci))
+ break;
+ }
+ if (vcp == NULL)
+ return (ENOENT);
+
+ /*
+ * Schedule VCC termination
+ */
+ err = atm_cm_abort(vcp->vc_connvc, &sigpvc_cause.v);
+ break;
+
+ case AIOCS_DEL_SVC:
+ /*
+ * Delete a SVC
+ */
+ err = ENOENT;
+ break;
+
+ case AIOCS_INF_VCC:
+ /*
+ * Get VCC information
+ */
+ aip = (struct atminfreq *)data;
+ pvp = (struct sigpvc *)arg1;
+
+ cp = aip->air_buf_addr;
+ space = aip->air_buf_len;
+
+ /*
+ * Get info for all VCCs on interface
+ */
+ for (vcp = Q_HEAD(pvp->pv_vccq, struct vccb); vcp;
+ vcp = Q_NEXT(vcp, struct vccb, vc_sigelem)) {
+ /*
+ * Make sure there's room in user buffer
+ */
+ if (space < sizeof(avr)) {
+ err = ENOSPC;
+ break;
+ }
+
+ /*
+ * Fill in info to be returned
+ */
+ (void) sprintf(avr.avp_intf, "%s%d",
+ pvp->pv_pif->pif_name, pvp->pv_pif->pif_unit);
+ avr.avp_vpi = vcp->vc_vpi;
+ avr.avp_vci = vcp->vc_vci;
+ avr.avp_type = vcp->vc_type;
+ avr.avp_sig_proto = ATM_SIG_PVC;
+ avr.avp_aal = vcp->vc_connvc->cvc_attr.aal.type;
+ cop = vcp->vc_connvc->cvc_conn;
+ if (cop)
+ avr.avp_encaps = cop->co_mpx;
+ else
+ avr.avp_encaps = 0;
+ KM_ZERO(avr.avp_owners, sizeof(avr.avp_owners));
+ for (i = 0; cop && i < sizeof(avr.avp_owners);
+ cop = cop->co_next,
+ i += T_ATM_APP_NAME_LEN+1) {
+ strncpy(&avr.avp_owners[i],
+ cop->co_endpt->ep_getname(cop->co_toku),
+ T_ATM_APP_NAME_LEN);
+ }
+ avr.avp_state = vcp->vc_sstate;
+ avr.avp_daddr.address_format = T_ATM_ABSENT;
+ avr.avp_dsubaddr.address_format = T_ATM_ABSENT;
+ avr.avp_ipdus = vcp->vc_ipdus;
+ avr.avp_opdus = vcp->vc_opdus;
+ avr.avp_ibytes = vcp->vc_ibytes;
+ avr.avp_obytes = vcp->vc_obytes;
+ avr.avp_ierrors = vcp->vc_ierrors;
+ avr.avp_oerrors = vcp->vc_oerrors;
+ avr.avp_tstamp = vcp->vc_tstamp;
+
+ /*
+ * Copy data to user buffer and update buffer info
+ */
+ if (err = copyout((caddr_t)&avr, cp, sizeof(avr)))
+ break;
+ cp += sizeof(avr);
+ space -= sizeof(avr);
+ }
+
+ /*
+ * Update buffer pointer/count
+ */
+ aip->air_buf_addr = cp;
+ aip->air_buf_len = space;
+ break;
+
+ case AIOCS_INF_ARP:
+ /*
+ * Get ARP table information
+ */
+ /* We don't maintain any ARP information */
+ break;
+
+ default:
+ err = EOPNOTSUPP;
+ }
+
+ return (err);
+}
+
+
+#ifdef ATM_SIGPVC_MODULE
+/*
+ *******************************************************************
+ *
+ * Loadable Module Support
+ *
+ *******************************************************************
+ */
+static int sigpvc_doload __P((void));
+static int sigpvc_dounload __P((void));
+
+/*
+ * Generic module load processing
+ *
+ * This function is called by an OS-specific function when this
+ * module is being loaded.
+ *
+ * Arguments:
+ * none
+ *
+ * Returns:
+ * 0 load was successful
+ * errno load failed - reason indicated
+ *
+ */
+static int
+sigpvc_doload()
+{
+ int err = 0;
+
+ /*
+ * Start us up
+ */
+ err = sigpvc_start();
+ if (err)
+ /* Problems, clean up */
+ (void)sigpvc_stop();
+
+ return (err);
+}
+
+
+/*
+ * Generic module unload processing
+ *
+ * This function is called by an OS-specific function when this
+ * module is being unloaded.
+ *
+ * Arguments:
+ * none
+ *
+ * Returns:
+ * 0 unload was successful
+ * errno unload failed - reason indicated
+ *
+ */
+static int
+sigpvc_dounload()
+{
+ int err = 0;
+
+ /*
+ * OK, try to clean up our mess
+ */
+ err = sigpvc_stop();
+
+ return (err);
+}
+
+
+#ifdef sun
+/*
+ * Loadable driver description
+ */
+struct vdldrv sigpvc_drv = {
+ VDMAGIC_PSEUDO, /* Pseudo Driver */
+ "sigpvc_mod", /* name */
+ NULL, /* dev_ops */
+ NULL, /* bdevsw */
+ NULL, /* cdevsw */
+ 0, /* blockmajor */
+ 0 /* charmajor */
+};
+
+
+/*
+ * Loadable module support entry point
+ *
+ * This is the routine called by the vd driver for all loadable module
+ * functions for this pseudo driver. This routine name must be specified
+ * on the modload(1) command. This routine will be called whenever the
+ * modload(1), modunload(1) or modstat(1) commands are issued for this
+ * module.
+ *
+ * Arguments:
+ * cmd vd command code
+ * vdp pointer to vd driver's structure
+ * vdi pointer to command-specific vdioctl_* structure
+ * vds pointer to status structure (VDSTAT only)
+ *
+ * Returns:
+ * 0 command was successful
+ * errno command failed - reason indicated
+ *
+ */
+int
+sigpvc_mod(cmd, vdp, vdi, vds)
+ int cmd;
+ struct vddrv *vdp;
+ caddr_t vdi;
+ struct vdstat *vds;
+{
+ int err = 0;
+
+ switch (cmd) {
+
+ case VDLOAD:
+ /*
+ * Module Load
+ *
+ * We dont support any user configuration
+ */
+ err = sigpvc_doload();
+ if (err == 0)
+ /* Let vd driver know about us */
+ vdp->vdd_vdtab = (struct vdlinkage *)&sigpvc_drv;
+ break;
+
+ case VDUNLOAD:
+ /*
+ * Module Unload
+ */
+ err = sigpvc_dounload();
+ break;
+
+ case VDSTAT:
+ /*
+ * Module Status
+ */
+
+ /* Not much to say at the moment */
+
+ break;
+
+ default:
+ log(LOG_ERR, "sigpvc_mod: Unknown vd command 0x%x\n", cmd);
+ err = EINVAL;
+ }
+
+ return (err);
+}
+#endif /* sun */
+
+#ifdef __FreeBSD__
+
+#include <sys/exec.h>
+#include <sys/sysent.h>
+#include <sys/lkm.h>
+
+/*
+ * Loadable miscellaneous module description
+ */
+MOD_MISC(sigpvc);
+
+
+/*
+ * Loadable module support "load" entry point
+ *
+ * This is the routine called by the lkm driver whenever the
+ * modload(1) command is issued for this module.
+ *
+ * Arguments:
+ * lkmtp pointer to lkm drivers's structure
+ * cmd lkm command code
+ *
+ * Returns:
+ * 0 command was successful
+ * errno command failed - reason indicated
+ *
+ */
+static int
+sigpvc_load(lkmtp, cmd)
+ struct lkm_table *lkmtp;
+ int cmd;
+{
+ return(sigpvc_doload());
+}
+
+
+/*
+ * Loadable module support "unload" entry point
+ *
+ * This is the routine called by the lkm driver whenever the
+ * modunload(1) command is issued for this module.
+ *
+ * Arguments:
+ * lkmtp pointer to lkm drivers's structure
+ * cmd lkm command code
+ *
+ * Returns:
+ * 0 command was successful
+ * errno command failed - reason indicated
+ *
+ */
+static int
+sigpvc_unload(lkmtp, cmd)
+ struct lkm_table *lkmtp;
+ int cmd;
+{
+ return(sigpvc_dounload());
+}
+
+
+/*
+ * Loadable module support entry point
+ *
+ * This is the routine called by the lkm driver for all loadable module
+ * functions for this driver. This routine name must be specified
+ * on the modload(1) command. This routine will be called whenever the
+ * modload(1), modunload(1) or modstat(1) commands are issued for this
+ * module.
+ *
+ * Arguments:
+ * lkmtp pointer to lkm drivers's structure
+ * cmd lkm command code
+ * ver lkm version
+ *
+ * Returns:
+ * 0 command was successful
+ * errno command failed - reason indicated
+ *
+ */
+int
+sigpvc_mod(lkmtp, cmd, ver)
+ struct lkm_table *lkmtp;
+ int cmd;
+ int ver;
+{
+ MOD_DISPATCH(sigpvc, lkmtp, cmd, ver,
+ sigpvc_load, sigpvc_unload, lkm_nullcmd);
+}
+#endif /* __FreeBSD__ */
+
+#else /* !ATM_SIGPVC_MODULE */
+
+/*
+ *******************************************************************
+ *
+ * Kernel Compiled Module Support
+ *
+ *******************************************************************
+ */
+static void sigpvc_doload __P((void *));
+
+SYSINIT(atmsigpvc, SI_SUB_PROTO_END, SI_ORDER_ANY, sigpvc_doload, NULL)
+
+/*
+ * Kernel initialization
+ *
+ * Arguments:
+ * arg Not used
+ *
+ * Returns:
+ * none
+ *
+ */
+static void
+sigpvc_doload(void *arg)
+{
+ int err = 0;
+
+ /*
+ * Start us up
+ */
+ err = sigpvc_start();
+ if (err) {
+ /* Problems, clean up */
+ (void)sigpvc_stop();
+
+ log(LOG_ERR, "ATM SIGPVC unable to initialize (%d)!!\n", err);
+ }
+ return;
+}
+#endif /* ATM_SIGPVC_MODULE */
+
diff --git a/sys/netatm/sigpvc/sigpvc_subr.c b/sys/netatm/sigpvc/sigpvc_subr.c
new file mode 100644
index 0000000..00f92ec
--- /dev/null
+++ b/sys/netatm/sigpvc/sigpvc_subr.c
@@ -0,0 +1,181 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $Id: sigpvc_subr.c,v 1.7 1998/06/29 21:52:25 mks Exp $
+ *
+ */
+
+/*
+ * PVC-only Signalling Manager
+ * ---------------------------
+ *
+ * Subroutines
+ *
+ */
+
+#ifndef lint
+static char *RCSid = "@(#) $Id: sigpvc_subr.c,v 1.7 1998/06/29 21:52:25 mks Exp $";
+#endif
+
+#include <netatm/kern_include.h>
+
+#include <netatm/sigpvc/sigpvc.h>
+#include <netatm/sigpvc/sigpvc_var.h>
+
+extern struct sp_info sigpvc_vcpool;
+
+/*
+ * Create a SigPVC Permanent Virtual Channel
+ *
+ * This function will construct a vccb for a "sigpvc-controlled" PVC
+ * and create the service stack requested by the user.
+ *
+ * Must be called at splnet.
+ *
+ * Arguments:
+ * pvp pointer to sigpvc protocol instance
+ * cvp pointer to CM's connection VCC
+ * errp location to store an error code if CALL_FAILED is returned
+ *
+ * Returns:
+ * CALL_FAILED - pvc creation failed
+ * CALL_CONNECTED - pvc has been successfully created
+ *
+ */
+int
+sigpvc_create_pvc(pvp, cvp, errp)
+ struct sigpvc *pvp;
+ Atm_connvc *cvp;
+ int *errp;
+{
+ Atm_addr_pvc *pp;
+ struct vccb *vcp;
+ u_int vpi, vci;
+
+ pp = (Atm_addr_pvc *)cvp->cvc_attr.called.addr.address;
+ vpi = ATM_PVC_GET_VPI(pp);
+ vci = ATM_PVC_GET_VCI(pp);
+
+ /*
+ * Verify requested VPI,VCI
+ */
+ if ((vpi > pvp->pv_pif->pif_maxvpi) ||
+ (vci == 0) || (vci > pvp->pv_pif->pif_maxvci)) {
+ *errp = ERANGE;
+ return (CALL_FAILED);
+ }
+
+ for (vcp = Q_HEAD(pvp->pv_vccq, struct vccb); vcp;
+ vcp = Q_NEXT(vcp, struct vccb, vc_sigelem)) {
+
+ if ((vcp->vc_vpi == vpi) &&
+ (vcp->vc_vci == vci)) {
+ *errp = EADDRINUSE;
+ return (CALL_FAILED);
+ }
+ }
+
+ /*
+ * Verify network interface
+ */
+ if (cvp->cvc_attr.nif) {
+ if (cvp->cvc_attr.nif->nif_pif != pvp->pv_pif) {
+ *errp = EINVAL;
+ return (CALL_FAILED);
+ }
+ }
+
+ /*
+ * Allocate control block for PVC
+ */
+ vcp = (struct vccb *)atm_allocate(&sigpvc_vcpool);
+ if (vcp == NULL) {
+ *errp = ENOMEM;
+ return (CALL_FAILED);
+ }
+
+ /*
+ * Fill in VCCB
+ */
+ vcp->vc_type = VCC_PVC | VCC_IN | VCC_OUT;
+ vcp->vc_proto = ATM_SIG_PVC;
+ vcp->vc_sstate = VCCS_ACTIVE;
+ vcp->vc_ustate = VCCU_OPEN;
+ vcp->vc_pif = pvp->pv_pif;
+ vcp->vc_nif = cvp->cvc_attr.nif;
+ vcp->vc_vpi = vpi;
+ vcp->vc_vci = vci;
+ vcp->vc_connvc = cvp;
+
+ /*
+ * Put VCCB on sigpvc queue
+ */
+ ENQUEUE(vcp, struct vccb, vc_sigelem, pvp->pv_vccq);
+
+ /*
+ * Pass back VCCB to connection manager
+ */
+ cvp->cvc_vcc = vcp;
+
+ /*
+ * PVC is ready to go!
+ */
+ return (CALL_CONNECTED);
+}
+
+/*
+ * Close a SigPVC VCC
+ *
+ * Clean up vccb, note that it's closing and wait for its freeing.
+ *
+ * Arguments:
+ * vcp pointer to connection's VCC control block
+ *
+ * Returns:
+ * none
+ *
+ */
+void
+sigpvc_close_vcc(vcp)
+ struct vccb *vcp;
+{
+
+ /*
+ * Sanity check (actually design-flaw check)
+ */
+ if (vcp->vc_connvc->cvc_upcnt || vcp->vc_connvc->cvc_downcnt)
+ panic("sigpvc_close_vcc: stack call");
+
+ /*
+ * Set state variables
+ */
+ vcp->vc_ustate = VCCU_CLOSED;
+ vcp->vc_sstate = VCCS_FREE;
+
+ /*
+ * Wait for user to free resources
+ */
+}
+
diff --git a/sys/netatm/sigpvc/sigpvc_var.h b/sys/netatm/sigpvc/sigpvc_var.h
new file mode 100644
index 0000000..24f92c0
--- /dev/null
+++ b/sys/netatm/sigpvc/sigpvc_var.h
@@ -0,0 +1,95 @@
+/*
+ *
+ * ===================================
+ * HARP | Host ATM Research Platform
+ * ===================================
+ *
+ *
+ * This Host ATM Research Platform ("HARP") file (the "Software") is
+ * made available by Network Computing Services, Inc. ("NetworkCS")
+ * "AS IS". NetworkCS does not provide maintenance, improvements or
+ * support of any kind.
+ *
+ * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
+ * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
+ * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
+ * In no event shall NetworkCS be responsible for any damages, including
+ * but not limited to consequential damages, arising from or relating to
+ * any use of the Software or related support.
+ *
+ * Copyright 1994-1998 Network Computing Services, Inc.
+ *
+ * Copies of this Software may be made, however, the above copyright
+ * notice must be reproduced on all copies.
+ *
+ * @(#) $Id: sigpvc_var.h,v 1.5 1998/02/19 20:16:28 mks Exp $
+ *
+ */
+
+/*
+ * PVC-only Signalling Manager
+ * ---------------------------
+ *
+ * Protocol control blocks
+ *
+ */
+
+#ifndef _SIGPVC_SIGPVC_VAR_H
+#define _SIGPVC_SIGPVC_VAR_H
+
+#ifdef ATM_KERNEL
+/*
+ * Structure containing state information for each SigPVC protocol instance.
+ * There will be one instance for each ATM device interface using the SigPVC
+ * signalling manager.
+ */
+struct sigpvc {
+ struct siginst pv_inst; /* Common header */
+};
+#define pv_next pv_inst.si_next
+#define pv_pif pv_inst.si_pif
+#define pv_addr pv_inst.si_addr
+#define pv_vccq pv_inst.si_vccq
+#define pv_state pv_inst.si_state
+#endif /* ATM_KERNEL */
+
+/*
+ * SigPVC Protocol States
+ */
+#define SIGPVC_ACTIVE 1 /* Active */
+#define SIGPVC_DETACH 2 /* Detach in progress */
+
+
+#ifdef ATM_KERNEL
+/*
+ * SigPVC Virtual Channel Connection control block. All information regarding
+ * the state of a SigPVC controlled VCC will be recorded here. There will be
+ * one SigPVC VCC control block for each SigPVC-controlled VCC.
+ */
+struct sigpvc_vccb {
+ struct vccb vcp_hdr; /* Generic vccb */
+};
+#endif /* ATM_KERNEL */
+
+/*
+ * SigPVC VCC Signalling Protocol States
+ */
+#define VCCS_NULL 0 /* No state */
+#define VCCS_ACTIVE 1 /* Active */
+#define VCCS_FREE 2 /* Waiting for user to free resources */
+
+
+#ifdef ATM_KERNEL
+/*
+ * Global function declarations
+ */
+ /* sigpvc_if.c */
+
+ /* sigpvc_subr.c */
+int sigpvc_create_pvc __P((struct sigpvc *, Atm_connvc *, int *));
+void sigpvc_close_vcc __P((struct vccb *));
+
+#endif /* ATM_KERNEL */
+
+#endif /* _SIGPVC_SIGPVC_VAR_H */
OpenPOWER on IntegriCloud