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