Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / netproto / atm / uni / uniip.c
1 /*
2  *
3  * ===================================
4  * HARP  |  Host ATM Research Platform
5  * ===================================
6  *
7  *
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.
12  *
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.
20  *
21  * Copyright 1994-1998 Network Computing Services, Inc.
22  *
23  * Copies of this Software may be made, however, the above copyright
24  * notice must be reproduced on all copies.
25  *
26  *      @(#) $FreeBSD: src/sys/netatm/uni/uniip.c,v 1.4 1999/08/28 00:49:03 peter Exp $
27  *
28  */
29
30 /*
31  * ATM Forum UNI Support
32  * ---------------------
33  *
34  * UNI IP interface module
35  *
36  */
37
38 #include <netatm/kern_include.h>
39
40 #include <netatm/ipatm/ipatm_var.h>
41 #include <netatm/ipatm/ipatm_serv.h>
42 #include <netatm/uni/uniip_var.h>
43
44 #ifndef lint
45 __RCSID("@(#) $FreeBSD: src/sys/netatm/uni/uniip.c,v 1.4 1999/08/28 00:49:03 peter Exp $");
46 #endif
47
48
49 /*
50  * Local functions
51  */
52 static int      uniip_ipact __P((struct ip_nif *));
53 static int      uniip_ipdact __P((struct ip_nif *));
54
55
56 /*
57  * Global variables
58  */
59 struct uniip    *uniip_head = NULL;
60
61 struct ip_serv  uniip_ipserv = {
62         uniip_ipact,
63         uniip_ipdact,
64         uniarp_ioctl,
65         uniarp_pvcopen,
66         uniarp_svcout,
67         uniarp_svcin,
68         uniarp_svcactive,
69         uniarp_vcclose,
70         NULL,
71         { { ATM_AAL5, ATM_ENC_LLC} },
72 };
73
74
75 /*
76  * Local variables
77  */
78 static struct sp_info  uniip_pool = {
79         "uni ip pool",                  /* si_name */
80         sizeof(struct uniip),           /* si_blksiz */
81         2,                              /* si_blkcnt */
82         100                             /* si_maxallow */
83 };
84
85
86 /*
87  * Process module loading notification
88  * 
89  * Called whenever the uni module is initializing.  
90  *
91  * Arguments:
92  *      none
93  *
94  * Returns:
95  *      0       initialization successful
96  *      errno   initialization failed - reason indicated
97  *
98  */
99 int
100 uniip_start()
101 {
102         int     err;
103
104         /*
105          * Tell arp to initialize stuff
106          */
107         err = uniarp_start();
108
109         return (err);
110 }
111
112
113 /*
114  * Process module unloading notification
115  * 
116  * Called whenever the uni module is about to be unloaded.  All signalling
117  * instances will have been previously detached.  All uniip resources
118  * must be freed now.
119  *
120  * Arguments:
121  *      none
122  *
123  * Returns:
124  *      0       shutdown was successful 
125  *      errno   shutdown failed - reason indicated
126  *
127  */
128 int
129 uniip_stop()
130 {
131
132         /*
133          * All IP interfaces should be gone
134          */
135         if (uniip_head)
136                 return (EBUSY);
137
138         /*
139          * Tell arp to stop
140          */
141         uniarp_stop();
142
143         /*
144          * Free our storage pools
145          */
146         atm_release_pool(&uniip_pool);
147
148         return (0);
149 }
150
151
152 /*
153  * Process IP Network Interface Activation
154  * 
155  * Called whenever an IP network interface becomes active.
156  *
157  * Called at splnet.
158  *
159  * Arguments:
160  *      inp     pointer to IP network interface
161  *
162  * Returns:
163  *      0       command successful
164  *      errno   command failed - reason indicated
165  *
166  */
167 static int
168 uniip_ipact(inp)
169         struct ip_nif   *inp;
170 {
171         struct uniip            *uip;
172
173         /*
174          * Make sure we don't already have this interface
175          */
176         for (uip = uniip_head; uip; uip = uip->uip_next) {
177                 if (uip->uip_ipnif == inp)
178                         return (EEXIST);
179         }
180
181         /*
182          * Get a new interface control block
183          */
184         uip = (struct uniip *)atm_allocate(&uniip_pool);
185         if (uip == NULL)
186                 return (ENOMEM);
187
188         /*
189          * Initialize and link up
190          */
191         uip->uip_ipnif = inp;
192         LINK2TAIL(uip, struct uniip, uniip_head, uip_next);
193
194         /*
195          * Link from IP world
196          */
197         inp->inf_isintf = (caddr_t)uip;
198
199         /*
200          * Tell arp about new interface
201          */
202         uniarp_ipact(uip);
203
204         return (0);
205 }
206
207
208 /*
209  * Process IP Network Interface Deactivation
210  * 
211  * Called whenever an IP network interface becomes inactive.
212  *
213  * Called at splnet.
214  *
215  * Arguments:
216  *      inp     pointer to IP network interface
217  *
218  * Returns:
219  *      0       command successful
220  *      errno   command failed - reason indicated
221  *
222  */
223 static int
224 uniip_ipdact(inp)
225         struct ip_nif   *inp;
226 {
227         struct uniip            *uip;
228
229         /*
230          * Get the appropriate IP interface block
231          */
232         uip = (struct uniip *)inp->inf_isintf;
233         if (uip == NULL)
234                 return (ENXIO);
235
236         /*
237          * Let arp know about this
238          */
239         uniarp_ipdact(uip);
240
241         /*
242          * Free interface info
243          */
244         UNLINK(uip, struct uniip, uniip_head, uip_next);
245         if (uip->uip_prefix != NULL)
246                 KM_FREE(uip->uip_prefix, 
247                         uip->uip_nprefix * sizeof(struct uniarp_prf), M_DEVBUF);
248         atm_free((caddr_t)uip);
249
250         return (0);
251 }
252