Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/atm/pvc.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0
2
/* net/atm/pvc.c - ATM PVC sockets */
3
4
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
5
6
7
#include <linux/net.h> /* struct socket, struct proto_ops */
8
#include <linux/atm.h> /* ATM stuff */
9
#include <linux/atmdev.h> /* ATM devices */
10
#include <linux/errno.h> /* error codes */
11
#include <linux/kernel.h> /* printk */
12
#include <linux/init.h>
13
#include <linux/skbuff.h>
14
#include <linux/bitops.h>
15
#include <linux/export.h>
16
#include <net/sock.h> /* for sock_no_* */
17
18
#include "resources.h" /* devs and vccs */
19
#include "common.h" /* common for PVCs and SVCs */
20
21
22
static int pvc_shutdown(struct socket *sock, int how)
23
{
24
return 0;
25
}
26
27
static int pvc_bind(struct socket *sock, struct sockaddr *sockaddr,
28
int sockaddr_len)
29
{
30
struct sock *sk = sock->sk;
31
struct sockaddr_atmpvc *addr;
32
struct atm_vcc *vcc;
33
int error;
34
35
if (sockaddr_len != sizeof(struct sockaddr_atmpvc))
36
return -EINVAL;
37
addr = (struct sockaddr_atmpvc *)sockaddr;
38
if (addr->sap_family != AF_ATMPVC)
39
return -EAFNOSUPPORT;
40
lock_sock(sk);
41
vcc = ATM_SD(sock);
42
if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) {
43
error = -EBADFD;
44
goto out;
45
}
46
if (test_bit(ATM_VF_PARTIAL, &vcc->flags)) {
47
if (vcc->vpi != ATM_VPI_UNSPEC)
48
addr->sap_addr.vpi = vcc->vpi;
49
if (vcc->vci != ATM_VCI_UNSPEC)
50
addr->sap_addr.vci = vcc->vci;
51
}
52
error = vcc_connect(sock, addr->sap_addr.itf, addr->sap_addr.vpi,
53
addr->sap_addr.vci);
54
out:
55
release_sock(sk);
56
return error;
57
}
58
59
static int pvc_connect(struct socket *sock, struct sockaddr *sockaddr,
60
int sockaddr_len, int flags)
61
{
62
return pvc_bind(sock, sockaddr, sockaddr_len);
63
}
64
65
static int pvc_setsockopt(struct socket *sock, int level, int optname,
66
sockptr_t optval, unsigned int optlen)
67
{
68
struct sock *sk = sock->sk;
69
int error;
70
71
lock_sock(sk);
72
error = vcc_setsockopt(sock, level, optname, optval, optlen);
73
release_sock(sk);
74
return error;
75
}
76
77
static int pvc_getsockopt(struct socket *sock, int level, int optname,
78
char __user *optval, int __user *optlen)
79
{
80
struct sock *sk = sock->sk;
81
int error;
82
83
lock_sock(sk);
84
error = vcc_getsockopt(sock, level, optname, optval, optlen);
85
release_sock(sk);
86
return error;
87
}
88
89
static int pvc_getname(struct socket *sock, struct sockaddr *sockaddr,
90
int peer)
91
{
92
struct sockaddr_atmpvc *addr;
93
struct atm_vcc *vcc = ATM_SD(sock);
94
95
if (!vcc->dev || !test_bit(ATM_VF_ADDR, &vcc->flags))
96
return -ENOTCONN;
97
addr = (struct sockaddr_atmpvc *)sockaddr;
98
memset(addr, 0, sizeof(*addr));
99
addr->sap_family = AF_ATMPVC;
100
addr->sap_addr.itf = vcc->dev->number;
101
addr->sap_addr.vpi = vcc->vpi;
102
addr->sap_addr.vci = vcc->vci;
103
return sizeof(struct sockaddr_atmpvc);
104
}
105
106
static const struct proto_ops pvc_proto_ops = {
107
.family = PF_ATMPVC,
108
.owner = THIS_MODULE,
109
110
.release = vcc_release,
111
.bind = pvc_bind,
112
.connect = pvc_connect,
113
.socketpair = sock_no_socketpair,
114
.accept = sock_no_accept,
115
.getname = pvc_getname,
116
.poll = vcc_poll,
117
.ioctl = vcc_ioctl,
118
#ifdef CONFIG_COMPAT
119
.compat_ioctl = vcc_compat_ioctl,
120
#endif
121
.gettstamp = sock_gettstamp,
122
.listen = sock_no_listen,
123
.shutdown = pvc_shutdown,
124
.setsockopt = pvc_setsockopt,
125
.getsockopt = pvc_getsockopt,
126
.sendmsg = vcc_sendmsg,
127
.recvmsg = vcc_recvmsg,
128
.mmap = sock_no_mmap,
129
};
130
131
132
static int pvc_create(struct net *net, struct socket *sock, int protocol,
133
int kern)
134
{
135
if (net != &init_net)
136
return -EAFNOSUPPORT;
137
138
sock->ops = &pvc_proto_ops;
139
return vcc_create(net, sock, protocol, PF_ATMPVC, kern);
140
}
141
142
static const struct net_proto_family pvc_family_ops = {
143
.family = PF_ATMPVC,
144
.create = pvc_create,
145
.owner = THIS_MODULE,
146
};
147
148
149
/*
150
* Initialize the ATM PVC protocol family
151
*/
152
153
154
int __init atmpvc_init(void)
155
{
156
return sock_register(&pvc_family_ops);
157
}
158
159
void atmpvc_exit(void)
160
{
161
sock_unregister(PF_ATMPVC);
162
}
163
164