2 * ===================================
3 * HARP | Host ATM Research Platform
4 * ===================================
7 * This Host ATM Research Platform ("HARP") file (the "Software") is
8 * made available by Network Computing Services, Inc. ("NetworkCS")
9 * "AS IS". NetworkCS does not provide maintenance, improvements or
10 * support of any kind.
12 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
13 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
14 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
15 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
16 * In no event shall NetworkCS be responsible for any damages, including
17 * but not limited to consequential damages, arising from or relating to
18 * any use of the Software or related support.
20 * Copyright 1994-1998 Network Computing Services, Inc.
22 * Copies of this Software may be made, however, the above copyright
23 * notice must be reproduced on all copies.
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/systm.h>
39 #include <sys/errno.h>
41 #include <sys/socket.h>
42 #include <sys/socketvar.h>
43 #include <sys/syslog.h>
44 #include <sys/malloc.h>
45 #include <sys/kernel.h>
47 #include <netinet/in.h>
48 #include <netatm/port.h>
49 #include <netatm/queue.h>
50 #include <netatm/atm.h>
51 #include <netatm/atm_sys.h>
52 #include <netatm/atm_sap.h>
53 #include <netatm/atm_cm.h>
54 #include <netatm/atm_if.h>
55 #include <netatm/atm_sigmgr.h>
56 #include <netatm/atm_stack.h>
57 #include <netatm/atm_pcb.h>
58 #include <netatm/atm_var.h>
60 #include <netatm/ipatm/ipatm_var.h>
61 #include <netatm/ipatm/ipatm_serv.h>
63 static MALLOC_DEFINE(M_IPATM_NIF, "ipatm nif", "IP/ATM network interfaces");
68 static void ipatm_closenif(struct ip_nif *);
72 * Process Network Interface status change
74 * Called whenever a network interface status change is requested.
80 * nip pointer to atm network interface control block
81 * arg command specific parameter
84 * 0 command successful
85 * errno command failed - reason indicated
89 ipatm_nifstat(cmd, nip, arg)
100 * Look for corresponding IP interface
102 for (inp = ipatm_nif_head; inp; inp = inp->inf_next) {
103 if (inp->inf_nif == nip)
114 * Make sure i/f isn't already attached
122 * Get a new interface block
124 inp = malloc(sizeof(*inp), M_IPATM_NIF, M_WAITOK | M_ZERO);
126 inp->inf_state = IPNIF_ADDR;
127 inp->inf_arpnotify = ipatm_arpnotify;
128 inp->inf_ipinput = ipatm_ipinput;
129 inp->inf_createsvc = ipatm_createsvc;
130 LINK2TAIL(inp, struct ip_nif, ipatm_nif_head, inf_next);
135 * Make sure i/f is attached
143 * Validate interface stuff
145 if (Q_HEAD(inp->inf_vcq, struct ipvcc))
146 panic("ipatm_nifstat: ipvcc queue not empty");
149 * If we're active, close all our VCCs and tell the
150 * interface service about the deactivation
152 if (inp->inf_state == IPNIF_ACTIVE) {
157 (void) (*inp->inf_serv->is_ifdact)(inp);
161 * Clean up and free block
163 UNLINK(inp, struct ip_nif, ipatm_nif_head, inf_next);
164 free(inp, M_IPATM_NIF);
169 * We only care about IP addresses
171 if (((struct ifaddr *)arg)->ifa_addr->sa_family != AF_INET)
175 * Make sure i/f is there
177 ia = (struct in_ifaddr *)arg;
179 panic("ipatm_nifstat: setaddr missing ip_nif");
182 * Process new address
184 switch (inp->inf_state) {
191 * If signalling manager is not set, wait for it
193 sip = nip->nif_pif->pif_siginst;
195 inp->inf_state = IPNIF_SIGMGR;
200 * Otherwise, everything's set
202 inp->inf_state = IPNIF_ACTIVE;
205 * Tell interface service we're around
207 if (sip->si_ipserv) {
208 inp->inf_serv = sip->si_ipserv;
209 err = (*inp->inf_serv->is_ifact)(inp);
213 * Reset state if there's been a problem
216 inp->inf_serv = NULL;
217 inp->inf_addr = NULL;
218 inp->inf_state = IPNIF_ADDR;
224 * We dont support an address change
233 * Make sure i/f is attached
241 * Are we waiting for the sigmgr attach??
243 if (inp->inf_state != IPNIF_SIGMGR) {
245 * No, nothing else to do
251 * OK, everything's set
253 inp->inf_state = IPNIF_ACTIVE;
256 * Tell interface service we're around
258 sip = nip->nif_pif->pif_siginst;
259 if (sip->si_ipserv) {
260 inp->inf_serv = sip->si_ipserv;
261 err = (*inp->inf_serv->is_ifact)(inp);
265 * Just report any problems, since a NCM_SIGDETACH will
266 * be coming down immediately
272 * Make sure i/f is attached
280 * Are we currently active??
282 if (inp->inf_state != IPNIF_ACTIVE) {
284 * No, nothing else to do
290 * Close all the IP VCCs for this interface
295 * Tell interface service that i/f has gone down
298 (void) (*inp->inf_serv->is_ifdact)(inp);
301 * Just have to wait for another sigattach
303 inp->inf_serv = NULL;
304 inp->inf_state = IPNIF_SIGMGR;
308 log(LOG_ERR, "ipatm_nifstat: unknown command %d\n", cmd);
316 * Close all VCCs on a Network Interface
321 * inp pointer to IP network interface
331 struct ipvcc *ivp, *inext;
334 * Close each IP VCC on this interface
336 for (ivp = Q_HEAD(inp->inf_vcq, struct ipvcc); ivp; ivp = inext) {
338 inext = Q_NEXT(ivp, struct ipvcc, iv_elem);
340 (void) ipatm_closevc(ivp, T_ATM_CAUSE_UNSPECIFIED_NORMAL);