3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sys/netatm/ipatm/ipatm_if.c,v 1.4 2000/01/17 20:49:43 mks Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/ipatm/ipatm_if.c,v 1.7 2006/01/14 13:36:39 swildner Exp $
38 #include <netproto/atm/kern_include.h>
40 #include "ipatm_var.h"
41 #include "ipatm_serv.h"
46 static void ipatm_closenif (struct ip_nif *);
50 * Process Network Interface status change
52 * Called whenever a network interface status change is requested.
58 * nip pointer to atm network interface control block
59 * arg command specific parameter
62 * 0 command successful
63 * errno command failed - reason indicated
67 ipatm_nifstat(int cmd, struct atm_nif *nip, int arg)
75 * Look for corresponding IP interface
77 for (inp = ipatm_nif_head; inp; inp = inp->inf_next) {
78 if (inp->inf_nif == nip)
89 * Make sure i/f isn't already attached
97 * Get a new interface block
99 inp = (struct ip_nif *)atm_allocate(&ipatm_nifpool);
105 inp->inf_state = IPNIF_ADDR;
106 inp->inf_arpnotify = ipatm_arpnotify;
107 inp->inf_ipinput = ipatm_ipinput;
108 inp->inf_createsvc = ipatm_createsvc;
109 LINK2TAIL(inp, struct ip_nif, ipatm_nif_head, inf_next);
114 * Make sure i/f is attached
122 * Validate interface stuff
124 if (Q_HEAD(inp->inf_vcq, struct ipvcc))
125 panic("ipatm_nifstat: ipvcc queue not empty");
128 * If we're active, close all our VCCs and tell the
129 * interface service about the deactivation
131 if (inp->inf_state == IPNIF_ACTIVE) {
136 (*inp->inf_serv->is_ifdact)(inp);
140 * Clean up and free block
142 UNLINK(inp, struct ip_nif, ipatm_nif_head, inf_next);
143 atm_free((caddr_t)inp);
148 * We only care about IP addresses
150 if (((struct ifaddr *)arg)->ifa_addr->sa_family != AF_INET)
154 * Make sure i/f is there
156 ia = (struct in_ifaddr *)arg;
158 panic("ipatm_nifstat: setaddr missing ip_nif");
161 * Process new address
163 switch (inp->inf_state) {
170 * If signalling manager is not set, wait for it
172 sip = nip->nif_pif->pif_siginst;
174 inp->inf_state = IPNIF_SIGMGR;
179 * Otherwise, everything's set
181 inp->inf_state = IPNIF_ACTIVE;
184 * Tell interface service we're around
186 if (sip->si_ipserv) {
187 inp->inf_serv = sip->si_ipserv;
188 err = (*inp->inf_serv->is_ifact)(inp);
192 * Reset state if there's been a problem
195 inp->inf_serv = NULL;
196 inp->inf_addr = NULL;
197 inp->inf_state = IPNIF_ADDR;
203 * We dont support an address change
212 * Make sure i/f is attached
220 * Are we waiting for the sigmgr attach??
222 if (inp->inf_state != IPNIF_SIGMGR) {
224 * No, nothing else to do
230 * OK, everything's set
232 inp->inf_state = IPNIF_ACTIVE;
235 * Tell interface service we're around
237 sip = nip->nif_pif->pif_siginst;
238 if (sip->si_ipserv) {
239 inp->inf_serv = sip->si_ipserv;
240 err = (*inp->inf_serv->is_ifact)(inp);
244 * Just report any problems, since a NCM_SIGDETACH will
245 * be coming down immediately
251 * Make sure i/f is attached
259 * Are we currently active??
261 if (inp->inf_state != IPNIF_ACTIVE) {
263 * No, nothing else to do
269 * Close all the IP VCCs for this interface
274 * Tell interface service that i/f has gone down
277 (*inp->inf_serv->is_ifdact)(inp);
280 * Just have to wait for another sigattach
282 inp->inf_serv = NULL;
283 inp->inf_state = IPNIF_SIGMGR;
287 log(LOG_ERR, "ipatm_nifstat: unknown command %d\n", cmd);
295 * Close all VCCs on a Network Interface
300 * inp pointer to IP network interface
307 ipatm_closenif(struct ip_nif *inp)
309 struct ipvcc *ivp, *inext;
312 * Close each IP VCC on this interface
314 for (ivp = Q_HEAD(inp->inf_vcq, struct ipvcc); ivp; ivp = inext) {
316 inext = Q_NEXT(ivp, struct ipvcc, iv_elem);
318 ipatm_closevc(ivp, T_ATM_CAUSE_UNSPECIFIED_NORMAL);