Lines Matching +full:vcc +full:- +full:p
1 // SPDX-License-Identifier: GPL-2.0
2 /* net/atm/svc.c - ATM SVC sockets */
4 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
46 static void svc_disconnect(struct atm_vcc *vcc) in svc_disconnect() argument
50 struct sock *sk = sk_atm(vcc); in svc_disconnect()
52 pr_debug("%p\n", vcc); in svc_disconnect()
53 if (test_bit(ATM_VF_REGIS, &vcc->flags)) { in svc_disconnect()
54 sigd_enq(vcc, as_close, NULL, NULL, NULL); in svc_disconnect()
57 if (test_bit(ATM_VF_RELEASED, &vcc->flags) || !sigd) in svc_disconnect()
63 /* beware - socket is still in use by atmsigd until the last in svc_disconnect()
65 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { in svc_disconnect()
66 atm_return(vcc, skb->truesize); in svc_disconnect()
68 sigd_enq2(NULL, as_reject, vcc, NULL, NULL, &vcc->qos, 0); in svc_disconnect()
71 clear_bit(ATM_VF_REGIS, &vcc->flags); in svc_disconnect()
77 struct sock *sk = sock->sk; in svc_release()
78 struct atm_vcc *vcc; in svc_release() local
81 vcc = ATM_SD(sock); in svc_release()
82 pr_debug("%p\n", vcc); in svc_release()
83 clear_bit(ATM_VF_READY, &vcc->flags); in svc_release()
85 * VCC pointer is used as a reference, in svc_release()
86 * so we must not free it (thereby subjecting it to re-use) in svc_release()
89 svc_disconnect(vcc); in svc_release()
99 struct sock *sk = sock->sk; in svc_bind()
101 struct atm_vcc *vcc; in svc_bind() local
105 return -EINVAL; in svc_bind()
107 if (sock->state == SS_CONNECTED) { in svc_bind()
108 error = -EISCONN; in svc_bind()
111 if (sock->state != SS_UNCONNECTED) { in svc_bind()
112 error = -EINVAL; in svc_bind()
115 vcc = ATM_SD(sock); in svc_bind()
117 if (addr->sas_family != AF_ATMSVC) { in svc_bind()
118 error = -EAFNOSUPPORT; in svc_bind()
121 clear_bit(ATM_VF_BOUND, &vcc->flags); in svc_bind()
124 if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) { in svc_bind()
125 error = -EBADFD; in svc_bind()
128 vcc->local = *addr; in svc_bind()
129 set_bit(ATM_VF_WAITING, &vcc->flags); in svc_bind()
130 sigd_enq(vcc, as_bind, NULL, NULL, &vcc->local); in svc_bind()
133 if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd) in svc_bind()
138 clear_bit(ATM_VF_REGIS, &vcc->flags); /* doesn't count */ in svc_bind()
140 error = -EUNATCH; in svc_bind()
143 if (!sk->sk_err) in svc_bind()
144 set_bit(ATM_VF_BOUND, &vcc->flags); in svc_bind()
145 error = -sk->sk_err; in svc_bind()
155 struct sock *sk = sock->sk; in svc_connect()
157 struct atm_vcc *vcc = ATM_SD(sock); in svc_connect() local
160 pr_debug("%p\n", vcc); in svc_connect()
163 error = -EINVAL; in svc_connect()
167 switch (sock->state) { in svc_connect()
169 error = -EINVAL; in svc_connect()
172 error = -EISCONN; in svc_connect()
175 if (test_bit(ATM_VF_WAITING, &vcc->flags)) { in svc_connect()
176 error = -EALREADY; in svc_connect()
179 sock->state = SS_UNCONNECTED; in svc_connect()
180 if (sk->sk_err) { in svc_connect()
181 error = -sk->sk_err; in svc_connect()
187 if (addr->sas_family != AF_ATMSVC) { in svc_connect()
188 error = -EAFNOSUPPORT; in svc_connect()
191 if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) { in svc_connect()
192 error = -EBADFD; in svc_connect()
195 if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS || in svc_connect()
196 vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) { in svc_connect()
197 error = -EINVAL; in svc_connect()
200 if (!vcc->qos.txtp.traffic_class && in svc_connect()
201 !vcc->qos.rxtp.traffic_class) { in svc_connect()
202 error = -EINVAL; in svc_connect()
205 vcc->remote = *addr; in svc_connect()
206 set_bit(ATM_VF_WAITING, &vcc->flags); in svc_connect()
207 sigd_enq(vcc, as_connect, NULL, NULL, &vcc->remote); in svc_connect()
209 sock->state = SS_CONNECTING; in svc_connect()
210 error = -EINPROGRESS; in svc_connect()
215 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { in svc_connect()
225 * Kernel ---close--> Demon in svc_connect()
226 * Kernel <--close--- Demon in svc_connect()
228 * Kernel ---close--> Demon in svc_connect()
229 * Kernel <--error--- Demon in svc_connect()
231 * Kernel ---close--> Demon in svc_connect()
232 * Kernel <--okay---- Demon in svc_connect()
233 * Kernel <--close--- Demon in svc_connect()
235 sigd_enq(vcc, as_close, NULL, NULL, NULL); in svc_connect()
236 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { in svc_connect()
241 if (!sk->sk_err) in svc_connect()
242 while (!test_bit(ATM_VF_RELEASED, &vcc->flags) && in svc_connect()
248 clear_bit(ATM_VF_REGIS, &vcc->flags); in svc_connect()
249 clear_bit(ATM_VF_RELEASED, &vcc->flags); in svc_connect()
250 clear_bit(ATM_VF_CLOSE, &vcc->flags); in svc_connect()
252 error = -EINTR; in svc_connect()
259 error = -EUNATCH; in svc_connect()
262 if (sk->sk_err) { in svc_connect()
263 error = -sk->sk_err; in svc_connect()
268 vcc->qos.txtp.max_pcr = SELECT_TOP_PCR(vcc->qos.txtp); in svc_connect()
269 vcc->qos.txtp.pcr = 0; in svc_connect()
270 vcc->qos.txtp.min_pcr = 0; in svc_connect()
272 error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci); in svc_connect()
274 sock->state = SS_CONNECTED; in svc_connect()
276 (void)svc_disconnect(vcc); in svc_connect()
285 struct sock *sk = sock->sk; in svc_listen()
286 struct atm_vcc *vcc = ATM_SD(sock); in svc_listen() local
289 pr_debug("%p\n", vcc); in svc_listen()
292 if (test_bit(ATM_VF_SESSION, &vcc->flags)) { in svc_listen()
293 error = -EINVAL; in svc_listen()
296 if (test_bit(ATM_VF_LISTEN, &vcc->flags)) { in svc_listen()
297 error = -EADDRINUSE; in svc_listen()
300 set_bit(ATM_VF_WAITING, &vcc->flags); in svc_listen()
301 sigd_enq(vcc, as_listen, NULL, NULL, &vcc->local); in svc_listen()
304 if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd) in svc_listen()
310 error = -EUNATCH; in svc_listen()
313 set_bit(ATM_VF_LISTEN, &vcc->flags); in svc_listen()
315 sk->sk_max_ack_backlog = backlog > 0 ? backlog : ATM_BACKLOG_DEFAULT; in svc_listen()
316 error = -sk->sk_err; in svc_listen()
325 struct sock *sk = sock->sk; in svc_accept()
340 pr_debug("%p -> %p\n", old_vcc, new_vcc); in svc_accept()
345 while (!(skb = skb_dequeue(&sk->sk_receive_queue)) && in svc_accept()
347 if (test_bit(ATM_VF_RELEASED, &old_vcc->flags)) in svc_accept()
349 if (test_bit(ATM_VF_CLOSE, &old_vcc->flags)) { in svc_accept()
350 error = -sk->sk_err; in svc_accept()
354 error = -EAGAIN; in svc_accept()
361 error = -ERESTARTSYS; in svc_accept()
371 error = -EUNATCH; in svc_accept()
374 msg = (struct atmsvc_msg *)skb->data; in svc_accept()
375 new_vcc->qos = msg->qos; in svc_accept()
376 set_bit(ATM_VF_HASQOS, &new_vcc->flags); in svc_accept()
377 new_vcc->remote = msg->svc; in svc_accept()
378 new_vcc->local = msg->local; in svc_accept()
379 new_vcc->sap = msg->sap; in svc_accept()
380 error = vcc_connect(newsock, msg->pvc.sap_addr.itf, in svc_accept()
381 msg->pvc.sap_addr.vpi, in svc_accept()
382 msg->pvc.sap_addr.vci); in svc_accept()
387 &old_vcc->qos, error); in svc_accept()
388 error = error == -EAGAIN ? -EBUSY : error; in svc_accept()
391 /* wait should be short, so we ignore the non-blocking flag */ in svc_accept()
392 set_bit(ATM_VF_WAITING, &new_vcc->flags); in svc_accept()
397 if (!test_bit(ATM_VF_WAITING, &new_vcc->flags) || !sigd) in svc_accept()
405 error = -EUNATCH; in svc_accept()
408 if (!sk_atm(new_vcc)->sk_err) in svc_accept()
410 if (sk_atm(new_vcc)->sk_err != ERESTARTSYS) { in svc_accept()
411 error = -sk_atm(new_vcc)->sk_err; in svc_accept()
415 newsock->state = SS_CONNECTED; in svc_accept()
427 memcpy(addr, peer ? &ATM_SD(sock)->remote : &ATM_SD(sock)->local, in svc_getname()
432 int svc_change_qos(struct atm_vcc *vcc, struct atm_qos *qos) in svc_change_qos() argument
434 struct sock *sk = sk_atm(vcc); in svc_change_qos()
437 set_bit(ATM_VF_WAITING, &vcc->flags); in svc_change_qos()
438 sigd_enq2(vcc, as_modify, NULL, NULL, &vcc->local, qos, 0); in svc_change_qos()
441 if (!test_bit(ATM_VF_WAITING, &vcc->flags) || in svc_change_qos()
442 test_bit(ATM_VF_RELEASED, &vcc->flags) || !sigd) { in svc_change_qos()
449 return -EUNATCH; in svc_change_qos()
450 return -sk->sk_err; in svc_change_qos()
456 struct sock *sk = sock->sk; in svc_setsockopt()
457 struct atm_vcc *vcc = ATM_SD(sock); in svc_setsockopt() local
464 error = -EINVAL; in svc_setsockopt()
467 if (copy_from_sockptr(&vcc->sap, optval, optlen)) { in svc_setsockopt()
468 error = -EFAULT; in svc_setsockopt()
471 set_bit(ATM_VF_HASSAP, &vcc->flags); in svc_setsockopt()
475 error = -EINVAL; in svc_setsockopt()
479 error = -EFAULT; in svc_setsockopt()
483 set_bit(ATM_VF_SESSION, &vcc->flags); in svc_setsockopt()
485 clear_bit(ATM_VF_SESSION, &vcc->flags); in svc_setsockopt()
487 error = -EINVAL; in svc_setsockopt()
501 struct sock *sk = sock->sk; in svc_getsockopt()
510 error = -EFAULT; in svc_getsockopt()
514 error = -EINVAL; in svc_getsockopt()
517 if (copy_to_user(optval, &ATM_SD(sock)->sap, sizeof(struct atm_sap))) { in svc_getsockopt()
518 error = -EFAULT; in svc_getsockopt()
530 struct sock *sk = sock->sk; in svc_addparty()
531 struct atm_vcc *vcc = ATM_SD(sock); in svc_addparty() local
535 set_bit(ATM_VF_WAITING, &vcc->flags); in svc_addparty()
536 sigd_enq(vcc, as_addparty, NULL, NULL, in svc_addparty()
539 error = -EINPROGRESS; in svc_addparty()
545 if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd) in svc_addparty()
550 error = -xchg(&sk->sk_err_soft, 0); in svc_addparty()
559 struct sock *sk = sock->sk; in svc_dropparty()
560 struct atm_vcc *vcc = ATM_SD(sock); in svc_dropparty() local
564 set_bit(ATM_VF_WAITING, &vcc->flags); in svc_dropparty()
565 sigd_enq2(vcc, as_dropparty, NULL, NULL, NULL, NULL, ep_ref); in svc_dropparty()
568 if (!test_bit(ATM_VF_WAITING, &vcc->flags) || !sigd) in svc_dropparty()
574 error = -EUNATCH; in svc_dropparty()
577 error = -xchg(&sk->sk_err_soft, 0); in svc_dropparty()
587 struct atm_vcc *vcc = ATM_SD(sock); in svc_ioctl() local
591 if (!test_bit(ATM_VF_SESSION, &vcc->flags)) in svc_ioctl()
592 return -EINVAL; in svc_ioctl()
594 return -EFAULT; in svc_ioctl()
599 if (!test_bit(ATM_VF_SESSION, &vcc->flags)) in svc_ioctl()
600 return -EINVAL; in svc_ioctl()
602 return -EFAULT; in svc_ioctl()
662 return -EAFNOSUPPORT; in svc_create()
664 sock->ops = &svc_proto_ops; in svc_create()
668 ATM_SD(sock)->local.sas_family = AF_ATMSVC; in svc_create()
669 ATM_SD(sock)->remote.sas_family = AF_ATMSVC; in svc_create()