summaryrefslogtreecommitdiffstats
path: root/sys/netatm/uni/uniarp.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/uni/uniarp.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/uni/uniarp.c')
-rw-r--r--sys/netatm/uni/uniarp.c1261
1 files changed, 0 insertions, 1261 deletions
diff --git a/sys/netatm/uni/uniarp.c b/sys/netatm/uni/uniarp.c
deleted file mode 100644
index a10cf55..0000000
--- a/sys/netatm/uni/uniarp.c
+++ /dev/null
@@ -1,1261 +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.
- */
-
-/*
- * ATM Forum UNI Support
- * ---------------------
- *
- * UNI ATMARP support (RFC1577)
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/errno.h>
-#include <sys/malloc.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/syslog.h>
-#include <sys/kernel.h>
-#include <sys/sysctl.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/in_var.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 <netatm/ipatm/ipatm_var.h>
-#include <netatm/ipatm/ipatm_serv.h>
-#include <netatm/uni/unisig_var.h>
-#include <netatm/uni/uniip_var.h>
-
-#include <vm/uma.h>
-
-/*
- * Global variables
- */
-struct uniarp *uniarp_arptab[UNIARP_HASHSIZ] = {NULL};
-struct uniarp *uniarp_nomaptab = NULL;
-struct uniarp *uniarp_pvctab = NULL;
-struct atm_time uniarp_timer = {0, 0}; /* Aging timer */
-struct uniarp_stat uniarp_stat = {0};
-
-/*
- * net.harp.uni.uniarp_print
- */
-int uniarp_print = 0;
-SYSCTL_INT(_net_harp_uni, OID_AUTO, uniarp_print, CTLFLAG_RW,
- &uniarp_print, 0, "dump UNI/ARP messages");
-
-Atm_endpoint uniarp_endpt = {
- NULL,
- ENDPT_ATMARP,
- uniarp_ioctl,
- uniarp_getname,
- uniarp_connected,
- uniarp_cleared,
- NULL,
- NULL,
- NULL,
- NULL,
- uniarp_cpcs_data,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-uma_zone_t uniarp_zone;
-
-
-/*
- * Local variables
- */
-static void uniarp_server_mode(struct uniip *);
-static void uniarp_client_mode(struct uniip *, Atm_addr *);
-
-
-/*
- * Process module loading notification
- *
- * Called whenever the uni module is initializing.
- *
- * Arguments:
- * none
- *
- * Returns:
- * 0 initialization successful
- * errno initialization failed - reason indicated
- *
- */
-int
-uniarp_start()
-{
- int err;
-
- uniarp_zone = uma_zcreate("uni arp", sizeof(struct uniarp), NULL, NULL,
- NULL, NULL, UMA_ALIGN_PTR, 0);
- if (uniarp_zone == NULL)
- panic("uniarp_start: uma_zcreate");
-
- /*
- * Register our endpoint
- */
- err = atm_endpoint_register(&uniarp_endpt);
- return (err);
-}
-
-
-/*
- * Process module unloading notification
- *
- * Called whenever the uni module is about to be unloaded. All signalling
- * instances will have been previously detached. All uniarp resources
- * must be freed now.
- *
- * Arguments:
- * none
- *
- * Returns:
- * none
- *
- */
-void
-uniarp_stop()
-{
- int i;
-
- /*
- * Make sure the arp table is empty
- */
- for (i = 0; i < UNIARP_HASHSIZ; i++) {
- if (uniarp_arptab[i] != NULL)
- panic("uniarp_stop: arp table not empty");
- }
-
- /*
- * Cancel timers
- */
- (void) atm_untimeout(&uniarp_timer);
-
- /*
- * De-register ourselves
- */
- (void) atm_endpoint_deregister(&uniarp_endpt);
-
- /*
- * Free our storage pools
- */
- uma_zdestroy(uniarp_zone);
-}
-
-
-/*
- * Process IP Network Interface Activation
- *
- * Called whenever an IP network interface becomes active.
- *
- * Called at splnet.
- *
- * Arguments:
- * uip pointer to UNI IP interface
- *
- * Returns:
- * none
- *
- */
-void
-uniarp_ipact(uip)
- struct uniip *uip;
-{
- struct unisig *usp;
-
- ATM_DEBUG1("uniarp_ipact: uip=%p\n", uip);
-
- /*
- * Set initial state
- */
- uip->uip_arpstate = UIAS_NOTCONF;
- uip->uip_arpsvratm.address_format = T_ATM_ABSENT;
- uip->uip_arpsvratm.address_length = 0;
- uip->uip_arpsvrsub.address_format = T_ATM_ABSENT;
- uip->uip_arpsvrsub.address_length = 0;
-
- usp = (struct unisig *)uip->uip_ipnif->inf_nif->nif_pif->pif_siginst;
- if (usp->us_addr.address_format != T_ATM_ABSENT)
- uip->uip_flags |= UIF_IFADDR;
-
- /*
- * Make sure aging timer is running
- */
- if ((uniarp_timer.ti_flag & TIF_QUEUED) == 0)
- atm_timeout(&uniarp_timer, UNIARP_AGING, uniarp_aging);
-
- return;
-}
-
-
-/*
- * Process IP Network Interface Deactivation
- *
- * Called whenever an IP network interface becomes inactive. All VCCs
- * for this interface should already have been closed.
- *
- * Called at splnet.
- *
- * Arguments:
- * uip pointer to UNI IP interface
- *
- * Returns:
- * none
- *
- */
-void
-uniarp_ipdact(uip)
- struct uniip *uip;
-{
- struct uniarp *uap, *unext;
- int i;
-
- ATM_DEBUG1("uniarp_ipdact: uip=%p\n", uip);
-
- /*
- * Delete all interface entries
- */
- for (i = 0; i < UNIARP_HASHSIZ; i++) {
- for (uap = uniarp_arptab[i]; uap; uap = unext) {
- unext = uap->ua_next;
-
- if (uap->ua_intf != uip)
- continue;
-
- /*
- * All VCCs should (better) be gone by now
- */
- if (uap->ua_ivp)
- panic("uniarp_ipdact: entry not empty");
-
- /*
- * Clean up any loose ends
- */
- UNIARP_CANCEL(uap);
-
- /*
- * Delete entry from arp table and free entry
- */
- UNIARP_DELETE(uap);
- uma_zfree(uniarp_zone, uap);
- }
- }
-
- /*
- * Clean up 'nomap' table
- */
- for (uap = uniarp_nomaptab; uap; uap = unext) {
- unext = uap->ua_next;
-
- if (uap->ua_intf != uip)
- continue;
-
- /*
- * All VCCs should (better) be gone by now
- */
- if (uap->ua_ivp)
- panic("uniarp_ipdact: entry not empty");
-
- /*
- * Clean up any loose ends
- */
- UNIARP_CANCEL(uap);
-
- /*
- * Delete entry from 'no map' table and free entry
- */
- UNLINK(uap, struct uniarp, uniarp_nomaptab, ua_next);
- uma_zfree(uniarp_zone, uap);
- }
-
- /*
- * Also clean up pvc table
- */
- for (uap = uniarp_pvctab; uap; uap = unext) {
- unext = uap->ua_next;
-
- if (uap->ua_intf != uip)
- continue;
-
- /*
- * All PVCs should (better) be gone by now
- */
- panic("uniarp_ipdact: pvc table not empty");
- }
-
- /*
- * Cancel arp interface timer
- */
- UNIIP_ARP_CANCEL(uip);
-
- /*
- * Stop aging timer if this is the last active interface
- */
- if (uniip_head == uip && uip->uip_next == NULL)
- (void) atm_untimeout(&uniarp_timer);
-}
-
-
-/*
- * Process Interface ATM Address Change
- *
- * This function is called whenever the ATM address for a physical
- * interface is set/changed.
- *
- * Called at splnet.
- *
- * Arguments:
- * sip pointer to interface's UNI signalling instance
- *
- * Returns:
- * none
- *
- */
-void
-uniarp_ifaddr(sip)
- struct siginst *sip;
-{
- struct atm_nif *nip;
- struct uniip *uip;
-
- ATM_DEBUG1("uniarp_ifaddr: sip=%p\n", sip);
-
- /*
- * We've got to handle this for every network interface
- */
- for (nip = sip->si_pif->pif_nif; nip; nip = nip->nif_pnext) {
-
- /*
- * Find our control blocks
- */
- for (uip = uniip_head; uip; uip = uip->uip_next) {
- if (uip->uip_ipnif->inf_nif == nip)
- break;
- }
- if (uip == NULL)
- continue;
-
- /*
- * We don't support changing prefix (yet)
- */
- if (uip->uip_flags & UIF_IFADDR) {
- log(LOG_ERR, "uniarp_ifaddr: change not supported\n");
- continue;
- }
-
- /*
- * Note that address has been set and figure out what
- * to do next
- */
- uip->uip_flags |= UIF_IFADDR;
-
- if (uip->uip_arpstate == UIAS_CLIENT_PADDR) {
- /*
- * This is what we're waiting for
- */
- uniarp_client_mode(uip, NULL);
- } else if (uip->uip_arpstate == UIAS_SERVER_ACTIVE) {
- /*
- * Set new local arpserver atm address
- */
- ATM_ADDR_SEL_COPY(&sip->si_addr, nip->nif_sel,
- &uip->uip_arpsvratm);
- }
- }
-
- return;
-}
-
-
-/*
- * Set ATMARP Server Mode
- *
- * This function is called to configure the local node to become the
- * ATMARP server for the specified LIS.
- *
- * Called at splnet.
- *
- * Arguments:
- * uip pointer to UNI IP interface
- *
- * Returns:
- * none
- *
- */
-static void
-uniarp_server_mode(uip)
- struct uniip *uip;
-{
- struct ip_nif *inp;
- struct atm_nif *nip;
- struct siginst *sgp;
- struct ipvcc *ivp, *inext;
- struct uniarp *uap, *unext;
- int i;
-
- ATM_DEBUG1("uniarp_server_mode: uip=%p\n", uip);
-
- /*
- * Handle client/server mode changes first
- */
- switch (uip->uip_arpstate) {
-
- case UIAS_NOTCONF:
- case UIAS_SERVER_ACTIVE:
- case UIAS_CLIENT_PADDR:
- /*
- * Nothing to undo
- */
- break;
-
- case UIAS_CLIENT_POPEN:
- /*
- * We're becoming the server, so kill the pending connection
- */
- UNIIP_ARP_CANCEL(uip);
- if ((ivp = uip->uip_arpsvrvcc) != NULL) {
- ivp->iv_flags &= ~IVF_NOIDLE;
- uip->uip_arpsvrvcc = NULL;
- (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
- }
- break;
-
- case UIAS_CLIENT_REGISTER:
- case UIAS_CLIENT_ACTIVE:
- /*
- * We're becoming the server, but leave existing VCC as a
- * "normal" IP VCC
- */
- UNIIP_ARP_CANCEL(uip);
- ivp = uip->uip_arpsvrvcc;
- ivp->iv_flags &= ~IVF_NOIDLE;
- uip->uip_arpsvrvcc = NULL;
- break;
- }
-
- /*
- * Revalidate status for all arp entries on this interface
- */
- for (i = 0; i < UNIARP_HASHSIZ; i++) {
- for (uap = uniarp_arptab[i]; uap; uap = unext) {
- unext = uap->ua_next;
-
- if (uap->ua_intf != uip)
- continue;
-
- if (uap->ua_origin >= UAO_PERM)
- continue;
-
- if (uap->ua_origin >= UAO_SCSP) {
- if (uniarp_validate_ip(uip, &uap->ua_dstip,
- uap->ua_origin) == 0)
- continue;
- }
-
- if (uap->ua_ivp == NULL) {
- UNIARP_CANCEL(uap);
- UNIARP_DELETE(uap);
- uma_zfree(uniarp_zone, uap);
- continue;
- }
-
- if (uap->ua_flags & UAF_VALID) {
- uap->ua_flags |= UAF_LOCKED;
- for (ivp = uap->ua_ivp; ivp; ivp = inext) {
- inext = ivp->iv_arpnext;
- (*ivp->iv_ipnif->inf_arpnotify)
- (ivp, MAP_INVALID);
- }
- uap->ua_flags &= ~(UAF_LOCKED | UAF_VALID);
- }
- uap->ua_aging = 1;
- uap->ua_origin = 0;
- }
- }
-
- /*
- * OK, now let's make ourselves the server
- */
- inp = uip->uip_ipnif;
- nip = inp->inf_nif;
- sgp = nip->nif_pif->pif_siginst;
- ATM_ADDR_SEL_COPY(&sgp->si_addr, nip->nif_sel, &uip->uip_arpsvratm);
- uip->uip_arpsvrip = IA_SIN(inp->inf_addr)->sin_addr;
- uip->uip_arpstate = UIAS_SERVER_ACTIVE;
- return;
-}
-
-
-/*
- * Set ATMARP Client Mode
- *
- * This function is called to configure the local node to be an ATMARP
- * client on the specified LIS using the specified ATMARP server.
- *
- * Called at splnet.
- *
- * Arguments:
- * uip pointer to UNI IP interface
- * aap pointer to the ATMARP server's ATM address
- *
- * Returns:
- * none
- *
- */
-static void
-uniarp_client_mode(uip, aap)
- struct uniip *uip;
- Atm_addr *aap;
-{
- struct ip_nif *inp = uip->uip_ipnif;
- struct uniarp *uap, *unext;
- struct ipvcc *ivp, *inext;
- int i;
-
- ATM_DEBUG2("uniarp_client_mode: uip=%p, atm=(%s,-)\n",
- uip, aap ? unisig_addr_print(aap): "-");
-
- /*
- * Handle client/server mode changes first
- */
- switch (uip->uip_arpstate) {
-
- case UIAS_NOTCONF:
- case UIAS_CLIENT_PADDR:
- /*
- * Nothing to undo
- */
- break;
-
- case UIAS_CLIENT_POPEN:
- /*
- * If this is this a timeout retry, just go do it
- */
- if (aap == NULL)
- break;
-
- /*
- * If this isn't really a different arpserver, we're done
- */
- if (ATM_ADDR_EQUAL(aap, &uip->uip_arpsvratm))
- return;
-
- /*
- * We're changing servers, so kill the pending connection
- */
- UNIIP_ARP_CANCEL(uip);
- if ((ivp = uip->uip_arpsvrvcc) != NULL) {
- ivp->iv_flags &= ~IVF_NOIDLE;
- uip->uip_arpsvrvcc = NULL;
- (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
- }
- break;
-
- case UIAS_CLIENT_REGISTER:
- case UIAS_CLIENT_ACTIVE:
- /*
- * If this isn't really a different arpserver, we're done
- */
- if (ATM_ADDR_EQUAL(aap, &uip->uip_arpsvratm))
- return;
-
- /*
- * We're changing servers, but leave existing VCC as a
- * "normal" IP VCC
- */
- UNIIP_ARP_CANCEL(uip);
- ivp = uip->uip_arpsvrvcc;
- ivp->iv_flags &= ~IVF_NOIDLE;
- uip->uip_arpsvrvcc = NULL;
- break;
-
- case UIAS_SERVER_ACTIVE:
- /*
- * We're changing from server mode, so...
- *
- * Reset valid/authoritative status for all arp entries
- * on this interface
- */
- for (i = 0; i < UNIARP_HASHSIZ; i++) {
- for (uap = uniarp_arptab[i]; uap; uap = unext) {
- unext = uap->ua_next;
-
- if (uap->ua_intf != uip)
- continue;
-
- if (uap->ua_origin >= UAO_PERM)
- continue;
-
- if (uap->ua_ivp == NULL) {
- UNIARP_CANCEL(uap);
- UNIARP_DELETE(uap);
- uma_zfree(uniarp_zone, uap);
- continue;
- }
-
- if (uap->ua_flags & UAF_VALID) {
- uap->ua_flags |= UAF_LOCKED;
- for (ivp = uap->ua_ivp; ivp;
- ivp = inext) {
- inext = ivp->iv_arpnext;
- (*ivp->iv_ipnif->inf_arpnotify)
- (ivp, MAP_INVALID);
- }
- uap->ua_flags &=
- ~(UAF_LOCKED | UAF_VALID);
- }
- uap->ua_aging = 1;
- uap->ua_origin = 0;
- }
- }
- uip->uip_arpsvratm.address_format = T_ATM_ABSENT;
- uip->uip_arpsvratm.address_length = 0;
- uip->uip_arpsvrsub.address_format = T_ATM_ABSENT;
- uip->uip_arpsvrsub.address_length = 0;
- uip->uip_arpsvrip.s_addr = 0;
- break;
- }
-
- /*
- * Save the arp server address, if supplied now
- */
- if (aap)
- ATM_ADDR_COPY(aap, &uip->uip_arpsvratm);
-
- /*
- * If the interface's ATM address isn't set yet, then we
- * can't do much until it is
- */
- if ((uip->uip_flags & UIF_IFADDR) == 0) {
- uip->uip_arpstate = UIAS_CLIENT_PADDR;
- return;
- }
-
- /*
- * Just to keep things simple, if we already have (or are trying to
- * setup) any SVCs to our new server, kill the connections so we can
- * open a "fresh" SVC for the arpserver connection.
- */
- for (i = 0; i < UNIARP_HASHSIZ; i++) {
- for (uap = uniarp_arptab[i]; uap; uap = unext) {
- unext = uap->ua_next;
-
- if (ATM_ADDR_EQUAL(&uip->uip_arpsvratm,
- &uap->ua_dstatm) &&
- ATM_ADDR_EQUAL(&uip->uip_arpsvrsub,
- &uap->ua_dstatmsub)) {
- uap->ua_flags &= ~UAF_VALID;
- for (ivp = uap->ua_ivp; ivp; ivp = inext) {
- inext = ivp->iv_arpnext;
- (*inp->inf_arpnotify)(ivp, MAP_FAILED);
- }
- }
- }
- }
- for (uap = uniarp_nomaptab; uap; uap = unext) {
- unext = uap->ua_next;
-
- if (ATM_ADDR_EQUAL(&uip->uip_arpsvratm, &uap->ua_dstatm) &&
- ATM_ADDR_EQUAL(&uip->uip_arpsvrsub, &uap->ua_dstatmsub)) {
- uap->ua_flags &= ~UAF_VALID;
- for (ivp = uap->ua_ivp; ivp; ivp = inext) {
- inext = ivp->iv_arpnext;
- (*inp->inf_arpnotify)(ivp, MAP_FAILED);
- }
- }
- }
-
- /*
- * Now, get an arp entry for the server connection
- * May be called from timeout - don't wait.
- */
- uip->uip_arpstate = UIAS_CLIENT_POPEN;
- uap = uma_zalloc(uniarp_zone, M_NOWAIT | M_ZERO);
- if (uap == NULL) {
- UNIIP_ARP_TIMER(uip, 1 * ATM_HZ);
- return;
- }
-
- /*
- * Next, initiate an SVC to the server
- */
- if ((*inp->inf_createsvc)(ANIF2IFP(inp->inf_nif), AF_ATM,
- (caddr_t)&uip->uip_arpsvratm, &ivp)) {
- uma_zfree(uniarp_zone, uap);
- UNIIP_ARP_TIMER(uip, 1 * ATM_HZ);
- return;
- }
-
- /*
- * Finally, get everything set up and wait for the SVC
- * connection to complete
- */
- uip->uip_arpsvrvcc = ivp;
- ivp->iv_flags |= IVF_NOIDLE;
-
- ATM_ADDR_COPY(&uip->uip_arpsvratm, &uap->ua_dstatm);
- ATM_ADDR_COPY(&uip->uip_arpsvrsub, &uap->ua_dstatmsub);
- uap->ua_intf = uip;
-
- LINK2TAIL(ivp, struct ipvcc, uap->ua_ivp, iv_arpnext);
- ivp->iv_arpent = (struct arpmap *)uap;
-
- LINK2TAIL(uap, struct uniarp, uniarp_nomaptab, ua_next);
-
- return;
-}
-
-
-/*
- * Process a UNI ARP interface timeout
- *
- * Called when a previously scheduled uniip arp interface timer expires.
- * Processing will be based on the current uniip arp state.
- *
- * Called at splnet.
- *
- * Arguments:
- * tip pointer to uniip arp timer control block
- *
- * Returns:
- * none
- *
- */
-void
-uniarp_iftimeout(tip)
- struct atm_time *tip;
-{
- struct ip_nif *inp;
- struct uniip *uip;
-
-
- /*
- * Back-off to uniip control block
- */
- uip = (struct uniip *)
- ((caddr_t)tip - offsetof(struct uniip, uip_arptime));
-
- ATM_DEBUG2("uniarp_iftimeout: uip=%p, state=%d\n", uip,
- uip->uip_arpstate);
-
- /*
- * Process timeout based on protocol state
- */
- switch (uip->uip_arpstate) {
-
- case UIAS_CLIENT_POPEN:
- /*
- * Retry opening arp server connection
- */
- uniarp_client_mode(uip, NULL);
- break;
-
- case UIAS_CLIENT_REGISTER:
- /*
- * Resend registration request
- */
- inp = uip->uip_ipnif;
- (void) uniarp_arp_req(uip, &(IA_SIN(inp->inf_addr)->sin_addr));
-
- /*
- * Restart timer
- */
- UNIIP_ARP_TIMER(uip, 2 * ATM_HZ);
-
- break;
-
- case UIAS_CLIENT_ACTIVE:
- /*
- * Refresh our registration
- */
- inp = uip->uip_ipnif;
- (void) uniarp_arp_req(uip, &(IA_SIN(inp->inf_addr)->sin_addr));
-
- /*
- * Restart timer
- */
- UNIIP_ARP_TIMER(uip, UNIARP_REGIS_RETRY);
-
- break;
-
- default:
- log(LOG_ERR, "uniarp_iftimeout: invalid state %d\n",
- uip->uip_arpstate);
- }
-}
-
-
-/*
- * UNI ARP 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
- *
- */
-int
-uniarp_ioctl(code, data, arg1)
- int code;
- caddr_t data;
- caddr_t arg1;
-{
- struct atmaddreq *aap;
- struct atmdelreq *adp;
- struct atmsetreq *asp;
- struct atminfreq *aip;
- struct air_arp_rsp aar;
- struct air_asrv_rsp asr;
- struct atm_pif *pip;
- struct atm_nif *nip;
- struct ipvcc *ivp, *inext;
- struct uniip *uip;
- struct uniarp *uap;
- struct unisig *usp;
- struct in_addr ip;
- Atm_addr atmsub;
- u_long dst;
- int err = 0;
- size_t buf_len, tlen;
- u_int i;
- caddr_t buf_addr;
-
- switch (code) {
-
- case AIOCS_ADD_ARP:
- /*
- * Add a permanent ARP mapping
- */
- aap = (struct atmaddreq *)data;
- uip = (struct uniip *)arg1;
- if (aap->aar_arp_addr.address_format != T_ATM_ENDSYS_ADDR) {
- err = EINVAL;
- break;
- }
- atmsub.address_format = T_ATM_ABSENT;
- atmsub.address_length = 0;
- ip = SATOSIN(&aap->aar_arp_dst)->sin_addr;
-
- /*
- * Validate IP address
- */
- if (uniarp_validate_ip(uip, &ip, aap->aar_arp_origin) != 0) {
- err = EADDRNOTAVAIL;
- break;
- }
-
- /*
- * Add an entry to the cache
- */
- err = uniarp_cache_svc(uip, &ip, &aap->aar_arp_addr,
- &atmsub, aap->aar_arp_origin);
- break;
-
- case AIOCS_DEL_ARP:
- /*
- * Delete an ARP mapping
- */
- adp = (struct atmdelreq *)data;
- uip = (struct uniip *)arg1;
- ip = SATOSIN(&adp->adr_arp_dst)->sin_addr;
-
- /*
- * Now find the entry to be deleted
- */
- UNIARP_LOOKUP(ip.s_addr, uap);
- if (uap == NULL) {
- err = ENOENT;
- break;
- }
-
- /*
- * Notify all VCCs using this entry that they must finish
- * up now.
- */
- uap->ua_flags |= UAF_LOCKED;
- for (ivp = uap->ua_ivp; ivp; ivp = inext) {
- inext = ivp->iv_arpnext;
- (*ivp->iv_ipnif->inf_arpnotify)(ivp, MAP_FAILED);
- }
-
- /*
- * Now free up the entry
- */
- UNIARP_CANCEL(uap);
- UNIARP_DELETE(uap);
- uma_zfree(uniarp_zone, uap);
- break;
-
- case AIOCS_SET_ASV:
- /*
- * Set interface ARP server address
- */
- asp = (struct atmsetreq *)data;
- for (uip = uniip_head; uip; uip = uip->uip_next) {
- if (uip->uip_ipnif->inf_nif == (struct atm_nif *)arg1)
- break;
- }
- if (uip == NULL) {
- err = ENOPROTOOPT;
- break;
- }
-
- /*
- * Check for our own address
- */
- usp = (struct unisig *)
- uip->uip_ipnif->inf_nif->nif_pif->pif_siginst;
- if (ATM_ADDR_EQUAL(&asp->asr_arp_addr, &usp->us_addr)) {
- asp->asr_arp_addr.address_format = T_ATM_ABSENT;
- }
-
- /*
- * If we're going into server mode, make sure we can get
- * the memory for the prefix list before continuing
- */
- if (asp->asr_arp_addr.address_format == T_ATM_ABSENT) {
- i = asp->asr_arp_plen / sizeof(struct uniarp_prf);
- if (i == 0) {
- err = EINVAL;
- break;
- }
- buf_len = i * sizeof(struct uniarp_prf);
- buf_addr = malloc(buf_len, M_DEVBUF, M_NOWAIT);
- if (buf_addr == NULL) {
- err = ENOMEM;
- break;
- }
- err = copyin(asp->asr_arp_pbuf, buf_addr, buf_len);
- if (err) {
- free(buf_addr, M_DEVBUF);
- break;
- }
- } else {
- /* Silence the compiler */
- i = 0;
- buf_addr = NULL;
- }
-
- /*
- * Free any existing prefix address list
- */
- if (uip->uip_prefix != NULL) {
- free(uip->uip_prefix, M_DEVBUF);
- uip->uip_prefix = NULL;
- uip->uip_nprefix = 0;
- }
-
- if (asp->asr_arp_addr.address_format == T_ATM_ABSENT) {
- /*
- * Set ATMARP server mode
- */
- uip->uip_prefix = (struct uniarp_prf *)buf_addr;
- uip->uip_nprefix = i;
- uniarp_server_mode(uip);
- } else
- /*
- * Set ATMARP client mode
- */
- uniarp_client_mode(uip, &asp->asr_arp_addr);
- break;
-
- case AIOCS_INF_ARP:
- /*
- * Get ARP table information
- */
- aip = (struct atminfreq *)data;
-
- if (aip->air_arp_addr.sa_family != AF_INET)
- break;
- dst = SATOSIN(&aip->air_arp_addr)->sin_addr.s_addr;
-
- buf_addr = aip->air_buf_addr;
- buf_len = aip->air_buf_len;
-
- pip = ((struct siginst *)arg1)->si_pif;
-
- /*
- * Run through entire arp table
- */
- for (i = 0; i < UNIARP_HASHSIZ; i++) {
- for (uap = uniarp_arptab[i]; uap; uap = uap->ua_next) {
- /*
- * We only want valid entries learned
- * from the supplied interface.
- */
- nip = uap->ua_intf->uip_ipnif->inf_nif;
- if (nip->nif_pif != pip)
- continue;
- if ((dst != INADDR_ANY) &&
- (dst != uap->ua_dstip.s_addr))
- continue;
-
- /*
- * Make sure there's room in the user's buffer
- */
- if (buf_len < sizeof(aar)) {
- err = ENOSPC;
- break;
- }
-
- /*
- * Fill in info to be returned
- */
- SATOSIN(&aar.aap_arp_addr)->sin_family =
- AF_INET;
- SATOSIN(&aar.aap_arp_addr)->sin_addr.s_addr =
- uap->ua_dstip.s_addr;
- strlcpy(aar.aap_intf, ANIF2IFP(nip)->if_xname,
- sizeof(aar.aap_intf));
- aar.aap_flags = uap->ua_flags;
- aar.aap_origin = uap->ua_origin;
- if (uap->ua_flags & UAF_VALID)
- aar.aap_age = uap->ua_aging +
- uap->ua_retry * UNIARP_RETRY_AGE;
- else
- aar.aap_age = 0;
- ATM_ADDR_COPY(&uap->ua_dstatm, &aar.aap_addr);
- ATM_ADDR_COPY(&uap->ua_dstatmsub,
- &aar.aap_subaddr);
-
- /*
- * Copy the response into the user's buffer
- */
- if ((err = copyout((caddr_t)&aar, buf_addr,
- sizeof(aar))) != 0)
- break;
- buf_addr += sizeof(aar);
- buf_len -= sizeof(aar);
- }
- if (err)
- break;
- }
-
- /*
- * Now go through the 'nomap' table
- */
- if (err || (dst != INADDR_ANY))
- goto updbuf;
- for (uap = uniarp_nomaptab; uap; uap = uap->ua_next) {
- /*
- * We only want valid entries learned
- * from the supplied interface.
- */
- nip = uap->ua_intf->uip_ipnif->inf_nif;
- if (nip->nif_pif != pip)
- continue;
-
- /*
- * Make sure there's room in the user's buffer
- */
- if (buf_len < sizeof(aar)) {
- err = ENOSPC;
- break;
- }
-
- /*
- * Fill in info to be returned
- */
- SATOSIN(&aar.aap_arp_addr)->sin_family = AF_INET;
- SATOSIN(&aar.aap_arp_addr)->sin_addr.s_addr = 0;
- strlcpy(aar.aap_intf, ANIF2IFP(nip)->if_xname,
- sizeof(aar.aap_intf));
- aar.aap_flags = 0;
- aar.aap_origin = uap->ua_origin;
- aar.aap_age = 0;
- ATM_ADDR_COPY(&uap->ua_dstatm, &aar.aap_addr);
- ATM_ADDR_COPY(&uap->ua_dstatmsub,
- &aar.aap_subaddr);
-
- /*
- * Copy the response into the user's buffer
- */
- if ((err = copyout((caddr_t)&aar, buf_addr,
- sizeof(aar))) != 0)
- break;
- buf_addr += sizeof(aar);
- buf_len -= sizeof(aar);
- }
-
-updbuf:
- /*
- * Update the buffer pointer and length
- */
- aip->air_buf_addr = buf_addr;
- aip->air_buf_len = buf_len;
-
- /*
- * If the user wants the refresh status reset and no
- * errors have been encountered, then do the reset
- */
- if ((err == 0) && (aip->air_arp_flags & ARP_RESET_REF)) {
- for (i = 0; i < UNIARP_HASHSIZ; i++) {
- for (uap = uniarp_arptab[i]; uap;
- uap = uap->ua_next) {
- /*
- * We only want valid entries learned
- * from the supplied interface.
- */
- nip = uap->ua_intf->uip_ipnif->inf_nif;
- if (nip->nif_pif != pip)
- continue;
- if ((dst != INADDR_ANY) &&
- (dst != uap->ua_dstip.s_addr))
- continue;
-
- /*
- * Reset refresh flag
- */
- uap->ua_flags &= ~UAF_REFRESH;
- }
- }
- }
- break;
-
- case AIOCS_INF_ASV:
- /*
- * Get ARP server information
- */
- aip = (struct atminfreq *)data;
- nip = (struct atm_nif *)arg1;
-
- buf_addr = aip->air_buf_addr;
- buf_len = aip->air_buf_len;
-
- for (uip = uniip_head; uip; uip = uip->uip_next) {
-
- if (uip->uip_ipnif->inf_nif != nip)
- continue;
-
- /*
- * Make sure there's room in the user's buffer
- */
- if (buf_len < sizeof(asr)) {
- err = ENOSPC;
- break;
- }
-
- /*
- * Fill in info to be returned
- */
- strlcpy(asr.asp_intf, ANIF2IFP(nip)->if_xname,
- sizeof(asr.asp_intf));
- asr.asp_state = uip->uip_arpstate;
- if (uip->uip_arpstate == UIAS_SERVER_ACTIVE) {
- asr.asp_addr.address_format = T_ATM_ABSENT;
- asr.asp_addr.address_length = 0;
- } else {
- ATM_ADDR_COPY(&uip->uip_arpsvratm,
- &asr.asp_addr);
- }
- asr.asp_subaddr.address_format = T_ATM_ABSENT;
- asr.asp_subaddr.address_length = 0;
- asr.asp_nprefix = uip->uip_nprefix;
-
- /*
- * Copy the response into the user's buffer
- */
- if ((err = copyout((caddr_t)&asr, buf_addr, sizeof(asr))) != 0)
- break;
- buf_addr += sizeof(asr);
- buf_len -= sizeof(asr);
-
- /*
- * Copy the prefix list into the user's buffer
- */
- if (uip->uip_nprefix) {
- tlen = uip->uip_nprefix *
- sizeof(struct uniarp_prf);
- if (buf_len < tlen) {
- err = ENOSPC;
- break;
- }
- err = copyout(uip->uip_prefix, buf_addr, tlen);
- if (err != 0)
- break;
- buf_addr += tlen;
- buf_len -= tlen;
- }
- }
-
- /*
- * Update the buffer pointer and length
- */
- aip->air_buf_addr = buf_addr;
- aip->air_buf_len = buf_len;
- break;
-
- default:
- err = EOPNOTSUPP;
- }
-
- return (err);
-}
-
-
-/*
- * Get Connection's Application/Owner Name
- *
- * Arguments:
- * tok uniarp connection token (pointer to ipvcc)
- *
- * Returns:
- * addr pointer to string containing our name
- *
- */
-caddr_t
-uniarp_getname(tok)
- void *tok;
-{
- return ("ATMARP");
-}
-
OpenPOWER on IntegriCloud