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,
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>
21 #include "resources.h" /* devs and vccs */
22 #include "common.h" /* common for PVCs and SVCs */
29 static int pvc_shutdown(struct socket
*sock
,int how
)
35 static int pvc_bind(struct socket
*sock
,struct sockaddr
*sockaddr
,
38 struct sockaddr_atmpvc
*addr
;
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
;
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
,
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
;
79 static struct proto_ops
SOCKOPS_WRAPPED(pvc_proto_ops
) = {
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
= {
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
)
129 error
= sock_register(&pvc_family_ops
);
131 printk(KERN_ERR
"ATMPVC: can't register (%d)",error
);
134 #ifdef CONFIG_ATM_CLIP
137 #ifdef CONFIG_PROC_FS
138 error
= atm_proc_init();
139 if (error
) printk("atm_proc_init fails with %d\n",error
);