[NET]: sem2mutex part 2
[linux-2.6.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 proto_ops */
10 #include <linux/atm.h>          /* ATM stuff */
11 #include <linux/atmdev.h>
12 #include <linux/socket.h>       /* SOL_SOCKET */
13 #include <linux/errno.h>        /* error codes */
14 #include <linux/capability.h>
15 #include <linux/mm.h>
16 #include <linux/sched.h>
17 #include <linux/time.h>         /* struct timeval */
18 #include <linux/skbuff.h>
19 #include <linux/bitops.h>
20 #include <linux/init.h>
21 #include <net/sock.h>           /* struct sock */
22
23 #include <asm/uaccess.h>
24 #include <asm/atomic.h>
25 #include <asm/poll.h>
26
27
28 #include "resources.h"          /* atm_find_dev */
29 #include "common.h"             /* prototypes */
30 #include "protocols.h"          /* atm_init_<transport> */
31 #include "addr.h"               /* address registry */
32 #include "signaling.h"          /* for WAITING and sigd_attach */
33
34
35 #if 0
36 #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
37 #else
38 #define DPRINTK(format,args...)
39 #endif
40
41 struct hlist_head vcc_hash[VCC_HTABLE_SIZE];
42 DEFINE_RWLOCK(vcc_sklist_lock);
43
44 static void __vcc_insert_socket(struct sock *sk)
45 {
46         struct atm_vcc *vcc = atm_sk(sk);
47         struct hlist_head *head = &vcc_hash[vcc->vci &
48                                         (VCC_HTABLE_SIZE - 1)];
49         sk->sk_hash = vcc->vci & (VCC_HTABLE_SIZE - 1);
50         sk_add_node(sk, head);
51 }
52
53 void vcc_insert_socket(struct sock *sk)
54 {
55         write_lock_irq(&vcc_sklist_lock);
56         __vcc_insert_socket(sk);
57         write_unlock_irq(&vcc_sklist_lock);
58 }
59
60 static void vcc_remove_socket(struct sock *sk)
61 {
62         write_lock_irq(&vcc_sklist_lock);
63         sk_del_node_init(sk);
64         write_unlock_irq(&vcc_sklist_lock);
65 }
66
67
68 static struct sk_buff *alloc_tx(struct atm_vcc *vcc,unsigned int size)
69 {
70         struct sk_buff *skb;
71         struct sock *sk = sk_atm(vcc);
72
73         if (atomic_read(&sk->sk_wmem_alloc) && !atm_may_send(vcc, size)) {
74                 DPRINTK("Sorry: wmem_alloc = %d, size = %d, sndbuf = %d\n",
75                         atomic_read(&sk->sk_wmem_alloc), size,
76                         sk->sk_sndbuf);
77                 return NULL;
78         }
79         while (!(skb = alloc_skb(size,GFP_KERNEL))) schedule();
80         DPRINTK("AlTx %d += %d\n", atomic_read(&sk->sk_wmem_alloc),
81                 skb->truesize);
82         atomic_add(skb->truesize, &sk->sk_wmem_alloc);
83         return skb;
84 }
85
86
87 EXPORT_SYMBOL(vcc_hash);
88 EXPORT_SYMBOL(vcc_sklist_lock);
89 EXPORT_SYMBOL(vcc_insert_socket);
90
91 static void vcc_sock_destruct(struct sock *sk)
92 {
93         if (atomic_read(&sk->sk_rmem_alloc))
94                 printk(KERN_DEBUG "vcc_sock_destruct: rmem leakage (%d bytes) detected.\n", atomic_read(&sk->sk_rmem_alloc));
95
96         if (atomic_read(&sk->sk_wmem_alloc))
97                 printk(KERN_DEBUG "vcc_sock_destruct: wmem leakage (%d bytes) detected.\n", atomic_read(&sk->sk_wmem_alloc));
98 }
99
100 static void vcc_def_wakeup(struct sock *sk)
101 {
102         read_lock(&sk->sk_callback_lock);
103         if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
104                 wake_up(sk->sk_sleep);
105         read_unlock(&sk->sk_callback_lock);
106 }
107
108 static inline int vcc_writable(struct sock *sk)
109 {
110         struct atm_vcc *vcc = atm_sk(sk);
111
112         return (vcc->qos.txtp.max_sdu +
113                 atomic_read(&sk->sk_wmem_alloc)) <= sk->sk_sndbuf;
114 }
115
116 static void vcc_write_space(struct sock *sk)
117 {       
118         read_lock(&sk->sk_callback_lock);
119
120         if (vcc_writable(sk)) {
121                 if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
122                         wake_up_interruptible(sk->sk_sleep);
123
124                 sk_wake_async(sk, 2, POLL_OUT);
125         }
126
127         read_unlock(&sk->sk_callback_lock);
128 }
129
130 static struct proto vcc_proto = {
131         .name     = "VCC",
132         .owner    = THIS_MODULE,
133         .obj_size = sizeof(struct atm_vcc),
134 };
135  
136 int vcc_create(struct socket *sock, int protocol, int family)
137 {
138         struct sock *sk;
139         struct atm_vcc *vcc;
140
141         sock->sk = NULL;
142         if (sock->type == SOCK_STREAM)
143                 return -EINVAL;
144         sk = sk_alloc(family, GFP_KERNEL, &vcc_proto, 1);
145         if (!sk)
146                 return -ENOMEM;
147         sock_init_data(sock, sk);
148         sk->sk_state_change = vcc_def_wakeup;
149         sk->sk_write_space = vcc_write_space;
150
151         vcc = atm_sk(sk);
152         vcc->dev = NULL;
153         memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc));
154         memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc));
155         vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */
156         atomic_set(&sk->sk_wmem_alloc, 0);
157         atomic_set(&sk->sk_rmem_alloc, 0);
158         vcc->push = NULL;
159         vcc->pop = NULL;
160         vcc->push_oam = NULL;
161         vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */
162         vcc->atm_options = vcc->aal_options = 0;
163         sk->sk_destruct = vcc_sock_destruct;
164         return 0;
165 }
166
167
168 static void vcc_destroy_socket(struct sock *sk)
169 {
170         struct atm_vcc *vcc = atm_sk(sk);
171         struct sk_buff *skb;
172
173         set_bit(ATM_VF_CLOSE, &vcc->flags);
174         clear_bit(ATM_VF_READY, &vcc->flags);
175         if (vcc->dev) {
176                 if (vcc->dev->ops->close)
177                         vcc->dev->ops->close(vcc);
178                 if (vcc->push)
179                         vcc->push(vcc, NULL); /* atmarpd has no push */
180
181                 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
182                         atm_return(vcc,skb->truesize);
183                         kfree_skb(skb);
184                 }
185
186                 module_put(vcc->dev->ops->owner);
187                 atm_dev_put(vcc->dev);
188         }
189
190         vcc_remove_socket(sk);
191 }
192
193
194 int vcc_release(struct socket *sock)
195 {
196         struct sock *sk = sock->sk;
197
198         if (sk) {
199                 lock_sock(sk);
200                 vcc_destroy_socket(sock->sk);
201                 release_sock(sk);
202                 sock_put(sk);
203         }
204
205         return 0;
206 }
207
208
209 void vcc_release_async(struct atm_vcc *vcc, int reply)
210 {
211         struct sock *sk = sk_atm(vcc);
212
213         set_bit(ATM_VF_CLOSE, &vcc->flags);
214         sk->sk_shutdown |= RCV_SHUTDOWN;
215         sk->sk_err = -reply;
216         clear_bit(ATM_VF_WAITING, &vcc->flags);
217         sk->sk_state_change(sk);
218 }
219
220
221 EXPORT_SYMBOL(vcc_release_async);
222
223
224 void atm_dev_release_vccs(struct atm_dev *dev)
225 {
226         int i;
227
228         write_lock_irq(&vcc_sklist_lock);
229         for (i = 0; i < VCC_HTABLE_SIZE; i++) {
230                 struct hlist_head *head = &vcc_hash[i];
231                 struct hlist_node *node, *tmp;
232                 struct sock *s;
233                 struct atm_vcc *vcc;
234
235                 sk_for_each_safe(s, node, tmp, head) {
236                         vcc = atm_sk(s);
237                         if (vcc->dev == dev) {
238                                 vcc_release_async(vcc, -EPIPE);
239                                 sk_del_node_init(s);
240                         }
241                 }
242         }
243         write_unlock_irq(&vcc_sklist_lock);
244 }
245
246
247 static int adjust_tp(struct atm_trafprm *tp,unsigned char aal)
248 {
249         int max_sdu;
250
251         if (!tp->traffic_class) return 0;
252         switch (aal) {
253                 case ATM_AAL0:
254                         max_sdu = ATM_CELL_SIZE-1;
255                         break;
256                 case ATM_AAL34:
257                         max_sdu = ATM_MAX_AAL34_PDU;
258                         break;
259                 default:
260                         printk(KERN_WARNING "ATM: AAL problems ... "
261                             "(%d)\n",aal);
262                         /* fall through */
263                 case ATM_AAL5:
264                         max_sdu = ATM_MAX_AAL5_PDU;
265         }
266         if (!tp->max_sdu) tp->max_sdu = max_sdu;
267         else if (tp->max_sdu > max_sdu) return -EINVAL;
268         if (!tp->max_cdv) tp->max_cdv = ATM_MAX_CDV;
269         return 0;
270 }
271
272
273 static int check_ci(struct atm_vcc *vcc, short vpi, int vci)
274 {
275         struct hlist_head *head = &vcc_hash[vci &
276                                         (VCC_HTABLE_SIZE - 1)];
277         struct hlist_node *node;
278         struct sock *s;
279         struct atm_vcc *walk;
280
281         sk_for_each(s, node, head) {
282                 walk = atm_sk(s);
283                 if (walk->dev != vcc->dev)
284                         continue;
285                 if (test_bit(ATM_VF_ADDR, &walk->flags) && walk->vpi == vpi &&
286                     walk->vci == vci && ((walk->qos.txtp.traffic_class !=
287                     ATM_NONE && vcc->qos.txtp.traffic_class != ATM_NONE) ||
288                     (walk->qos.rxtp.traffic_class != ATM_NONE &&
289                     vcc->qos.rxtp.traffic_class != ATM_NONE)))
290                         return -EADDRINUSE;
291         }
292
293         /* allow VCCs with same VPI/VCI iff they don't collide on
294            TX/RX (but we may refuse such sharing for other reasons,
295            e.g. if protocol requires to have both channels) */
296
297         return 0;
298 }
299
300
301 static int find_ci(struct atm_vcc *vcc, short *vpi, int *vci)
302 {
303         static short p;        /* poor man's per-device cache */
304         static int c;
305         short old_p;
306         int old_c;
307         int err;
308
309         if (*vpi != ATM_VPI_ANY && *vci != ATM_VCI_ANY) {
310                 err = check_ci(vcc, *vpi, *vci);
311                 return err;
312         }
313         /* last scan may have left values out of bounds for current device */
314         if (*vpi != ATM_VPI_ANY)
315                 p = *vpi;
316         else if (p >= 1 << vcc->dev->ci_range.vpi_bits)
317                 p = 0;
318         if (*vci != ATM_VCI_ANY)
319                 c = *vci;
320         else if (c < ATM_NOT_RSV_VCI || c >= 1 << vcc->dev->ci_range.vci_bits)
321                         c = ATM_NOT_RSV_VCI;
322         old_p = p;
323         old_c = c;
324         do {
325                 if (!check_ci(vcc, p, c)) {
326                         *vpi = p;
327                         *vci = c;
328                         return 0;
329                 }
330                 if (*vci == ATM_VCI_ANY) {
331                         c++;
332                         if (c >= 1 << vcc->dev->ci_range.vci_bits)
333                                 c = ATM_NOT_RSV_VCI;
334                 }
335                 if ((c == ATM_NOT_RSV_VCI || *vci != ATM_VCI_ANY) &&
336                     *vpi == ATM_VPI_ANY) {
337                         p++;
338                         if (p >= 1 << vcc->dev->ci_range.vpi_bits) p = 0;
339                 }
340         }
341         while (old_p != p || old_c != c);
342         return -EADDRINUSE;
343 }
344
345
346 static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, short vpi,
347                          int vci)
348 {
349         struct sock *sk = sk_atm(vcc);
350         int error;
351
352         if ((vpi != ATM_VPI_UNSPEC && vpi != ATM_VPI_ANY &&
353             vpi >> dev->ci_range.vpi_bits) || (vci != ATM_VCI_UNSPEC &&
354             vci != ATM_VCI_ANY && vci >> dev->ci_range.vci_bits))
355                 return -EINVAL;
356         if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE))
357                 return -EPERM;
358         error = -ENODEV;
359         if (!try_module_get(dev->ops->owner))
360                 return error;
361         vcc->dev = dev;
362         write_lock_irq(&vcc_sklist_lock);
363         if (test_bit(ATM_DF_REMOVED, &dev->flags) || 
364             (error = find_ci(vcc, &vpi, &vci))) {
365                 write_unlock_irq(&vcc_sklist_lock);
366                 goto fail_module_put;
367         }
368         vcc->vpi = vpi;
369         vcc->vci = vci;
370         __vcc_insert_socket(sk);
371         write_unlock_irq(&vcc_sklist_lock);
372         switch (vcc->qos.aal) {
373                 case ATM_AAL0:
374                         error = atm_init_aal0(vcc);
375                         vcc->stats = &dev->stats.aal0;
376                         break;
377                 case ATM_AAL34:
378                         error = atm_init_aal34(vcc);
379                         vcc->stats = &dev->stats.aal34;
380                         break;
381                 case ATM_NO_AAL:
382                         /* ATM_AAL5 is also used in the "0 for default" case */
383                         vcc->qos.aal = ATM_AAL5;
384                         /* fall through */
385                 case ATM_AAL5:
386                         error = atm_init_aal5(vcc);
387                         vcc->stats = &dev->stats.aal5;
388                         break;
389                 default:
390                         error = -EPROTOTYPE;
391         }
392         if (!error) error = adjust_tp(&vcc->qos.txtp,vcc->qos.aal);
393         if (!error) error = adjust_tp(&vcc->qos.rxtp,vcc->qos.aal);
394         if (error)
395                 goto fail;
396         DPRINTK("VCC %d.%d, AAL %d\n",vpi,vci,vcc->qos.aal);
397         DPRINTK("  TX: %d, PCR %d..%d, SDU %d\n",vcc->qos.txtp.traffic_class,
398             vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu);
399         DPRINTK("  RX: %d, PCR %d..%d, SDU %d\n",vcc->qos.rxtp.traffic_class,
400             vcc->qos.rxtp.min_pcr,vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu);
401
402         if (dev->ops->open) {
403                 if ((error = dev->ops->open(vcc)))
404                         goto fail;
405         }
406         return 0;
407
408 fail:
409         vcc_remove_socket(sk);
410 fail_module_put:
411         module_put(dev->ops->owner);
412         /* ensure we get dev module ref count correct */
413         vcc->dev = NULL;
414         return error;
415 }
416
417
418 int vcc_connect(struct socket *sock, int itf, short vpi, int vci)
419 {
420         struct atm_dev *dev;
421         struct atm_vcc *vcc = ATM_SD(sock);
422         int error;
423
424         DPRINTK("vcc_connect (vpi %d, vci %d)\n",vpi,vci);
425         if (sock->state == SS_CONNECTED)
426                 return -EISCONN;
427         if (sock->state != SS_UNCONNECTED)
428                 return -EINVAL;
429         if (!(vpi || vci))
430                 return -EINVAL;
431
432         if (vpi != ATM_VPI_UNSPEC && vci != ATM_VCI_UNSPEC)
433                 clear_bit(ATM_VF_PARTIAL,&vcc->flags);
434         else
435                 if (test_bit(ATM_VF_PARTIAL,&vcc->flags))
436                         return -EINVAL;
437         DPRINTK("vcc_connect (TX: cl %d,bw %d-%d,sdu %d; "
438             "RX: cl %d,bw %d-%d,sdu %d,AAL %s%d)\n",
439             vcc->qos.txtp.traffic_class,vcc->qos.txtp.min_pcr,
440             vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu,
441             vcc->qos.rxtp.traffic_class,vcc->qos.rxtp.min_pcr,
442             vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu,
443             vcc->qos.aal == ATM_AAL5 ? "" : vcc->qos.aal == ATM_AAL0 ? "" :
444             " ??? code ",vcc->qos.aal == ATM_AAL0 ? 0 : vcc->qos.aal);
445         if (!test_bit(ATM_VF_HASQOS, &vcc->flags))
446                 return -EBADFD;
447         if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
448             vcc->qos.rxtp.traffic_class == ATM_ANYCLASS)
449                 return -EINVAL;
450         if (likely(itf != ATM_ITF_ANY)) {
451                 dev = try_then_request_module(atm_dev_lookup(itf), "atm-device-%d", itf);
452         } else {
453                 dev = NULL;
454                 mutex_lock(&atm_dev_mutex);
455                 if (!list_empty(&atm_devs)) {
456                         dev = list_entry(atm_devs.next, struct atm_dev, dev_list);
457                         atm_dev_hold(dev);
458                 }
459                 mutex_unlock(&atm_dev_mutex);
460         }
461         if (!dev)
462                 return -ENODEV;
463         error = __vcc_connect(vcc, dev, vpi, vci);
464         if (error) {
465                 atm_dev_put(dev);
466                 return error;
467         }
468         if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
469                 set_bit(ATM_VF_PARTIAL,&vcc->flags);
470         if (test_bit(ATM_VF_READY,&ATM_SD(sock)->flags))
471                 sock->state = SS_CONNECTED;
472         return 0;
473 }
474
475
476 int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
477                 size_t size, int flags)
478 {
479         struct sock *sk = sock->sk;
480         struct atm_vcc *vcc;
481         struct sk_buff *skb;
482         int copied, error = -EINVAL;
483
484         if (sock->state != SS_CONNECTED)
485                 return -ENOTCONN;
486         if (flags & ~MSG_DONTWAIT)              /* only handle MSG_DONTWAIT */
487                 return -EOPNOTSUPP;
488         vcc = ATM_SD(sock);
489         if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
490             test_bit(ATM_VF_CLOSE,&vcc->flags) ||
491             !test_bit(ATM_VF_READY, &vcc->flags))
492                 return 0;
493
494         skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &error);
495         if (!skb)
496                 return error;
497
498         copied = skb->len; 
499         if (copied > size) {
500                 copied = size; 
501                 msg->msg_flags |= MSG_TRUNC;
502         }
503
504         error = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
505         if (error)
506                 return error;
507         sock_recv_timestamp(msg, sk, skb);
508         DPRINTK("RcvM %d -= %d\n", atomic_read(&sk->rmem_alloc), skb->truesize);
509         atm_return(vcc, skb->truesize);
510         skb_free_datagram(sk, skb);
511         return copied;
512 }
513
514
515 int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
516                 size_t total_len)
517 {
518         struct sock *sk = sock->sk;
519         DEFINE_WAIT(wait);
520         struct atm_vcc *vcc;
521         struct sk_buff *skb;
522         int eff,error;
523         const void __user *buff;
524         int size;
525
526         lock_sock(sk);
527         if (sock->state != SS_CONNECTED) {
528                 error = -ENOTCONN;
529                 goto out;
530         }
531         if (m->msg_name) {
532                 error = -EISCONN;
533                 goto out;
534         }
535         if (m->msg_iovlen != 1) {
536                 error = -ENOSYS; /* fix this later @@@ */
537                 goto out;
538         }
539         buff = m->msg_iov->iov_base;
540         size = m->msg_iov->iov_len;
541         vcc = ATM_SD(sock);
542         if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
543             test_bit(ATM_VF_CLOSE, &vcc->flags) ||
544             !test_bit(ATM_VF_READY, &vcc->flags)) {
545                 error = -EPIPE;
546                 send_sig(SIGPIPE, current, 0);
547                 goto out;
548         }
549         if (!size) {
550                 error = 0;
551                 goto out;
552         }
553         if (size < 0 || size > vcc->qos.txtp.max_sdu) {
554                 error = -EMSGSIZE;
555                 goto out;
556         }
557
558         eff = (size+3) & ~3; /* align to word boundary */
559         prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
560         error = 0;
561         while (!(skb = alloc_tx(vcc,eff))) {
562                 if (m->msg_flags & MSG_DONTWAIT) {
563                         error = -EAGAIN;
564                         break;
565                 }
566                 schedule();
567                 if (signal_pending(current)) {
568                         error = -ERESTARTSYS;
569                         break;
570                 }
571                 if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
572                     test_bit(ATM_VF_CLOSE,&vcc->flags) ||
573                     !test_bit(ATM_VF_READY,&vcc->flags)) {
574                         error = -EPIPE;
575                         send_sig(SIGPIPE, current, 0);
576                         break;
577                 }
578                 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
579         }
580         finish_wait(sk->sk_sleep, &wait);
581         if (error)
582                 goto out;
583         skb->dev = NULL; /* for paths shared with net_device interfaces */
584         ATM_SKB(skb)->atm_options = vcc->atm_options;
585         if (copy_from_user(skb_put(skb,size),buff,size)) {
586                 kfree_skb(skb);
587                 error = -EFAULT;
588                 goto out;
589         }
590         if (eff != size) memset(skb->data+size,0,eff-size);
591         error = vcc->dev->ops->send(vcc,skb);
592         error = error ? error : size;
593 out:
594         release_sock(sk);
595         return error;
596 }
597
598
599 unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
600 {
601         struct sock *sk = sock->sk;
602         struct atm_vcc *vcc;
603         unsigned int mask;
604
605         poll_wait(file, sk->sk_sleep, wait);
606         mask = 0;
607
608         vcc = ATM_SD(sock);
609
610         /* exceptional events */
611         if (sk->sk_err)
612                 mask = POLLERR;
613
614         if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
615             test_bit(ATM_VF_CLOSE, &vcc->flags))
616                 mask |= POLLHUP;
617
618         /* readable? */
619         if (!skb_queue_empty(&sk->sk_receive_queue))
620                 mask |= POLLIN | POLLRDNORM;
621
622         /* writable? */
623         if (sock->state == SS_CONNECTING &&
624             test_bit(ATM_VF_WAITING, &vcc->flags))
625                 return mask;
626
627         if (vcc->qos.txtp.traffic_class != ATM_NONE &&
628             vcc_writable(sk))
629                 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
630
631         return mask;
632 }
633
634
635 static int atm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
636 {
637         int error;
638
639         /*
640          * Don't let the QoS change the already connected AAL type nor the
641          * traffic class.
642          */
643         if (qos->aal != vcc->qos.aal ||
644             qos->rxtp.traffic_class != vcc->qos.rxtp.traffic_class ||
645             qos->txtp.traffic_class != vcc->qos.txtp.traffic_class)
646                 return -EINVAL;
647         error = adjust_tp(&qos->txtp,qos->aal);
648         if (!error) error = adjust_tp(&qos->rxtp,qos->aal);
649         if (error) return error;
650         if (!vcc->dev->ops->change_qos) return -EOPNOTSUPP;
651         if (sk_atm(vcc)->sk_family == AF_ATMPVC)
652                 return vcc->dev->ops->change_qos(vcc,qos,ATM_MF_SET);
653         return svc_change_qos(vcc,qos);
654 }
655
656
657 static int check_tp(struct atm_trafprm *tp)
658 {
659         /* @@@ Should be merged with adjust_tp */
660         if (!tp->traffic_class || tp->traffic_class == ATM_ANYCLASS) return 0;
661         if (tp->traffic_class != ATM_UBR && !tp->min_pcr && !tp->pcr &&
662             !tp->max_pcr) return -EINVAL;
663         if (tp->min_pcr == ATM_MAX_PCR) return -EINVAL;
664         if (tp->min_pcr && tp->max_pcr && tp->max_pcr != ATM_MAX_PCR &&
665             tp->min_pcr > tp->max_pcr) return -EINVAL;
666         /*
667          * We allow pcr to be outside [min_pcr,max_pcr], because later
668          * adjustment may still push it in the valid range.
669          */
670         return 0;
671 }
672
673
674 static int check_qos(struct atm_qos *qos)
675 {
676         int error;
677
678         if (!qos->txtp.traffic_class && !qos->rxtp.traffic_class)
679                 return -EINVAL;
680         if (qos->txtp.traffic_class != qos->rxtp.traffic_class &&
681             qos->txtp.traffic_class && qos->rxtp.traffic_class &&
682             qos->txtp.traffic_class != ATM_ANYCLASS &&
683             qos->rxtp.traffic_class != ATM_ANYCLASS) return -EINVAL;
684         error = check_tp(&qos->txtp);
685         if (error) return error;
686         return check_tp(&qos->rxtp);
687 }
688
689 int vcc_setsockopt(struct socket *sock, int level, int optname,
690                    char __user *optval, int optlen)
691 {
692         struct atm_vcc *vcc;
693         unsigned long value;
694         int error;
695
696         if (__SO_LEVEL_MATCH(optname, level) && optlen != __SO_SIZE(optname))
697                 return -EINVAL;
698
699         vcc = ATM_SD(sock);
700         switch (optname) {
701                 case SO_ATMQOS:
702                         {
703                                 struct atm_qos qos;
704
705                                 if (copy_from_user(&qos,optval,sizeof(qos)))
706                                         return -EFAULT;
707                                 error = check_qos(&qos);
708                                 if (error) return error;
709                                 if (sock->state == SS_CONNECTED)
710                                         return atm_change_qos(vcc,&qos);
711                                 if (sock->state != SS_UNCONNECTED)
712                                         return -EBADFD;
713                                 vcc->qos = qos;
714                                 set_bit(ATM_VF_HASQOS,&vcc->flags);
715                                 return 0;
716                         }
717                 case SO_SETCLP:
718                         if (get_user(value,(unsigned long __user *)optval))
719                                 return -EFAULT;
720                         if (value) vcc->atm_options |= ATM_ATMOPT_CLP;
721                         else vcc->atm_options &= ~ATM_ATMOPT_CLP;
722                         return 0;
723                 default:
724                         if (level == SOL_SOCKET) return -EINVAL;
725                         break;
726         }
727         if (!vcc->dev || !vcc->dev->ops->setsockopt) return -EINVAL;
728         return vcc->dev->ops->setsockopt(vcc,level,optname,optval,optlen);
729 }
730
731
732 int vcc_getsockopt(struct socket *sock, int level, int optname,
733                    char __user *optval, int __user *optlen)
734 {
735         struct atm_vcc *vcc;
736         int len;
737
738         if (get_user(len, optlen))
739                 return -EFAULT;
740         if (__SO_LEVEL_MATCH(optname, level) && len != __SO_SIZE(optname))
741                 return -EINVAL;
742
743         vcc = ATM_SD(sock);
744         switch (optname) {
745                 case SO_ATMQOS:
746                         if (!test_bit(ATM_VF_HASQOS,&vcc->flags))
747                                 return -EINVAL;
748                         return copy_to_user(optval,&vcc->qos,sizeof(vcc->qos)) ?
749                             -EFAULT : 0;
750                 case SO_SETCLP:
751                         return put_user(vcc->atm_options & ATM_ATMOPT_CLP ? 1 :
752                           0,(unsigned long __user *)optval) ? -EFAULT : 0;
753                 case SO_ATMPVC:
754                         {
755                                 struct sockaddr_atmpvc pvc;
756
757                                 if (!vcc->dev ||
758                                     !test_bit(ATM_VF_ADDR,&vcc->flags))
759                                         return -ENOTCONN;
760                                 pvc.sap_family = AF_ATMPVC;
761                                 pvc.sap_addr.itf = vcc->dev->number;
762                                 pvc.sap_addr.vpi = vcc->vpi;
763                                 pvc.sap_addr.vci = vcc->vci;
764                                 return copy_to_user(optval,&pvc,sizeof(pvc)) ?
765                                     -EFAULT : 0;
766                         }
767                 default:
768                         if (level == SOL_SOCKET) return -EINVAL;
769                         break;
770         }
771         if (!vcc->dev || !vcc->dev->ops->getsockopt) return -EINVAL;
772         return vcc->dev->ops->getsockopt(vcc, level, optname, optval, len);
773 }
774
775 static int __init atm_init(void)
776 {
777         int error;
778
779         if ((error = proto_register(&vcc_proto, 0)) < 0)
780                 goto out;
781
782         if ((error = atmpvc_init()) < 0) {
783                 printk(KERN_ERR "atmpvc_init() failed with %d\n", error);
784                 goto out_unregister_vcc_proto;
785         }
786         if ((error = atmsvc_init()) < 0) {
787                 printk(KERN_ERR "atmsvc_init() failed with %d\n", error);
788                 goto out_atmpvc_exit;
789         }
790         if ((error = atm_proc_init()) < 0) {
791                 printk(KERN_ERR "atm_proc_init() failed with %d\n",error);
792                 goto out_atmsvc_exit;
793         }
794 out:
795         return error;
796 out_atmsvc_exit:
797         atmsvc_exit();
798 out_atmpvc_exit:
799         atmsvc_exit();
800 out_unregister_vcc_proto:
801         proto_unregister(&vcc_proto);
802         goto out;
803 }
804
805 static void __exit atm_exit(void)
806 {
807         atm_proc_exit();
808         atmsvc_exit();
809         atmpvc_exit();
810         proto_unregister(&vcc_proto);
811 }
812
813 module_init(atm_init);
814 module_exit(atm_exit);
815
816 MODULE_LICENSE("GPL");
817 MODULE_ALIAS_NETPROTO(PF_ATMPVC);
818 MODULE_ALIAS_NETPROTO(PF_ATMSVC);