cleanup
[linux-2.4.21-pre4.git] / net / atm / common.c
1 /* net/atm/common.c - ATM sockets (common part for PVC and SVC) */
2
3 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
4
5
6 #include <linux/config.h>
7 #include <linux/module.h>
8 #include <linux/kmod.h>
9 #include <linux/net.h>          /* struct socket, struct net_proto, struct
10                                    proto_ops */
11 #include <linux/atm.h>          /* ATM stuff */
12 #include <linux/atmdev.h>
13 #include <linux/atmclip.h>      /* CLIP_*ENCAP */
14 #include <linux/atmarp.h>       /* manifest constants */
15 #include <linux/sonet.h>        /* for ioctls */
16 #include <linux/socket.h>       /* SOL_SOCKET */
17 #include <linux/errno.h>        /* error codes */
18 #include <linux/capability.h>
19 #include <linux/mm.h>           /* verify_area */
20 #include <linux/sched.h>
21 #include <linux/time.h>         /* struct timeval */
22 #include <linux/skbuff.h>
23 #include <linux/bitops.h>
24 #include <net/sock.h>           /* struct sock */
25
26 #include <asm/uaccess.h>
27 #include <asm/atomic.h>
28 #include <asm/poll.h>
29 #include <asm/ioctls.h>
30
31 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
32 #include <linux/atmlec.h>
33 #include "lec.h"
34 #include "lec_arpc.h"
35 struct atm_lane_ops atm_lane_ops;
36 #endif
37 #ifdef CONFIG_ATM_LANE_MODULE
38 EXPORT_SYMBOL(atm_lane_ops);
39 #endif
40
41 #if defined(CONFIG_ATM_MPOA) || defined(CONFIG_ATM_MPOA_MODULE)
42 #include <linux/atmmpc.h>
43 #include "mpc.h"
44 struct atm_mpoa_ops atm_mpoa_ops;
45 #endif
46 #ifdef CONFIG_ATM_MPOA_MODULE
47 EXPORT_SYMBOL(atm_mpoa_ops);
48 #ifndef CONFIG_ATM_LANE_MODULE
49 EXPORT_SYMBOL(atm_lane_ops);
50 #endif
51 #endif
52
53 #if defined(CONFIG_ATM_TCP) || defined(CONFIG_ATM_TCP_MODULE)
54 #include <linux/atm_tcp.h>
55 #ifdef CONFIG_ATM_TCP_MODULE
56 struct atm_tcp_ops atm_tcp_ops;
57 EXPORT_SYMBOL(atm_tcp_ops);
58 #endif
59 #endif
60
61 #if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE)
62 int (*pppoatm_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
63 EXPORT_SYMBOL(pppoatm_ioctl_hook);
64 #endif
65
66 #if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
67 int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
68 #endif
69 #ifdef CONFIG_ATM_BR2684_MODULE
70 EXPORT_SYMBOL(br2684_ioctl_hook);
71 #endif
72
73 #include "resources.h"          /* atm_find_dev */
74 #include "common.h"             /* prototypes */
75 #include "protocols.h"          /* atm_init_<transport> */
76 #include "addr.h"               /* address registry */
77 #ifdef CONFIG_ATM_CLIP
78 #include <net/atmclip.h>        /* for clip_create */
79 #endif
80 #include "signaling.h"          /* for WAITING and sigd_attach */
81
82
83 #if 0
84 #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
85 #else
86 #define DPRINTK(format,args...)
87 #endif
88
89 spinlock_t atm_dev_lock = SPIN_LOCK_UNLOCKED;
90
91 static struct sk_buff *alloc_tx(struct atm_vcc *vcc,unsigned int size)
92 {
93         struct sk_buff *skb;
94
95         if (atomic_read(&vcc->tx_inuse) && !atm_may_send(vcc,size)) {
96                 DPRINTK("Sorry: tx_inuse = %d, size = %d, sndbuf = %d\n",
97                     atomic_read(&vcc->tx_inuse),size,vcc->sk->sndbuf);
98                 return NULL;
99         }
100         while (!(skb = alloc_skb(size,GFP_KERNEL))) schedule();
101         DPRINTK("AlTx %d += %d\n",atomic_read(&vcc->tx_inuse),skb->truesize);
102         atomic_add(skb->truesize+ATM_PDU_OVHD,&vcc->tx_inuse);
103         return skb;
104 }
105
106
107 int atm_create(struct socket *sock,int protocol,int family)
108 {
109         struct sock *sk;
110         struct atm_vcc *vcc;
111
112         sock->sk = NULL;
113         if (sock->type == SOCK_STREAM) return -EINVAL;
114         if (!(sk = alloc_atm_vcc_sk(family))) return -ENOMEM;
115         vcc = sk->protinfo.af_atm;
116         memset(&vcc->flags,0,sizeof(vcc->flags));
117         vcc->dev = NULL;
118         vcc->family = sock->ops->family;
119         vcc->alloc_tx = alloc_tx;
120         vcc->callback = NULL;
121         memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc));
122         memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc));
123         vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */
124         atomic_set(&vcc->tx_inuse,0);
125         atomic_set(&vcc->rx_inuse,0);
126         vcc->push = NULL;
127         vcc->pop = NULL;
128         vcc->push_oam = NULL;
129         vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */
130         vcc->atm_options = vcc->aal_options = 0;
131         vcc->timestamp.tv_sec = vcc->timestamp.tv_usec = 0;
132         init_waitqueue_head(&vcc->sleep);
133         skb_queue_head_init(&vcc->recvq);
134         skb_queue_head_init(&vcc->listenq);
135         sk->sleep = &vcc->sleep;
136         sock->sk = sk;
137         return 0;
138 }
139
140
141 void atm_release_vcc_sk(struct sock *sk,int free_sk)
142 {
143         struct atm_vcc *vcc;
144         struct sk_buff *skb;
145
146         vcc = sk->protinfo.af_atm;
147         clear_bit(ATM_VF_READY,&vcc->flags);
148         if (vcc->dev) {
149                 if (vcc->dev->ops->close) vcc->dev->ops->close(vcc);
150                 if (vcc->push) vcc->push(vcc,NULL); /* atmarpd has no push */
151                 while ((skb = skb_dequeue(&vcc->recvq))) {
152                         atm_return(vcc,skb->truesize);
153                         if (vcc->dev->ops->free_rx_skb)
154                                 vcc->dev->ops->free_rx_skb(vcc,skb);
155                         else kfree_skb(skb);
156                 }
157                 spin_lock (&atm_dev_lock);      
158                 fops_put (vcc->dev->ops);
159                 if (atomic_read(&vcc->rx_inuse))
160                         printk(KERN_WARNING "atm_release_vcc: strange ... "
161                             "rx_inuse == %d after closing\n",
162                             atomic_read(&vcc->rx_inuse));
163                 bind_vcc(vcc,NULL);
164         } else
165                 spin_lock (&atm_dev_lock);      
166
167         if (free_sk) free_atm_vcc_sk(sk);
168
169         spin_unlock (&atm_dev_lock);
170 }
171
172
173 int atm_release(struct socket *sock)
174 {
175         if (sock->sk)
176                 atm_release_vcc_sk(sock->sk,1);
177         return 0;
178 }
179
180
181 void atm_async_release_vcc(struct atm_vcc *vcc,int reply)
182 {
183         set_bit(ATM_VF_CLOSE,&vcc->flags);
184         vcc->reply = reply;
185         wake_up(&vcc->sleep);
186 }
187
188
189 EXPORT_SYMBOL(atm_async_release_vcc);
190
191
192 static int adjust_tp(struct atm_trafprm *tp,unsigned char aal)
193 {
194         int max_sdu;
195
196         if (!tp->traffic_class) return 0;
197         switch (aal) {
198                 case ATM_AAL0:
199                         max_sdu = ATM_CELL_SIZE-1;
200                         break;
201                 case ATM_AAL34:
202                         max_sdu = ATM_MAX_AAL34_PDU;
203                         break;
204                 default:
205                         printk(KERN_WARNING "ATM: AAL problems ... "
206                             "(%d)\n",aal);
207                         /* fall through */
208                 case ATM_AAL5:
209                         max_sdu = ATM_MAX_AAL5_PDU;
210         }
211         if (!tp->max_sdu) tp->max_sdu = max_sdu;
212         else if (tp->max_sdu > max_sdu) return -EINVAL;
213         if (!tp->max_cdv) tp->max_cdv = ATM_MAX_CDV;
214         return 0;
215 }
216
217
218 static int atm_do_connect_dev(struct atm_vcc *vcc,struct atm_dev *dev,int vpi,
219     int vci)
220 {
221         int error;
222
223         if ((vpi != ATM_VPI_UNSPEC && vpi != ATM_VPI_ANY &&
224             vpi >> dev->ci_range.vpi_bits) || (vci != ATM_VCI_UNSPEC &&
225             vci != ATM_VCI_ANY && vci >> dev->ci_range.vci_bits))
226                 return -EINVAL;
227         if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE))
228                 return -EPERM;
229         error = 0;
230         bind_vcc(vcc,dev);
231         switch (vcc->qos.aal) {
232                 case ATM_AAL0:
233                         error = atm_init_aal0(vcc);
234                         vcc->stats = &dev->stats.aal0;
235                         break;
236                 case ATM_AAL34:
237                         error = atm_init_aal34(vcc);
238                         vcc->stats = &dev->stats.aal34;
239                         break;
240                 case ATM_NO_AAL:
241                         /* ATM_AAL5 is also used in the "0 for default" case */
242                         vcc->qos.aal = ATM_AAL5;
243                         /* fall through */
244                 case ATM_AAL5:
245                         error = atm_init_aal5(vcc);
246                         vcc->stats = &dev->stats.aal5;
247                         break;
248                 default:
249                         error = -EPROTOTYPE;
250         }
251         if (!error) error = adjust_tp(&vcc->qos.txtp,vcc->qos.aal);
252         if (!error) error = adjust_tp(&vcc->qos.rxtp,vcc->qos.aal);
253         if (error) {
254                 bind_vcc(vcc,NULL);
255                 return error;
256         }
257         DPRINTK("VCC %d.%d, AAL %d\n",vpi,vci,vcc->qos.aal);
258         DPRINTK("  TX: %d, PCR %d..%d, SDU %d\n",vcc->qos.txtp.traffic_class,
259             vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu);
260         DPRINTK("  RX: %d, PCR %d..%d, SDU %d\n",vcc->qos.rxtp.traffic_class,
261             vcc->qos.rxtp.min_pcr,vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu);
262         fops_get (dev->ops);
263         if (dev->ops->open) {
264                 error = dev->ops->open(vcc,vpi,vci);
265                 if (error) {
266                         fops_put (dev->ops);
267                         bind_vcc(vcc,NULL);
268                         return error;
269                 }
270         }
271         return 0;
272 }
273
274
275 static int atm_do_connect(struct atm_vcc *vcc,int itf,int vpi,int vci)
276 {
277         struct atm_dev *dev;
278         int return_val;
279
280         spin_lock (&atm_dev_lock);
281         dev = atm_find_dev(itf);
282         if (!dev)
283                 return_val =  -ENODEV;
284         else
285                 return_val = atm_do_connect_dev(vcc,dev,vpi,vci);
286
287         spin_unlock (&atm_dev_lock);
288
289         return return_val;
290 }
291
292
293 int atm_connect_vcc(struct atm_vcc *vcc,int itf,short vpi,int vci)
294 {
295         if (vpi != ATM_VPI_UNSPEC && vci != ATM_VCI_UNSPEC)
296                 clear_bit(ATM_VF_PARTIAL,&vcc->flags);
297         else if (test_bit(ATM_VF_PARTIAL,&vcc->flags)) return -EINVAL;
298         printk(KERN_DEBUG "atm_connect (TX: cl %d,bw %d-%d,sdu %d; "
299             "RX: cl %d,bw %d-%d,sdu %d,AAL %s%d)\n",
300             vcc->qos.txtp.traffic_class,vcc->qos.txtp.min_pcr,
301             vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu,
302             vcc->qos.rxtp.traffic_class,vcc->qos.rxtp.min_pcr,
303             vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu,
304             vcc->qos.aal == ATM_AAL5 ? "" : vcc->qos.aal == ATM_AAL0 ? "" :
305             " ??? code ",vcc->qos.aal == ATM_AAL0 ? 0 : vcc->qos.aal);
306         if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
307         if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
308             vcc->qos.rxtp.traffic_class == ATM_ANYCLASS)
309                 return -EINVAL;
310         if (itf != ATM_ITF_ANY) {
311                 int error;
312
313                 error = atm_do_connect(vcc,itf,vpi,vci);
314                 if (error) return error;
315         }
316         else {
317                 struct atm_dev *dev;
318
319                 spin_lock (&atm_dev_lock);
320                 for (dev = atm_devs; dev; dev = dev->next)
321                         if (!atm_do_connect_dev(vcc,dev,vpi,vci)) break;
322                 spin_unlock (&atm_dev_lock);
323                 if (!dev) return -ENODEV;
324         }
325         if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
326                 set_bit(ATM_VF_PARTIAL,&vcc->flags);
327         return 0;
328 }
329
330
331 int atm_connect(struct socket *sock,int itf,short vpi,int vci)
332 {
333         int error;
334
335         DPRINTK("atm_connect (vpi %d, vci %d)\n",vpi,vci);
336         if (sock->state == SS_CONNECTED) return -EISCONN;
337         if (sock->state != SS_UNCONNECTED) return -EINVAL;
338         if (!(vpi || vci)) return -EINVAL;
339         error = atm_connect_vcc(ATM_SD(sock),itf,vpi,vci);
340         if (error) return error;
341         if (test_bit(ATM_VF_READY,&ATM_SD(sock)->flags))
342                 sock->state = SS_CONNECTED;
343         return 0;
344 }
345
346
347 int atm_recvmsg(struct socket *sock,struct msghdr *m,int total_len,
348     int flags,struct scm_cookie *scm)
349 {
350         DECLARE_WAITQUEUE(wait,current);
351         struct atm_vcc *vcc;
352         struct sk_buff *skb;
353         int eff_len,error;
354         void *buff;
355         int size;
356
357         if (sock->state != SS_CONNECTED) return -ENOTCONN;
358         if (flags & ~MSG_DONTWAIT) return -EOPNOTSUPP;
359         if (m->msg_iovlen != 1) return -ENOSYS; /* fix this later @@@ */
360         buff = m->msg_iov->iov_base;
361         size = m->msg_iov->iov_len;
362         vcc = ATM_SD(sock);
363         add_wait_queue(&vcc->sleep,&wait);
364         set_current_state(TASK_INTERRUPTIBLE);
365         error = 1; /* <= 0 is error */
366         while (!(skb = skb_dequeue(&vcc->recvq))) {
367                 if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
368                     test_bit(ATM_VF_CLOSE,&vcc->flags)) {
369                         error = vcc->reply;
370                         break;
371                 }
372                 if (!test_bit(ATM_VF_READY,&vcc->flags)) {
373                         error = 0;
374                         break;
375                 }
376                 if (flags & MSG_DONTWAIT) {
377                         error = -EAGAIN;
378                         break;
379                 }
380                 schedule();
381                 set_current_state(TASK_INTERRUPTIBLE);
382                 if (signal_pending(current)) {
383                         error = -ERESTARTSYS;
384                         break;
385                 }
386         }
387         set_current_state(TASK_RUNNING);
388         remove_wait_queue(&vcc->sleep,&wait);
389         if (error <= 0) return error;
390         vcc->timestamp = skb->stamp;
391         eff_len = skb->len > size ? size : skb->len;
392         if (skb->len > size) /* Not fit ?  Report it... */
393                 m->msg_flags |= MSG_TRUNC;
394         if (vcc->dev->ops->feedback)
395                 vcc->dev->ops->feedback(vcc,skb,(unsigned long) skb->data,
396                     (unsigned long) buff,eff_len);
397         DPRINTK("RcvM %d -= %d\n",atomic_read(&vcc->rx_inuse),skb->truesize);
398         atm_return(vcc,skb->truesize);
399         if (ATM_SKB(skb)->iovcnt) { /* @@@ hack */
400                 /* iovcnt set, use scatter-gather for receive */
401                 int el, cnt;
402                 struct iovec *iov = (struct iovec *)skb->data;
403                 unsigned char *p = (unsigned char *)buff;
404
405                 el = eff_len;
406                 error = 0;
407                 for (cnt = 0; (cnt < ATM_SKB(skb)->iovcnt) && el; cnt++) {
408 /*printk("s-g???: %p -> %p (%d)\n",iov->iov_base,p,iov->iov_len);*/
409                         error = copy_to_user(p,iov->iov_base,
410                             (iov->iov_len > el) ? el : iov->iov_len) ?
411                             -EFAULT : 0;
412                         if (error) break;
413                         p += iov->iov_len;
414                         el -= (iov->iov_len > el)?el:iov->iov_len;
415                         iov++;
416                 }
417                 if (!vcc->dev->ops->free_rx_skb) kfree_skb(skb);
418                 else vcc->dev->ops->free_rx_skb(vcc, skb);
419                 return error ? error : eff_len;
420         }
421         error = copy_to_user(buff,skb->data,eff_len) ? -EFAULT : 0;
422         if (!vcc->dev->ops->free_rx_skb) kfree_skb(skb);
423         else vcc->dev->ops->free_rx_skb(vcc, skb);
424         return error ? error : eff_len;
425 }
426
427
428 int atm_sendmsg(struct socket *sock,struct msghdr *m,int total_len,
429     struct scm_cookie *scm)
430 {
431         DECLARE_WAITQUEUE(wait,current);
432         struct atm_vcc *vcc;
433         struct sk_buff *skb;
434         int eff,error;
435         const void *buff;
436         int size;
437
438         if (sock->state != SS_CONNECTED) return -ENOTCONN;
439         if (m->msg_name) return -EISCONN;
440         if (m->msg_iovlen != 1) return -ENOSYS; /* fix this later @@@ */
441         buff = m->msg_iov->iov_base;
442         size = m->msg_iov->iov_len;
443         vcc = ATM_SD(sock);
444         if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
445             test_bit(ATM_VF_CLOSE,&vcc->flags))
446                 return vcc->reply;
447         if (!test_bit(ATM_VF_READY,&vcc->flags)) return -EPIPE;
448         if (!size) return 0;
449         if (size < 0 || size > vcc->qos.txtp.max_sdu) return -EMSGSIZE;
450         /* verify_area is done by net/socket.c */
451         eff = (size+3) & ~3; /* align to word boundary */
452         add_wait_queue(&vcc->sleep,&wait);
453         set_current_state(TASK_INTERRUPTIBLE);
454         error = 0;
455         while (!(skb = vcc->alloc_tx(vcc,eff))) {
456                 if (m->msg_flags & MSG_DONTWAIT) {
457                         error = -EAGAIN;
458                         break;
459                 }
460                 schedule();
461                 set_current_state(TASK_INTERRUPTIBLE);
462                 if (signal_pending(current)) {
463                         error = -ERESTARTSYS;
464                         break;
465                 }
466                 if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
467                     test_bit(ATM_VF_CLOSE,&vcc->flags)) {
468                         error = vcc->reply;
469                         break;
470                 }
471                 if (!test_bit(ATM_VF_READY,&vcc->flags)) {
472                         error = -EPIPE;
473                         break;
474                 }
475         }
476         set_current_state(TASK_RUNNING);
477         remove_wait_queue(&vcc->sleep,&wait);
478         if (error) return error;
479         skb->dev = NULL; /* for paths shared with net_device interfaces */
480         ATM_SKB(skb)->iovcnt = 0;
481         ATM_SKB(skb)->atm_options = vcc->atm_options;
482         if (copy_from_user(skb_put(skb,size),buff,size)) {
483                 kfree_skb(skb);
484                 return -EFAULT;
485         }
486         if (eff != size) memset(skb->data+size,0,eff-size);
487         error = vcc->dev->ops->send(vcc,skb);
488         return error ? error : size;
489 }
490
491
492 unsigned int atm_poll(struct file *file,struct socket *sock,poll_table *wait)
493 {
494         struct atm_vcc *vcc;
495         unsigned int mask;
496
497         vcc = ATM_SD(sock);
498         poll_wait(file,&vcc->sleep,wait);
499         mask = 0;
500         if (skb_peek(&vcc->recvq) || skb_peek(&vcc->listenq))
501                 mask |= POLLIN | POLLRDNORM;
502         if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
503             test_bit(ATM_VF_CLOSE,&vcc->flags))
504                 mask |= POLLHUP;
505         if (sock->state != SS_CONNECTING) {
506                 if (vcc->qos.txtp.traffic_class != ATM_NONE &&
507                     vcc->qos.txtp.max_sdu+atomic_read(&vcc->tx_inuse)+
508                     ATM_PDU_OVHD <= vcc->sk->sndbuf)
509                         mask |= POLLOUT | POLLWRNORM;
510         }
511         else if (vcc->reply != WAITING) {
512                         mask |= POLLOUT | POLLWRNORM;
513                         if (vcc->reply) mask |= POLLERR;
514                 }
515         return mask;
516 }
517
518
519 static void copy_aal_stats(struct k_atm_aal_stats *from,
520     struct atm_aal_stats *to)
521 {
522 #define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
523         __AAL_STAT_ITEMS
524 #undef __HANDLE_ITEM
525 }
526
527
528 static void subtract_aal_stats(struct k_atm_aal_stats *from,
529     struct atm_aal_stats *to)
530 {
531 #define __HANDLE_ITEM(i) atomic_sub(to->i,&from->i)
532         __AAL_STAT_ITEMS
533 #undef __HANDLE_ITEM
534 }
535
536
537 static int fetch_stats(struct atm_dev *dev,struct atm_dev_stats *arg,int zero)
538 {
539         struct atm_dev_stats tmp;
540         int error = 0;
541
542         copy_aal_stats(&dev->stats.aal0,&tmp.aal0);
543         copy_aal_stats(&dev->stats.aal34,&tmp.aal34);
544         copy_aal_stats(&dev->stats.aal5,&tmp.aal5);
545         if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
546         if (zero && !error) {
547                 subtract_aal_stats(&dev->stats.aal0,&tmp.aal0);
548                 subtract_aal_stats(&dev->stats.aal34,&tmp.aal34);
549                 subtract_aal_stats(&dev->stats.aal5,&tmp.aal5);
550         }
551         return error ? -EFAULT : 0;
552 }
553
554
555 int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
556 {
557         struct atm_dev *dev;
558         struct atm_vcc *vcc;
559         int *tmp_buf, *tmp_p;
560         void *buf;
561         int error,len,size,number, ret_val;
562
563         ret_val = 0;
564         spin_lock (&atm_dev_lock);
565         vcc = ATM_SD(sock);
566         switch (cmd) {
567                 case SIOCOUTQ:
568                         if (sock->state != SS_CONNECTED ||
569                             !test_bit(ATM_VF_READY,&vcc->flags)) {
570                                 ret_val =  -EINVAL;
571                                 goto done;
572                         }
573                         ret_val =  put_user(vcc->sk->sndbuf-
574                             atomic_read(&vcc->tx_inuse)-ATM_PDU_OVHD,
575                             (int *) arg) ? -EFAULT : 0;
576                         goto done;
577                 case SIOCINQ:
578                         {
579                                 struct sk_buff *skb;
580
581                                 if (sock->state != SS_CONNECTED) {
582                                         ret_val = -EINVAL;
583                                         goto done;
584                                 }
585                                 skb = skb_peek(&vcc->recvq);
586                                 ret_val = put_user(skb ? skb->len : 0,(int *) arg)
587                                     ? -EFAULT : 0;
588                                 goto done;
589                         }
590                 case ATM_GETNAMES:
591                         if (get_user(buf,
592                                      &((struct atm_iobuf *) arg)->buffer)) {
593                                 ret_val = -EFAULT;
594                                 goto done;
595                         }
596                         if (get_user(len,
597                                      &((struct atm_iobuf *) arg)->length)) {
598                                 ret_val = -EFAULT;
599                                 goto done;
600                         }
601                         size = 0;
602                         for (dev = atm_devs; dev; dev = dev->next)
603                                 size += sizeof(int);
604                         if (size > len) {
605                                 ret_val = -E2BIG;
606                                 goto done;
607                         }
608                         tmp_buf = kmalloc(size,GFP_KERNEL);
609                         if (!tmp_buf) {
610                                 ret_val = -ENOMEM;
611                                 goto done;
612                         }
613                         tmp_p = tmp_buf;
614                         for (dev = atm_devs; dev; dev = dev->next)
615                                 *tmp_p++ = dev->number;
616                         ret_val = ((copy_to_user(buf, tmp_buf, size)) ||
617                             put_user(size, &((struct atm_iobuf *) arg)->length)
618                             ) ? -EFAULT : 0;
619                         kfree(tmp_buf);
620                         goto done;
621                 case SIOCGSTAMP: /* borrowed from IP */
622                         if (!vcc->timestamp.tv_sec) {
623                                 ret_val = -ENOENT;
624                                 goto done;
625                         }
626                         vcc->timestamp.tv_sec += vcc->timestamp.tv_usec/1000000;
627                         vcc->timestamp.tv_usec %= 1000000;
628                         ret_val = copy_to_user((void *) arg,&vcc->timestamp,
629                             sizeof(struct timeval)) ? -EFAULT : 0;
630                         goto done;
631                 case ATM_SETSC:
632                         printk(KERN_WARNING "ATM_SETSC is obsolete\n");
633                         ret_val = 0;
634                         goto done;
635                 case ATMSIGD_CTRL:
636                         if (!capable(CAP_NET_ADMIN)) {
637                                 ret_val = -EPERM;
638                                 goto done;
639                         }
640                         /*
641                          * The user/kernel protocol for exchanging signalling
642                          * info uses kernel pointers as opaque references,
643                          * so the holder of the file descriptor can scribble
644                          * on the kernel... so we should make sure that we
645                          * have the same privledges that /proc/kcore needs
646                          */
647                         if (!capable(CAP_SYS_RAWIO)) {
648                                 ret_val = -EPERM;
649                                 goto done;
650                         }
651                         error = sigd_attach(vcc);
652                         if (!error) sock->state = SS_CONNECTED;
653                         ret_val = error;
654                         goto done;
655 #ifdef CONFIG_ATM_CLIP
656                 case SIOCMKCLIP:
657                         if (!capable(CAP_NET_ADMIN))
658                                 ret_val = -EPERM;
659                         else 
660                                 ret_val = clip_create(arg);
661                         goto done;
662                 case ATMARPD_CTRL:
663                         if (!capable(CAP_NET_ADMIN)) {
664                                 ret_val = -EPERM;
665                                 goto done;
666                         }
667                         error = atm_init_atmarp(vcc);
668                         if (!error) sock->state = SS_CONNECTED;
669                         ret_val = error;
670                         goto done;
671                 case ATMARP_MKIP:
672                         if (!capable(CAP_NET_ADMIN)) 
673                                 ret_val = -EPERM;
674                         else 
675                                 ret_val = clip_mkip(vcc,arg);
676                         goto done;
677                 case ATMARP_SETENTRY:
678                         if (!capable(CAP_NET_ADMIN)) 
679                                 ret_val = -EPERM;
680                         else
681                                 ret_val = clip_setentry(vcc,arg);
682                         goto done;
683                 case ATMARP_ENCAP:
684                         if (!capable(CAP_NET_ADMIN)) 
685                                 ret_val = -EPERM;
686                         else
687                                 ret_val = clip_encap(vcc,arg);
688                         goto done;
689 #endif
690 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
691                 case ATMLEC_CTRL:
692                         if (!capable(CAP_NET_ADMIN)) {
693                                 ret_val = -EPERM;
694                                 goto done;
695                         }
696                         if (atm_lane_ops.lecd_attach == NULL)
697                                 atm_lane_init();
698                         if (atm_lane_ops.lecd_attach == NULL) { /* try again */
699                                 ret_val = -ENOSYS;
700                                 goto done;
701                         }
702                         error = atm_lane_ops.lecd_attach(vcc, (int)arg);
703                         if (error >= 0) sock->state = SS_CONNECTED;
704                         ret_val =  error;
705                         goto done;
706                 case ATMLEC_MCAST:
707                         if (!capable(CAP_NET_ADMIN))
708                                 ret_val = -EPERM;
709                         else
710                                 ret_val = atm_lane_ops.mcast_attach(vcc, (int)arg);
711                         goto done;
712                 case ATMLEC_DATA:
713                         if (!capable(CAP_NET_ADMIN))
714                                 ret_val = -EPERM;
715                         else
716                                 ret_val = atm_lane_ops.vcc_attach(vcc, (void*)arg);
717                         goto done;
718 #endif
719 #if defined(CONFIG_ATM_MPOA) || defined(CONFIG_ATM_MPOA_MODULE)
720                 case ATMMPC_CTRL:
721                         if (!capable(CAP_NET_ADMIN)) {
722                                 ret_val = -EPERM;
723                                 goto done;
724                         }
725                         if (atm_mpoa_ops.mpoad_attach == NULL)
726                                 atm_mpoa_init();
727                         if (atm_mpoa_ops.mpoad_attach == NULL) { /* try again */
728                                 ret_val = -ENOSYS;
729                                 goto done;
730                         }
731                         error = atm_mpoa_ops.mpoad_attach(vcc, (int)arg);
732                         if (error >= 0) sock->state = SS_CONNECTED;
733                         ret_val = error;
734                         goto done;
735                 case ATMMPC_DATA:
736                         if (!capable(CAP_NET_ADMIN)) 
737                                 ret_val = -EPERM;
738                         else
739                                 ret_val = atm_mpoa_ops.vcc_attach(vcc, arg);
740                         goto done;
741 #endif
742 #if defined(CONFIG_ATM_TCP) || defined(CONFIG_ATM_TCP_MODULE)
743                 case SIOCSIFATMTCP:
744                         if (!capable(CAP_NET_ADMIN)) {
745                                 ret_val = -EPERM;
746                                 goto done;
747                         }
748                         if (!atm_tcp_ops.attach) {
749                                 ret_val = -ENOPKG;
750                                 goto done;
751                         }
752                         fops_get (&atm_tcp_ops);
753                         error = atm_tcp_ops.attach(vcc,(int) arg);
754                         if (error >= 0) sock->state = SS_CONNECTED;
755                         else            fops_put (&atm_tcp_ops);
756                         ret_val = error;
757                         goto done;
758                 case ATMTCP_CREATE:
759                         if (!capable(CAP_NET_ADMIN)) {
760                                 ret_val = -EPERM;
761                                 goto done;
762                         }
763                         if (!atm_tcp_ops.create_persistent) {
764                                 ret_val = -ENOPKG;
765                                 goto done;
766                         }
767                         error = atm_tcp_ops.create_persistent((int) arg);
768                         if (error < 0) fops_put (&atm_tcp_ops);
769                         ret_val = error;
770                         goto done;
771                 case ATMTCP_REMOVE:
772                         if (!capable(CAP_NET_ADMIN)) {
773                                 ret_val = -EPERM;
774                                 goto done;
775                         }
776                         if (!atm_tcp_ops.remove_persistent) {
777                                 ret_val = -ENOPKG;
778                                 goto done;
779                         }
780                         error = atm_tcp_ops.remove_persistent((int) arg);
781                         fops_put (&atm_tcp_ops);
782                         ret_val = error;
783                         goto done;
784 #endif
785                 default:
786                         break;
787         }
788 #if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE)
789         if (pppoatm_ioctl_hook) {
790                 ret_val = pppoatm_ioctl_hook(vcc, cmd, arg);
791                 if (ret_val != -ENOIOCTLCMD)
792                         goto done;
793         }
794 #endif
795 #if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
796         if (br2684_ioctl_hook) {
797                 ret_val = br2684_ioctl_hook(vcc, cmd, arg);
798                 if (ret_val != -ENOIOCTLCMD)
799                         goto done;
800         }
801 #endif
802
803         if (get_user(buf,&((struct atmif_sioc *) arg)->arg)) {
804                 ret_val = -EFAULT;
805                 goto done;
806         }
807         if (get_user(len,&((struct atmif_sioc *) arg)->length)) {
808                 ret_val = -EFAULT;
809                 goto done;
810         }
811         if (get_user(number,&((struct atmif_sioc *) arg)->number)) {
812                 ret_val = -EFAULT;
813                 goto done;
814         }
815         if (!(dev = atm_find_dev(number))) {
816                 ret_val = -ENODEV;
817                 goto done;
818         }
819         
820         size = 0;
821         switch (cmd) {
822                 case ATM_GETTYPE:
823                         size = strlen(dev->type)+1;
824                         if (copy_to_user(buf,dev->type,size)) {
825                                 ret_val = -EFAULT;
826                                 goto done;
827                         }
828                         break;
829                 case ATM_GETESI:
830                         size = ESI_LEN;
831                         if (copy_to_user(buf,dev->esi,size)) {
832                                 ret_val = -EFAULT;
833                                 goto done;
834                         }
835                         break;
836                 case ATM_SETESI:
837                         {
838                                 int i;
839
840                                 for (i = 0; i < ESI_LEN; i++)
841                                         if (dev->esi[i]) {
842                                                 ret_val = -EEXIST;
843                                                 goto done;
844                                         }
845                         }
846                         /* fall through */
847                 case ATM_SETESIF:
848                         {
849                                 unsigned char esi[ESI_LEN];
850
851                                 if (!capable(CAP_NET_ADMIN)) {
852                                         ret_val = -EPERM;
853                                         goto done;
854                                 }
855                                 if (copy_from_user(esi,buf,ESI_LEN)) {
856                                         ret_val = -EFAULT;
857                                         goto done;
858                                 }
859                                 memcpy(dev->esi,esi,ESI_LEN);
860                                 ret_val =  ESI_LEN;
861                                 goto done;
862                         }
863                 case ATM_GETSTATZ:
864                         if (!capable(CAP_NET_ADMIN)) {
865                                 ret_val = -EPERM;
866                                 goto done;
867                         }
868                         /* fall through */
869                 case ATM_GETSTAT:
870                         size = sizeof(struct atm_dev_stats);
871                         error = fetch_stats(dev,buf,cmd == ATM_GETSTATZ);
872                         if (error) {
873                                 ret_val = error;
874                                 goto done;
875                         }
876                         break;
877                 case ATM_GETCIRANGE:
878                         size = sizeof(struct atm_cirange);
879                         if (copy_to_user(buf,&dev->ci_range,size)) {
880                                 ret_val = -EFAULT;
881                                 goto done;
882                         }
883                         break;
884                 case ATM_GETLINKRATE:
885                         size = sizeof(int);
886                         if (copy_to_user(buf,&dev->link_rate,size)) {
887                                 ret_val = -EFAULT;
888                                 goto done;
889                         }
890                         break;
891                 case ATM_RSTADDR:
892                         if (!capable(CAP_NET_ADMIN)) {
893                                 ret_val = -EPERM;
894                                 goto done;
895                         }
896                         atm_reset_addr(dev);
897                         break;
898                 case ATM_ADDADDR:
899                 case ATM_DELADDR:
900                         if (!capable(CAP_NET_ADMIN)) {
901                                 ret_val = -EPERM;
902                                 goto done;
903                         }
904                         {
905                                 struct sockaddr_atmsvc addr;
906
907                                 if (copy_from_user(&addr,buf,sizeof(addr))) {
908                                         ret_val = -EFAULT;
909                                         goto done;
910                                 }
911                                 if (cmd == ATM_ADDADDR)
912                                         ret_val = atm_add_addr(dev,&addr);
913                                 else
914                                         ret_val = atm_del_addr(dev,&addr);
915                                 goto done;
916                         }
917                 case ATM_GETADDR:
918                         size = atm_get_addr(dev,buf,len);
919                         if (size < 0)
920                                 ret_val = size;
921                         else
922                         /* may return 0, but later on size == 0 means "don't
923                            write the length" */
924                                 ret_val = put_user(size,
925                                                    &((struct atmif_sioc *) arg)->length) ? -EFAULT : 0;
926                         goto done;
927                 case ATM_SETLOOP:
928                         if (__ATM_LM_XTRMT((int) (long) buf) &&
929                             __ATM_LM_XTLOC((int) (long) buf) >
930                             __ATM_LM_XTRMT((int) (long) buf)) {
931                                 ret_val = -EINVAL;
932                                 goto done;
933                         }
934                         /* fall through */
935                 case ATM_SETCIRANGE:
936                 case SONET_GETSTATZ:
937                 case SONET_SETDIAG:
938                 case SONET_CLRDIAG:
939                 case SONET_SETFRAMING:
940                         if (!capable(CAP_NET_ADMIN)) {
941                                 ret_val = -EPERM;
942                                 goto done;
943                         }
944                         /* fall through */
945                 default:
946                         if (!dev->ops->ioctl) {
947                                 ret_val = -EINVAL;
948                                 goto done;
949                         }
950                         size = dev->ops->ioctl(dev,cmd,buf);
951                         if (size < 0) {
952                                 ret_val = (size == -ENOIOCTLCMD ? -EINVAL : size);
953                                 goto done;
954                         }
955         }
956         
957         if (size)
958                 ret_val =  put_user(size,&((struct atmif_sioc *) arg)->length) ?
959                         -EFAULT : 0;
960         else
961                 ret_val = 0;
962
963  done:
964         spin_unlock (&atm_dev_lock); 
965         return ret_val;
966 }
967
968
969 static int atm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
970 {
971         int error;
972
973         /*
974          * Don't let the QoS change the already connected AAL type nor the
975          * traffic class.
976          */
977         if (qos->aal != vcc->qos.aal ||
978             qos->rxtp.traffic_class != vcc->qos.rxtp.traffic_class ||
979             qos->txtp.traffic_class != vcc->qos.txtp.traffic_class)
980                 return -EINVAL;
981         error = adjust_tp(&qos->txtp,qos->aal);
982         if (!error) error = adjust_tp(&qos->rxtp,qos->aal);
983         if (error) return error;
984         if (!vcc->dev->ops->change_qos) return -EOPNOTSUPP;
985         if (vcc->family == AF_ATMPVC)
986                 return vcc->dev->ops->change_qos(vcc,qos,ATM_MF_SET);
987         return svc_change_qos(vcc,qos);
988 }
989
990
991 static int check_tp(struct atm_trafprm *tp)
992 {
993         /* @@@ Should be merged with adjust_tp */
994         if (!tp->traffic_class || tp->traffic_class == ATM_ANYCLASS) return 0;
995         if (tp->traffic_class != ATM_UBR && !tp->min_pcr && !tp->pcr &&
996             !tp->max_pcr) return -EINVAL;
997         if (tp->min_pcr == ATM_MAX_PCR) return -EINVAL;
998         if (tp->min_pcr && tp->max_pcr && tp->max_pcr != ATM_MAX_PCR &&
999             tp->min_pcr > tp->max_pcr) return -EINVAL;
1000         /*
1001          * We allow pcr to be outside [min_pcr,max_pcr], because later
1002          * adjustment may still push it in the valid range.
1003          */
1004         return 0;
1005 }
1006
1007
1008 static int check_qos(struct atm_qos *qos)
1009 {
1010         int error;
1011
1012         if (!qos->txtp.traffic_class && !qos->rxtp.traffic_class)
1013                 return -EINVAL;
1014         if (qos->txtp.traffic_class != qos->rxtp.traffic_class &&
1015             qos->txtp.traffic_class && qos->rxtp.traffic_class &&
1016             qos->txtp.traffic_class != ATM_ANYCLASS &&
1017             qos->rxtp.traffic_class != ATM_ANYCLASS) return -EINVAL;
1018         error = check_tp(&qos->txtp);
1019         if (error) return error;
1020         return check_tp(&qos->rxtp);
1021 }
1022
1023
1024 static int atm_do_setsockopt(struct socket *sock,int level,int optname,
1025     void *optval,int optlen)
1026 {
1027         struct atm_vcc *vcc;
1028         unsigned long value;
1029         int error;
1030
1031         vcc = ATM_SD(sock);
1032         switch (optname) {
1033                 case SO_ATMQOS:
1034                         {
1035                                 struct atm_qos qos;
1036
1037                                 if (copy_from_user(&qos,optval,sizeof(qos)))
1038                                         return -EFAULT;
1039                                 error = check_qos(&qos);
1040                                 if (error) return error;
1041                                 if (sock->state == SS_CONNECTED)
1042                                         return atm_change_qos(vcc,&qos);
1043                                 if (sock->state != SS_UNCONNECTED)
1044                                         return -EBADFD;
1045                                 vcc->qos = qos;
1046                                 set_bit(ATM_VF_HASQOS,&vcc->flags);
1047                                 return 0;
1048                         }
1049                 case SO_SETCLP:
1050                         if (get_user(value,(unsigned long *) optval))
1051                                 return -EFAULT;
1052                         if (value) vcc->atm_options |= ATM_ATMOPT_CLP;
1053                         else vcc->atm_options &= ~ATM_ATMOPT_CLP;
1054                         return 0;
1055                 default:
1056                         if (level == SOL_SOCKET) return -EINVAL;
1057                         break;
1058         }
1059         if (!vcc->dev || !vcc->dev->ops->setsockopt) return -EINVAL;
1060         return vcc->dev->ops->setsockopt(vcc,level,optname,optval,optlen);
1061 }
1062
1063
1064 static int atm_do_getsockopt(struct socket *sock,int level,int optname,
1065     void *optval,int optlen)
1066 {
1067         struct atm_vcc *vcc;
1068
1069         vcc = ATM_SD(sock);
1070         switch (optname) {
1071                 case SO_ATMQOS:
1072                         if (!test_bit(ATM_VF_HASQOS,&vcc->flags))
1073                                 return -EINVAL;
1074                         return copy_to_user(optval,&vcc->qos,sizeof(vcc->qos)) ?
1075                             -EFAULT : 0;
1076                 case SO_SETCLP:
1077                         return put_user(vcc->atm_options & ATM_ATMOPT_CLP ? 1 :
1078                           0,(unsigned long *) optval) ? -EFAULT : 0;
1079                 case SO_ATMPVC:
1080                         {
1081                                 struct sockaddr_atmpvc pvc;
1082
1083                                 if (!vcc->dev ||
1084                                     !test_bit(ATM_VF_ADDR,&vcc->flags))
1085                                         return -ENOTCONN;
1086                                 pvc.sap_family = AF_ATMPVC;
1087                                 pvc.sap_addr.itf = vcc->dev->number;
1088                                 pvc.sap_addr.vpi = vcc->vpi;
1089                                 pvc.sap_addr.vci = vcc->vci;
1090                                 return copy_to_user(optval,&pvc,sizeof(pvc)) ?
1091                                     -EFAULT : 0;
1092                         }
1093                 default:
1094                         if (level == SOL_SOCKET) return -EINVAL;
1095                         break;
1096         }
1097         if (!vcc->dev || !vcc->dev->ops->getsockopt) return -EINVAL;
1098         return vcc->dev->ops->getsockopt(vcc,level,optname,optval,optlen);
1099 }
1100
1101
1102 int atm_setsockopt(struct socket *sock,int level,int optname,char *optval,
1103     int optlen)
1104 {
1105         if (__SO_LEVEL_MATCH(optname, level) && optlen != __SO_SIZE(optname))
1106                 return -EINVAL;
1107         return atm_do_setsockopt(sock,level,optname,optval,optlen);
1108 }
1109
1110
1111 int atm_getsockopt(struct socket *sock,int level,int optname,
1112     char *optval,int *optlen)
1113 {
1114         int len;
1115
1116         if (get_user(len,optlen)) return -EFAULT;
1117         if (__SO_LEVEL_MATCH(optname, level) && len != __SO_SIZE(optname))
1118                 return -EINVAL;
1119         return atm_do_getsockopt(sock,level,optname,optval,len);
1120 }
1121
1122
1123 /*
1124  * lane_mpoa_init.c: A couple of helper functions
1125  * to make modular LANE and MPOA client easier to implement
1126  */
1127
1128 /*
1129  * This is how it goes:
1130  *
1131  * if xxxx is not compiled as module, call atm_xxxx_init_ops()
1132  *    from here
1133  * else call atm_mpoa_init_ops() from init_module() within
1134  *    the kernel when xxxx module is loaded
1135  *
1136  * In either case function pointers in struct atm_xxxx_ops
1137  * are initialized to their correct values. Either they
1138  * point to functions in the module or in the kernel
1139  */
1140  
1141 extern struct atm_mpoa_ops atm_mpoa_ops; /* in common.c */
1142 extern struct atm_lane_ops atm_lane_ops; /* in common.c */
1143
1144 #if defined(CONFIG_ATM_MPOA) || defined(CONFIG_ATM_MPOA_MODULE)
1145 void atm_mpoa_init(void)
1146 {
1147 #ifndef CONFIG_ATM_MPOA_MODULE /* not module */
1148         atm_mpoa_init_ops(&atm_mpoa_ops);
1149 #else
1150         request_module("mpoa");
1151 #endif
1152
1153         return;
1154 }
1155 #endif
1156
1157 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
1158 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
1159 struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
1160                                                 unsigned char *addr) = NULL;
1161 void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent) = NULL;
1162 #if defined(CONFIG_ATM_LANE_MODULE) || defined(CONFIG_BRIDGE_MODULE)
1163 EXPORT_SYMBOL(br_fdb_get_hook);
1164 EXPORT_SYMBOL(br_fdb_put_hook);
1165 #endif /* defined(CONFIG_ATM_LANE_MODULE) || defined(CONFIG_BRIDGE_MODULE) */
1166 #endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
1167
1168 void atm_lane_init(void)
1169 {
1170 #ifndef CONFIG_ATM_LANE_MODULE /* not module */
1171         atm_lane_init_ops(&atm_lane_ops);
1172 #else
1173         request_module("lec");
1174 #endif
1175
1176         return;
1177 }        
1178 #endif