~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/atm/common.c

Version: ~ [ linux-5.6-rc7 ] ~ [ linux-5.5.11 ] ~ [ linux-5.4.27 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.112 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.174 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.217 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.217 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.82 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp