summaryrefslogtreecommitdiffstats
path: root/sys/netatm/spans/spans_if.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2008-05-25 22:11:40 +0000
committerrwatson <rwatson@FreeBSD.org>2008-05-25 22:11:40 +0000
commita3623cb733d4a3ddcf8ba280724b8ce3f19a7a58 (patch)
treeafe56b8f23cfc7884850445d064a110b6ac85c9e /sys/netatm/spans/spans_if.c
parent2f956b205ca6c855f85983809448ddc387407d46 (diff)
downloadFreeBSD-src-a3623cb733d4a3ddcf8ba280724b8ce3f19a7a58.zip
FreeBSD-src-a3623cb733d4a3ddcf8ba280724b8ce3f19a7a58.tar.gz
Remove netatm from HEAD as it is not MPSAFE and relies on the now removed
NET_NEEDS_GIANT. netatm has been disconnected from the build for ten months in HEAD/RELENG_7. Specifics: - netatm include files - netatm command line management tools - libatm - ATM parts in rescue and sysinstall - sample configuration files and documents - kernel support as a module or in NOTES - netgraph wrapper nodes for netatm - ctags data for netatm. - netatm-specific device drivers. MFC after: 3 weeks Reviewed by: bz Discussed with: bms, bz, harti
Diffstat (limited to 'sys/netatm/spans/spans_if.c')
-rw-r--r--sys/netatm/spans/spans_if.c1272
1 files changed, 0 insertions, 1272 deletions
diff --git a/sys/netatm/spans/spans_if.c b/sys/netatm/spans/spans_if.c
deleted file mode 100644
index 6587812..0000000
--- a/sys/netatm/spans/spans_if.c
+++ /dev/null
@@ -1,1272 +0,0 @@
-/*-
- * ===================================
- * 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.
- */
-
-/*
- * SPANS Signalling Manager
- * ---------------------------
- *
- * External interfaces to SPANS manager. Includes support for
- * running as a loadable kernel module.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#ifndef ATM_SPANS_MODULE
-#include "opt_atm.h"
-#endif
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-#include <sys/malloc.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/syslog.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netatm/port.h>
-#include <netatm/queue.h>
-#include <netatm/atm.h>
-#include <netatm/atm_sys.h>
-#include <netatm/atm_sap.h>
-#include <netatm/atm_cm.h>
-#include <netatm/atm_if.h>
-#include <netatm/atm_vc.h>
-#include <netatm/atm_ioctl.h>
-#include <netatm/atm_sigmgr.h>
-#include <netatm/atm_stack.h>
-#include <netatm/atm_pcb.h>
-#include <netatm/atm_var.h>
-
-#include "spans_xdr.h"
-#include <netatm/spans/spans_var.h>
-
-/*
- * Global variables
- */
-uma_zone_t spans_vc_zone;
-uma_zone_t spans_msg_zone;
-
-/*
- * Local functions
- */
-static int spans_start(void);
-static int spans_stop(void);
-static int spans_attach(struct sigmgr *, struct atm_pif *);
-static int spans_detach(struct atm_pif *);
-static int spans_setup(Atm_connvc *, int *);
-static int spans_release(struct vccb *, int *);
-static int spans_accept(struct vccb *, int *);
-static int spans_reject(struct vccb *, int *);
-static int spans_ioctl(int, caddr_t, caddr_t);
-
-/*
- * Local variables
- */
-static struct sigmgr *spans_mgr = NULL;
-
-
-/*
- * Initialize SPANS processing
- *
- * This will be called during module loading. We'll just register
- * the SPANS protocol descriptor and wait for a SPANS ATM interface
- * to come online.
- *
- * Arguments:
- * none
- *
- * Returns:
- * 0 startup was successful
- * errno startup failed - reason indicated
- *
- */
-static int
-spans_start()
-{
- int err = 0;
-
- /*
- * Verify software version
- */
- if (atm_version != ATM_VERSION) {
- log(LOG_ERR, "version mismatch: spans=%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);
- }
-
- spans_vc_zone = uma_zcreate("spans vc", sizeof(struct spans_vccb),
- NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
- if (spans_vc_zone == NULL)
- panic("spans_vc_zone");
-
- spans_msg_zone = uma_zcreate("spans msg", sizeof(spans_msg), NULL,
- NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
- if (spans_msg_zone == NULL)
- panic("spans_msg_zone");
-
- /*
- * Allocate protocol definition structure
- */
- spans_mgr = malloc(sizeof(struct sigmgr), M_DEVBUF, M_NOWAIT|M_ZERO);
- if (spans_mgr == NULL) {
- err = ENOMEM;
- goto done;
- }
-
- /*
- * Initialize protocol invariant values
- */
- spans_mgr->sm_proto = ATM_SIG_SPANS;
- spans_mgr->sm_attach = spans_attach;
- spans_mgr->sm_detach = spans_detach;
- spans_mgr->sm_setup = spans_setup;
- spans_mgr->sm_release = spans_release;
- spans_mgr->sm_accept = spans_accept;
- spans_mgr->sm_reject = spans_reject;
- spans_mgr->sm_free = spans_free;
- spans_mgr->sm_ioctl = spans_ioctl;
-
- /*
- * Register ourselves with system
- */
- err = atm_sigmgr_register(spans_mgr);
- if (err)
- goto done;
-
- /*
- * Start the arp service
- */
- spansarp_start();
-
- /*
- * Start up Connectionless Service
- */
- err = spanscls_start();
- if (err)
- goto done;
-
-done:
- return (err);
-}
-
-
-/*
- * Halt SPANS processing
- *
- * This should be called just prior to unloading the module from
- * memory. All SPANS interfaces must be deregistered before the
- * protocol can be shutdown.
- *
- * Arguments:
- * none
- *
- * Returns:
- * 0 startup was successful
- * errno startup failed - reason indicated
- *
- */
-static int
-spans_stop()
-{
- int err = 0;
- int s = splnet();
-
- /*
- * Is protocol even set up?
- */
- if (spans_mgr) {
-
- /*
- * Any protocol instances still registered?
- */
- if (spans_mgr->sm_prinst) {
-
- /* Yes, can't stop now */
- err = EBUSY;
- goto done;
- }
-
- /*
- * Stop Connectionless Service
- */
- spanscls_stop();
-
- /*
- * De-register from system
- */
- err = atm_sigmgr_deregister(spans_mgr);
-
- /*
- * Free up protocol block
- */
- free(spans_mgr, M_DEVBUF);
- spans_mgr = NULL;
-
- /*
- * Free up our storage pools
- */
- uma_zdestroy(spans_vc_zone);
- uma_zdestroy(spans_msg_zone);
- } else
- err = ENXIO;
-
-done:
- (void) splx(s);
- return (err);
-}
-
-
-/*
- * Attach a SPANS-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 SPANS-controlled interfaces. A new SPANS protocol
- * instance will be created and then we'll just sit around waiting for
- * status or connection requests.
- *
- * Function must be called at splnet.
- *
- * Arguments:
- * smp pointer to SPANS signalling manager control block
- * pip pointer to ATM physical interface control block
- *
- * Returns:
- * 0 attach successful
- * errno attach failed - reason indicated
- *
- */
-static int
-spans_attach(smp, pip)
- struct sigmgr *smp;
- struct atm_pif *pip;
-{
- int err = 0, n = 0, s;
- struct spans *spp = NULL;
- struct atm_nif *np;
-
- ATM_DEBUG2("spans_attach: smp=%p, pip=%p\n", smp, pip);
-
- /*
- * Count network interfaces attached to the physical interface.
- * If there are more or less than one, we have big problems.
- */
- np = pip->pif_nif;
- while (np) {
- n++;
- np = np->nif_pnext;
- }
- if (n != 1) {
- err = ETOOMANYREFS;
- goto done;
- }
-
- /*
- * Allocate SPANS protocol instance control block
- */
- spp = malloc(sizeof(struct spans), M_DEVBUF, M_NOWAIT|M_ZERO);
- if (spp == NULL) {
- err = ENOMEM;
- goto done;
- }
-
- /*
- * Set variables in SPANS protocol instance control block
- */
- spp->sp_state = SPANS_INIT;
- spp->sp_h_epoch = time_second;
- spp->sp_s_epoch = 0;
- spp->sp_addr.address_format = T_ATM_ABSENT;
- spp->sp_addr.address_length = 0;
- spp->sp_subaddr.address_format = T_ATM_ABSENT;
- spp->sp_subaddr.address_length = 0;
- spp->sp_probe_ct = 0;
- spp->sp_alloc_vci = SPANS_MIN_VCI;
- spp->sp_alloc_vpi = SPANS_VPI;
- spp->sp_min_vci = SPANS_MIN_VCI;
- spp->sp_max_vci = pip->pif_maxvci;
-
- /*
- * Link instance into manager's chain
- */
- LINK2TAIL((struct siginst *)spp, struct siginst, smp->sm_prinst,
- si_next);
-
- /*
- * Link in interface
- */
- spp->sp_pif = pip;
- pip->pif_sigmgr = smp;
- pip->pif_siginst = (struct siginst *) spp;
-
- /*
- * Kick-start the SPANS protocol
- */
- SPANS_TIMER(spp, 0);
-
- /*
- * Notify Connectionless Service
- */
- err = spanscls_attach(spp);
-
- /*
- * Log the fact that we've attached
- */
- if (!err)
- log(LOG_INFO, "spans: attached to interface %s%d\n",
- pip->pif_name, pip->pif_unit);
-
-done:
- /*
- * Reset our work if attach fails
- */
- if (err) {
- if (spp) {
- SPANS_CANCEL(spp);
- UNLINK((struct siginst *)spp, struct siginst,
- smp->sm_prinst, si_next);
- free(spp, M_DEVBUF);
- }
- s = splimp();
- pip->pif_sigmgr = NULL;
- pip->pif_siginst = NULL;
- (void) splx(s);
- }
-
- return (err);
-}
-
-
-/*
- * Detach a SPANS-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 SPANS-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
-spans_detach(pip)
- struct atm_pif *pip;
-{
- struct spans *spp;
- struct vccb *vcp, *vnext;
- Atm_connection *cop;
- int err;
-
- ATM_DEBUG1("spans_detach: pip=%p\n", pip);
-
- /*
- * Get SPANS protocol instance
- */
- spp = (struct spans *)pip->pif_siginst;
-
- /*
- * Return an error if we're already detaching
- */
- if (spp->sp_state == SPANS_DETACH) {
- return(EALREADY);
- }
-
- /*
- * Cancel any outstanding timer
- */
- SPANS_CANCEL(spp);
-
- /*
- * Notify Connectionless Service
- */
- spanscls_detach(spp);
-
- /*
- * Terminate all of our VCCs
- */
- for (vcp = Q_HEAD(spp->sp_vccq, struct vccb); vcp; vcp = vnext) {
-
- vnext = Q_NEXT(vcp, struct vccb, vc_sigelem);
-
- /*
- * Don't close the signalling VCC yet
- */
- if (vcp->vc_connvc && vcp->vc_connvc->cvc_conn ==
- spp->sp_conn)
- continue;
-
- /*
- * Close VCC and notify owner
- */
- err = spans_clear_vcc(spp, (struct spans_vccb *)vcp);
- if (err) {
- log(LOG_ERR, "spans: error %d clearing VCCB %p\n",
- err, vcp);
- }
- }
-
- /*
- * Now close the SPANS signalling VCC
- */
- if ((cop = spp->sp_conn) != NULL) {
- err = atm_cm_release(cop, &spans_cause);
- if (err)
- ATM_DEBUG2(
- "spans_detach: close failed for SPANS signalling channel; cop=%p, err=%d\n",
- cop, err);
- }
-
-
- /*
- * Get rid of protocol instance if there are no VCCs queued
- */
- if (Q_HEAD(spp->sp_vccq, struct vccb) == NULL) {
- struct sigmgr *smp = pip->pif_sigmgr;
-
- pip->pif_sigmgr = NULL;
- pip->pif_siginst = NULL;
- UNLINK((struct siginst *)spp, struct siginst,
- smp->sm_prinst, si_next);
- free(spp, M_DEVBUF);
- } else {
- /*
- * Otherwise, wait for protocol instance to be freed
- * during spans_free processing for the last queued VCC.
- */
- spp->sp_state = SPANS_DETACH;
- }
-
- /*
- * Log the fact that we've detached
- */
- log(LOG_INFO, "spans: detached from interface %s%d\n",
- pip->pif_name, pip->pif_unit);
-
- return (0);
-}
-
-
-/*
- * Open a SPANS ATM Connection
- *
- * All service user requests to open a VC connection (via
- * atm_open_connection) over an ATM interface attached to the SPANS
- * signalling manager are handled here.
- *
- * Function will be called at splnet.
- *
- * Arguments:
- * cvp pointer to user's requested connection parameters
- * errp pointer to an int for extended error information
- *
- * Returns:
- * CALL_PROCEEDING connection establishment is in progress
- * CALL_FAILED connection establishment failed
- * CALL_CONNECTED connection has been successfully established
- *
- */
-static int
-spans_setup(cvp, errp)
- Atm_connvc *cvp;
- int *errp;
-{
- struct atm_pif *pip = cvp->cvc_attr.nif->nif_pif;
- struct spans *spp = (struct spans *)pip->pif_siginst;
- int rc = 0;
-
- ATM_DEBUG1("spans_setup: cvp=%p\n", cvp);
-
- /*
- * Intialize the returned error code
- */
- *errp = 0;
-
- /*
- * Open the connection
- */
- switch (cvp->cvc_attr.called.addr.address_format) {
- case T_ATM_PVC_ADDR:
- /*
- * Create a PVC
- */
- *errp = spans_open_vcc(spp, cvp);
- rc = (*errp ? CALL_FAILED : CALL_CONNECTED);
- break;
-
- case T_ATM_SPANS_ADDR:
-
- /*
- * Create an SVC
- */
- *errp = spans_open_vcc(spp, cvp);
- rc = (*errp ? CALL_FAILED : CALL_PROCEEDING);
- break;
-
- default:
- *errp = EPROTONOSUPPORT;
- rc = CALL_FAILED;
- }
-
- return (rc);
-}
-
-
-/*
- * Close a SPANS 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 SPANS signalling manager, are
- * handled here.
- *
- * Function will be called at splnet.
- *
- * Arguments:
- * vcp pointer to connection's VC control block
- * errp pointer to an int for extended error information
- *
- * Returns:
- * CALL_PROCEEDING connection termination is in progress
- * CALL_FAILED connection termination failed
- * CALL_CLEARED connection has been successfully terminated
- *
- */
-static int
-spans_release(vcp, errp)
- struct vccb *vcp;
- int *errp;
-{
- int rc = 0;
- struct atm_pif *pip = vcp->vc_pif;
- struct spans *spp = (struct spans *)pip->pif_siginst;
-
- ATM_DEBUG1("spans_release: vcp=%p\n", vcp);
-
- /*
- * Initialize returned error code
- */
- *errp = 0;
-
- /*
- * Make sure VCC is open
- */
- if ((vcp->vc_sstate == SPANS_VC_NULL) ||
- (vcp->vc_sstate == SPANS_VC_CLOSE) ||
- (vcp->vc_sstate == SPANS_VC_FREE) ||
- (vcp->vc_ustate == VCCU_NULL) ||
- (vcp->vc_ustate == VCCU_CLOSED)) {
- *errp = EALREADY;
- return(CALL_FAILED);
- }
-
- /*
- * Validate the connection type (PVC or SVC)
- */
- if (!(vcp->vc_type & (VCC_PVC | VCC_SVC))) {
- *errp = EPROTONOSUPPORT;
- return(CALL_FAILED);
- }
-
- /*
- * Close the VCCB
- */
- *errp = spans_close_vcc(spp, (struct spans_vccb *)vcp, FALSE);
-
- /*
- * Set the return code
- */
- if (vcp->vc_type & VCC_PVC) {
- rc = (*errp ? CALL_FAILED : CALL_CLEARED);
- } else {
- rc = (*errp ? CALL_FAILED : CALL_PROCEEDING);
- }
-
- return (rc);
-}
-
-
-/*
- * Accept a SPANS Open from a remote host
- *
- * A user calls this routine (via the atm_accept_call function)
- * after it is notified that an open request was received for it.
- *
- * Function will be called at splnet.
- *
- * Arguments:
- * vcp pointer to user's VCCB
- * errp pointer to an int for extended error information
- *
- * Returns:
- * CALL_PROCEEDING connection establishment is in progress
- * CALL_FAILED connection establishment failed
- * CALL_CONNECTED connection has been successfully established
- *
- */
-static int
-spans_accept(vcp, errp)
- struct vccb *vcp;
- int *errp;
-{
- struct atm_pif *pip = vcp->vc_pif;
- struct spans *spp = (struct spans *)pip->pif_siginst;
- struct spans_vccb *svp = (struct spans_vccb *)vcp;
-
- ATM_DEBUG1("spans_accept: vcp=%p\n", vcp);
-
- /*
- * Initialize the returned error code
- */
- *errp = 0;
-
- /*
- * Return an error if we're detaching
- */
- if (spp->sp_state == SPANS_DETACH) {
- *errp = ENETDOWN;
- ATM_DEBUG0("spans_accept: detaching\n");
- return(CALL_FAILED);
- }
-
- /*
- * Respond to the open request
- */
- *errp = spans_send_open_rsp(spp, svp, SPANS_OK);
- if (*errp) {
- ATM_DEBUG0("spans_accept: spans_send_open_rsp failed\n");
- goto failed;
- }
-
- /*
- * Update the VCC states
- */
- svp->sv_sstate = SPANS_VC_OPEN;
- svp->sv_ustate = VCCU_OPEN;
-
- return(CALL_CONNECTED);
-
-failed:
- /*
- * On error, free the VCCB and return CALL_FAILED
- */
- svp->sv_sstate = SPANS_VC_FREE;
- svp->sv_ustate = VCCU_CLOSED;
- DEQUEUE(svp, struct spans_vccb, sv_sigelem, spp->sp_vccq);
- spans_free((struct vccb *)svp);
-
- return(CALL_FAILED);
-}
-
-
-/*
- * Reject a SPANS Open from a remote host
- *
- * A user calls this routine (via the atm_reject_call function)
- * after it is notified that an open request was received for it.
- *
- * Function will be called at splnet.
- *
- * Arguments:
- * vcp pointer to user's VCCB
- * errp pointer to an int for extended error information
- *
- * Returns:
- * CALL_CLEARED call request rejected
- * CALL_FAILED call rejection failed
- *
- */
-static int
-spans_reject(vcp, errp)
- struct vccb *vcp;
- int *errp;
-{
- struct atm_pif *pip = vcp->vc_pif;
- struct spans *spp = (struct spans *)pip->pif_siginst;
- struct spans_vccb *svp = (struct spans_vccb *)vcp;
-
- ATM_DEBUG1("spans_reject: vcp=%p\n", vcp);
-
- /*
- * Initialize the returned error code
- */
- *errp = 0;
-
- /*
- * Return an error if we're detaching
- */
- if (spp->sp_state == SPANS_DETACH) {
- *errp = ENETDOWN;
- ATM_DEBUG0("spans_reject: detaching\n");
- return(CALL_FAILED);
- }
-
- ATM_DEBUG1("spans_reject: cause code is %d\n",
- vcp->vc_connvc->cvc_attr.cause.v.cause_value);
-
- /*
- * Clean up the VCCB--the connection manager will free it
- * spans_close_vcc will send a SPANS open response
- */
- if ((*errp = spans_close_vcc(spp, svp, TRUE)) != 0) {
- ATM_DEBUG0("spans_reject: spans_close_vcc failed\n");
- return(CALL_FAILED);
- }
-
- return(CALL_CLEARED);
-}
-
-
-/*
- * Abort a SPANS ATM Connection
- *
- * All (non-user) requests to abort a previously open VC connection (via
- * the atm_abort_connection function), which is running over an
- * interface attached to the SPANS signalling manager, are handled here.
- * The VCC owner will be notified of the request, in order to initiate
- * termination of the connection.
- *
- * Function will be called at splnet.
- *
- * Arguments:
- * vcp pointer to connection's VC control block
- *
- * Returns:
- * 0 connection release was succesful
- * errno connection release failed - reason indicated
- *
- */
-int
-spans_abort(vcp)
- struct vccb *vcp;
-{
-
- /*
- * Make sure VCC is available
- */
- if ((vcp->vc_sstate == SPANS_VC_NULL) ||
- (vcp->vc_sstate == SPANS_VC_CLOSE) ||
- (vcp->vc_sstate == SPANS_VC_FREE) ||
- (vcp->vc_ustate == VCCU_NULL) ||
- (vcp->vc_ustate == VCCU_CLOSED)) {
- return(EALREADY);
- }
-
- /*
- * Only abort once
- */
- if (vcp->vc_sstate == SPANS_VC_ABORT) {
- return (EALREADY);
- }
-
- /*
- * Cancel any timer that might be running
- */
- SPANS_VC_CANCEL(vcp);
-
- /*
- * Set immediate timer to schedule connection termination
- */
- vcp->vc_sstate = SPANS_VC_ABORT;
- SPANS_VC_TIMER(vcp, 0);
-
- return (0);
-}
-
-
-/*
- * Free SPANS 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 VC control block
- *
- * Returns:
- * 0 connection free was successful
- * errno connection free failed - reason indicated
- *
- */
-int
-spans_free(vcp)
- struct vccb *vcp;
-{
- struct atm_pif *pip = vcp->vc_pif;
- struct spans *spp = (struct spans *)pip->pif_siginst;
-
- ATM_DEBUG1("spans_free: vcp = %p\n", vcp);
-
- /*
- * Make sure VCC has been closed
- */
- if ((vcp->vc_ustate != VCCU_CLOSED) ||
- (vcp->vc_sstate != SPANS_VC_FREE)) {
- ATM_DEBUG2("spans_free: bad state, sstate=%d, ustate=%d\n",
- vcp->vc_sstate, vcp->vc_ustate);
- return(EEXIST);
- }
-
- /*
- * Remove VCCB from protocol queue
- */
- DEQUEUE(vcp, struct vccb, vc_sigelem, spp->sp_vccq);
-
- /*
- * Free VCCB storage
- */
- vcp->vc_ustate = VCCU_NULL;
- vcp->vc_sstate = SPANS_VC_NULL;
- uma_zfree(spans_vc_zone, vcp);
-
- /*
- * If we're detaching and this was the last VCC queued,
- * get rid of the protocol instance
- */
- if ((spp->sp_state == SPANS_DETACH) &&
- (Q_HEAD(spp->sp_vccq, struct vccb) == NULL)) {
- struct sigmgr *smp = pip->pif_sigmgr;
-
- pip->pif_sigmgr = NULL;
- pip->pif_siginst = NULL;
- UNLINK((struct siginst *)spp, struct siginst, smp->sm_prinst,
- si_next);
- free(spp, M_DEVBUF);
- }
-
- return (0);
-}
-
-
-/*
- * SPANS IOCTL support
- *
- * 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
-spans_ioctl(code, data, arg1)
- int code;
- caddr_t data;
- caddr_t arg1;
-{
- struct atmdelreq *adp;
- struct atminfreq *aip;
- struct spans *spp;
- struct spans_vccb *svp;
- struct air_vcc_rsp rsp;
- Atm_connection *cop;
- int err = 0, i, vpi, vci;
- size_t buf_len;
- caddr_t buf_addr;
-
-
- switch (code) {
-
- case AIOCS_DEL_PVC:
- case AIOCS_DEL_SVC:
- /*
- * Delete a VCC
- */
- adp = (struct atmdelreq *)data;
- spp = (struct spans *)arg1;
-
- /*
- * Don't let a user close the SPANS signalling VC or
- * the SPANS CLS VC
- */
- vpi = adp->adr_pvc_vpi;
- vci = adp->adr_pvc_vci;
- if ((vpi == SPANS_SIG_VPI && vci == SPANS_SIG_VCI) ||
- (vpi == SPANS_CLS_VPI &&
- vci == SPANS_CLS_VCI))
- return(EINVAL);
-
- /*
- * Find requested VCC
- */
- for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp;
- svp = Q_NEXT(svp, struct spans_vccb, sv_sigelem)) {
- if ((svp->sv_vpi == vpi) && (svp->sv_vci == vci))
- break;
- }
- if (svp == NULL)
- return (ENOENT);
-
- /*
- * Check VCC type
- */
- switch (code) {
- case AIOCS_DEL_PVC:
- if (!(svp->sv_type & VCC_PVC)) {
- return(EINVAL);
- }
- break;
- case AIOCS_DEL_SVC:
- if (!(svp->sv_type & VCC_SVC)) {
- return(EINVAL);
- }
- break;
- }
-
- /*
- * Schedule VCC termination
- */
- err = spans_abort((struct vccb *)svp);
- break;
-
- case AIOCS_INF_VCC:
- /*
- * Return VCC information
- */
- aip = (struct atminfreq *)data;
- spp = (struct spans *)arg1;
-
- buf_addr = aip->air_buf_addr;
- buf_len = aip->air_buf_len;
-
- /*
- * Loop through the VCC queue
- */
- for (svp = Q_HEAD(spp->sp_vccq, struct spans_vccb); svp;
- svp = Q_NEXT(svp, struct spans_vccb, sv_sigelem)) {
- /*
- * Make sure there's room in the user's buffer
- */
- if (buf_len < sizeof(rsp)) {
- err = ENOSPC;
- break;
- }
-
- /*
- * Fill out the response struct for the VCC
- */
- (void) snprintf(rsp.avp_intf,
- sizeof(rsp.avp_intf), "%s%d",
- spp->sp_pif->pif_name,
- spp->sp_pif->pif_unit);
- rsp.avp_vpi = svp->sv_vpi;
- rsp.avp_vci = svp->sv_vci;
- rsp.avp_type = svp->sv_type;
- rsp.avp_aal = svp->sv_connvc->cvc_attr.aal.type;
- rsp.avp_sig_proto = svp->sv_proto;
- cop = svp->sv_connvc->cvc_conn;
- if (cop)
- rsp.avp_encaps = cop->co_mpx;
- else
- rsp.avp_encaps = 0;
- rsp.avp_state = svp->sv_sstate;
- bzero(rsp.avp_owners, sizeof(rsp.avp_owners));
- for (i = 0; cop && i < sizeof(rsp.avp_owners);
- cop = cop->co_next,
- i += T_ATM_APP_NAME_LEN+1) {
- strncpy(&rsp.avp_owners[i],
- cop->co_endpt->ep_getname(cop->co_toku),
- T_ATM_APP_NAME_LEN);
- }
- rsp.avp_daddr.address_format = T_ATM_SPANS_ADDR;
- rsp.avp_daddr.address_length =
- sizeof(Atm_addr_spans);
- if (svp->sv_type & VCC_OUT) {
- spans_addr_copy(&svp->sv_conn.con_dst,
- rsp.avp_daddr.address);
- } else {
- spans_addr_copy(&svp->sv_conn.con_src,
- rsp.avp_daddr.address);
- }
- rsp.avp_dsubaddr.address_format = T_ATM_ABSENT;
- rsp.avp_dsubaddr.address_length = 0;
- rsp.avp_ipdus = svp->sv_ipdus;
- rsp.avp_opdus = svp->sv_opdus;
- rsp.avp_ibytes = svp->sv_ibytes;
- rsp.avp_obytes = svp->sv_obytes;
- rsp.avp_ierrors = svp->sv_ierrors;
- rsp.avp_oerrors = svp->sv_oerrors;
- rsp.avp_tstamp = svp->sv_tstamp;
-
- /*
- * Copy the response into the user's buffer
- */
- if ((err = copyout((caddr_t)&rsp, buf_addr,
- sizeof(rsp))) != 0)
- break;
- buf_addr += sizeof(rsp);
- buf_len -= sizeof(rsp);
- }
-
- /*
- * Update the buffer pointer and length
- */
- aip->air_buf_addr = buf_addr;
- aip->air_buf_len = buf_len;
- break;
-
- case AIOCS_ADD_ARP:
- case AIOCS_DEL_ARP:
- case AIOCS_INF_ARP:
- case AIOCS_INF_ASV:
- /*
- * ARP specific ioctl's
- */
- err = spansarp_ioctl(code, data, arg1);
- break;
-
- default:
- err = EOPNOTSUPP;
- }
-
- return (err);
-}
-
-
-#ifdef ATM_SPANS_MODULE
-/*
- *******************************************************************
- *
- * Loadable Module Support
- *
- *******************************************************************
- */
-static int spans_doload(void);
-static int spans_dounload(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
-spans_doload()
-{
- int err = 0;
-
- /*
- * Start us up
- */
- err = spans_start();
- if (err)
- /* Problems, clean up */
- (void)spans_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
-spans_dounload()
-{
- int err = 0;
-
- /*
- * OK, try to clean up our mess
- */
- err = spans_stop();
-
- return (err);
-}
-
-
-
-
-#include <sys/exec.h>
-#include <sys/sysent.h>
-#include <sys/lkm.h>
-
-/*
- * Loadable miscellaneous module description
- */
-MOD_MISC(spans);
-
-
-/*
- * 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
-spans_load(lkmtp, cmd)
- struct lkm_table *lkmtp;
- int cmd;
-{
- return(spans_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
-spans_unload(lkmtp, cmd)
- struct lkm_table *lkmtp;
- int cmd;
-{
- return(spans_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
-spans_mod(lkmtp, cmd, ver)
- struct lkm_table *lkmtp;
- int cmd;
- int ver;
-{
- MOD_DISPATCH(spans, lkmtp, cmd, ver,
- spans_load, spans_unload, lkm_nullcmd);
-}
-
-#else /* !ATM_SPANS_MODULE */
-
-/*
- *******************************************************************
- *
- * Kernel Compiled Module Support
- *
- *******************************************************************
- */
-static void spans_doload(void *);
-
-SYSINIT(atmspans, SI_SUB_PROTO_END, SI_ORDER_ANY, spans_doload, NULL);
-
-/*
- * Kernel initialization
- *
- * Arguments:
- * arg Not used
- *
- * Returns:
- * none
- *
- */
-static void
-spans_doload(void *arg)
-{
- int err = 0;
-
- /*
- * Start us up
- */
- err = spans_start();
- if (err) {
- /* Problems, clean up */
- (void)spans_stop();
-
- log(LOG_ERR, "ATM SPANS unable to initialize (%d)!!\n", err);
- }
- return;
-}
-#endif /* ATM_SPANS_MODULE */
-
OpenPOWER on IntegriCloud