Import 2.3.18pre1
[davej-history.git] / net / atm / pvc.c
blob4b6817eb90f4b9d4882e785dc431056f037816b2
1 /* net/atm/pvc.c - ATM PVC sockets */
3 /* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */
6 #include <linux/config.h>
7 #include <linux/net.h> /* struct socket, struct net_proto,
8 struct proto_ops */
9 #include <linux/atm.h> /* ATM stuff */
10 #include <linux/atmdev.h> /* ATM devices */
11 #include <linux/atmclip.h> /* Classical IP over ATM */
12 #include <linux/errno.h> /* error codes */
13 #include <linux/kernel.h> /* printk */
14 #include <linux/init.h>
15 #include <linux/skbuff.h>
16 #include <net/sock.h> /* for sock_no_* */
17 #ifdef CONFIG_ATM_CLIP
18 #include <net/atmclip.h>
19 #endif
21 #include "resources.h" /* devs and vccs */
22 #include "common.h" /* common for PVCs and SVCs */
24 #ifndef NULL
25 #define NULL 0
26 #endif
29 static int pvc_shutdown(struct socket *sock,int how)
31 return 0;
35 static int pvc_bind(struct socket *sock,struct sockaddr *sockaddr,
36 int sockaddr_len)
38 struct sockaddr_atmpvc *addr;
39 struct atm_vcc *vcc;
41 if (sockaddr_len != sizeof(struct sockaddr_atmpvc)) return -EINVAL;
42 addr = (struct sockaddr_atmpvc *) sockaddr;
43 if (addr->sap_family != AF_ATMPVC) return -EAFNOSUPPORT;
44 vcc = ATM_SD(sock);
45 if (!(vcc->flags & ATM_VF_HASQOS)) return -EBADFD;
46 if (vcc->flags & ATM_VF_PARTIAL) {
47 if (vcc->vpi != ATM_VPI_UNSPEC) addr->sap_addr.vpi = vcc->vpi;
48 if (vcc->vci != ATM_VCI_UNSPEC) addr->sap_addr.vci = vcc->vci;
50 return atm_connect(sock,addr->sap_addr.itf,addr->sap_addr.vpi,
51 addr->sap_addr.vci);
55 static int pvc_connect(struct socket *sock,struct sockaddr *sockaddr,
56 int sockaddr_len,int flags)
58 return pvc_bind(sock,sockaddr,sockaddr_len);
62 static int pvc_getname(struct socket *sock,struct sockaddr *sockaddr,
63 int *sockaddr_len,int peer)
65 struct sockaddr_atmpvc *addr;
66 struct atm_vcc *vcc = ATM_SD(sock);
68 if (!vcc->dev || !(vcc->flags & ATM_VF_ADDR)) return -ENOTCONN;
69 *sockaddr_len = sizeof(struct sockaddr_atmpvc);
70 addr = (struct sockaddr_atmpvc *) sockaddr;
71 addr->sap_family = AF_ATMPVC;
72 addr->sap_addr.itf = vcc->dev->number;
73 addr->sap_addr.vpi = vcc->vpi;
74 addr->sap_addr.vci = vcc->vci;
75 return 0;
79 static struct proto_ops SOCKOPS_WRAPPED(pvc_proto_ops) = {
80 PF_ATMPVC,
81 atm_release,
82 pvc_bind,
83 pvc_connect,
84 sock_no_socketpair,
85 sock_no_accept,
86 pvc_getname,
87 atm_poll,
88 atm_ioctl,
89 sock_no_listen,
90 pvc_shutdown,
91 atm_setsockopt,
92 atm_getsockopt,
93 sock_no_fcntl,
94 atm_sendmsg,
95 atm_recvmsg,
96 sock_no_mmap
100 #include <linux/smp_lock.h>
101 SOCKOPS_WRAP(pvc_proto, PF_ATMPVC);
104 static int pvc_create(struct socket *sock,int protocol)
106 sock->ops = &pvc_proto_ops;
107 return atm_create(sock,protocol,PF_ATMPVC);
111 static struct net_proto_family pvc_family_ops = {
112 PF_ATMPVC,
113 pvc_create,
114 0, /* no authentication */
115 0, /* no encryption */
116 0 /* no encrypt_net */
121 * Initialize the ATM PVC protocol family
125 void __init atmpvc_proto_init(struct net_proto *pro)
127 int error;
129 error = sock_register(&pvc_family_ops);
130 if (error < 0) {
131 printk(KERN_ERR "ATMPVC: can't register (%d)",error);
132 return;
134 #ifdef CONFIG_ATM_CLIP
135 atm_clip_init();
136 #endif
137 #ifdef CONFIG_PROC_FS
138 error = atm_proc_init();
139 if (error) printk("atm_proc_init fails with %d\n",error);
140 #endif