be4f357149
- Prefer '_' to ' ', as it results in more easily parsed results in memory monitoring tools such as vmstat. - Remove punctuation that is incompatible with using memory type names as file names, such as '/' characters. - Disambiguate some collisions by adding subsystem prefixes to some memory types. - Generally prefer lower case to upper case. - If the same type is defined in multiple architecture directories, attempt to use the same name in additional cases. Not all instances were caught in this change, so more work is required to finish this conversion. Similar changes are required for UMA zone names.
344 lines
6.5 KiB
C
344 lines
6.5 KiB
C
/*-
|
|
* ===================================
|
|
* 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.
|
|
*/
|
|
|
|
/*
|
|
* IP Over ATM Support
|
|
* -------------------
|
|
*
|
|
* Interface Manager
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/types.h>
|
|
#include <sys/systm.h>
|
|
#include <sys/errno.h>
|
|
#include <sys/time.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/socketvar.h>
|
|
#include <sys/syslog.h>
|
|
#include <sys/malloc.h>
|
|
#include <sys/kernel.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_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>
|
|
|
|
static MALLOC_DEFINE(M_IPATM_NIF, "ipatm_nif", "IP/ATM network interfaces");
|
|
|
|
/*
|
|
* Local functions
|
|
*/
|
|
static void ipatm_closenif(struct ip_nif *);
|
|
|
|
|
|
/*
|
|
* Process Network Interface status change
|
|
*
|
|
* Called whenever a network interface status change is requested.
|
|
*
|
|
* Called at splnet.
|
|
*
|
|
* Arguments:
|
|
* cmd command code
|
|
* nip pointer to atm network interface control block
|
|
* arg command specific parameter
|
|
*
|
|
* Returns:
|
|
* 0 command successful
|
|
* errno command failed - reason indicated
|
|
*
|
|
*/
|
|
int
|
|
ipatm_nifstat(cmd, nip, arg)
|
|
int cmd;
|
|
struct atm_nif *nip;
|
|
intptr_t arg;
|
|
{
|
|
struct in_ifaddr *ia;
|
|
struct siginst *sip;
|
|
struct ip_nif *inp;
|
|
int err = 0;
|
|
|
|
/*
|
|
* Look for corresponding IP interface
|
|
*/
|
|
for (inp = ipatm_nif_head; inp; inp = inp->inf_next) {
|
|
if (inp->inf_nif == nip)
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Process command
|
|
*/
|
|
switch (cmd) {
|
|
|
|
case NCM_ATTACH:
|
|
/*
|
|
* Make sure i/f isn't already attached
|
|
*/
|
|
if (inp != NULL) {
|
|
err = EEXIST;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Get a new interface block
|
|
*/
|
|
inp = malloc(sizeof(*inp), M_IPATM_NIF, M_WAITOK | M_ZERO);
|
|
inp->inf_nif = nip;
|
|
inp->inf_state = IPNIF_ADDR;
|
|
inp->inf_arpnotify = ipatm_arpnotify;
|
|
inp->inf_ipinput = ipatm_ipinput;
|
|
inp->inf_createsvc = ipatm_createsvc;
|
|
LINK2TAIL(inp, struct ip_nif, ipatm_nif_head, inf_next);
|
|
break;
|
|
|
|
case NCM_DETACH:
|
|
/*
|
|
* Make sure i/f is attached
|
|
*/
|
|
if (inp == NULL) {
|
|
err = ENODEV;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Validate interface stuff
|
|
*/
|
|
if (Q_HEAD(inp->inf_vcq, struct ipvcc))
|
|
panic("ipatm_nifstat: ipvcc queue not empty");
|
|
|
|
/*
|
|
* If we're active, close all our VCCs and tell the
|
|
* interface service about the deactivation
|
|
*/
|
|
if (inp->inf_state == IPNIF_ACTIVE) {
|
|
|
|
ipatm_closenif(inp);
|
|
|
|
if (inp->inf_serv)
|
|
(void) (*inp->inf_serv->is_ifdact)(inp);
|
|
}
|
|
|
|
/*
|
|
* Clean up and free block
|
|
*/
|
|
UNLINK(inp, struct ip_nif, ipatm_nif_head, inf_next);
|
|
free(inp, M_IPATM_NIF);
|
|
break;
|
|
|
|
case NCM_SETADDR:
|
|
/*
|
|
* We only care about IP addresses
|
|
*/
|
|
if (((struct ifaddr *)arg)->ifa_addr->sa_family != AF_INET)
|
|
break;
|
|
|
|
/*
|
|
* Make sure i/f is there
|
|
*/
|
|
ia = (struct in_ifaddr *)arg;
|
|
if (inp == NULL)
|
|
panic("ipatm_nifstat: setaddr missing ip_nif");
|
|
|
|
/*
|
|
* Process new address
|
|
*/
|
|
switch (inp->inf_state) {
|
|
|
|
case IPNIF_SIGMGR:
|
|
case IPNIF_ADDR:
|
|
inp->inf_addr = ia;
|
|
|
|
/*
|
|
* If signalling manager is not set, wait for it
|
|
*/
|
|
sip = nip->nif_pif->pif_siginst;
|
|
if (sip == NULL) {
|
|
inp->inf_state = IPNIF_SIGMGR;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Otherwise, everything's set
|
|
*/
|
|
inp->inf_state = IPNIF_ACTIVE;
|
|
|
|
/*
|
|
* Tell interface service we're around
|
|
*/
|
|
if (sip->si_ipserv) {
|
|
inp->inf_serv = sip->si_ipserv;
|
|
err = (*inp->inf_serv->is_ifact)(inp);
|
|
}
|
|
|
|
/*
|
|
* Reset state if there's been a problem
|
|
*/
|
|
if (err) {
|
|
inp->inf_serv = NULL;
|
|
inp->inf_addr = NULL;
|
|
inp->inf_state = IPNIF_ADDR;
|
|
}
|
|
break;
|
|
|
|
case IPNIF_ACTIVE:
|
|
/*
|
|
* We dont support an address change
|
|
*/
|
|
err = EEXIST;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case NCM_SIGATTACH:
|
|
/*
|
|
* Make sure i/f is attached
|
|
*/
|
|
if (inp == NULL) {
|
|
err = ENODEV;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Are we waiting for the sigmgr attach??
|
|
*/
|
|
if (inp->inf_state != IPNIF_SIGMGR) {
|
|
/*
|
|
* No, nothing else to do
|
|
*/
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* OK, everything's set
|
|
*/
|
|
inp->inf_state = IPNIF_ACTIVE;
|
|
|
|
/*
|
|
* Tell interface service we're around
|
|
*/
|
|
sip = nip->nif_pif->pif_siginst;
|
|
if (sip->si_ipserv) {
|
|
inp->inf_serv = sip->si_ipserv;
|
|
err = (*inp->inf_serv->is_ifact)(inp);
|
|
}
|
|
|
|
/*
|
|
* Just report any problems, since a NCM_SIGDETACH will
|
|
* be coming down immediately
|
|
*/
|
|
break;
|
|
|
|
case NCM_SIGDETACH:
|
|
/*
|
|
* Make sure i/f is attached
|
|
*/
|
|
if (inp == NULL) {
|
|
err = ENODEV;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Are we currently active??
|
|
*/
|
|
if (inp->inf_state != IPNIF_ACTIVE) {
|
|
/*
|
|
* No, nothing else to do
|
|
*/
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Close all the IP VCCs for this interface
|
|
*/
|
|
ipatm_closenif(inp);
|
|
|
|
/*
|
|
* Tell interface service that i/f has gone down
|
|
*/
|
|
if (inp->inf_serv)
|
|
(void) (*inp->inf_serv->is_ifdact)(inp);
|
|
|
|
/*
|
|
* Just have to wait for another sigattach
|
|
*/
|
|
inp->inf_serv = NULL;
|
|
inp->inf_state = IPNIF_SIGMGR;
|
|
break;
|
|
|
|
default:
|
|
log(LOG_ERR, "ipatm_nifstat: unknown command %d\n", cmd);
|
|
}
|
|
|
|
return (err);
|
|
}
|
|
|
|
|
|
/*
|
|
* Close all VCCs on a Network Interface
|
|
*
|
|
* Called at splnet.
|
|
*
|
|
* Arguments:
|
|
* inp pointer to IP network interface
|
|
*
|
|
* Returns:
|
|
* none
|
|
*
|
|
*/
|
|
static void
|
|
ipatm_closenif(inp)
|
|
struct ip_nif *inp;
|
|
{
|
|
struct ipvcc *ivp, *inext;
|
|
|
|
/*
|
|
* Close each IP VCC on this interface
|
|
*/
|
|
for (ivp = Q_HEAD(inp->inf_vcq, struct ipvcc); ivp; ivp = inext) {
|
|
|
|
inext = Q_NEXT(ivp, struct ipvcc, iv_elem);
|
|
|
|
(void) ipatm_closevc(ivp, T_ATM_CAUSE_UNSPECIFIED_NORMAL);
|
|
}
|
|
}
|
|
|