1 /* net/atm/signaling.c - ATM signaling */
3 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
5 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
7 #include <linux/errno.h> /* error codes */
8 #include <linux/kernel.h> /* printk */
9 #include <linux/skbuff.h>
10 #include <linux/wait.h>
11 #include <linux/sched.h> /* jiffies and HZ */
12 #include <linux/atm.h> /* ATM stuff */
13 #include <linux/atmsap.h>
14 #include <linux/atmsvc.h>
15 #include <linux/atmdev.h>
16 #include <linux/bitops.h>
17 #include <linux/slab.h>
19 #include "resources.h"
20 #include "signaling.h"
22 struct atm_vcc
*sigd
= NULL
;
24 static void sigd_put_skb(struct sk_buff
*skb
)
27 pr_debug("atmsvc: no signaling daemon\n");
31 atm_force_charge(sigd
, skb
->truesize
);
32 skb_queue_tail(&sk_atm(sigd
)->sk_receive_queue
, skb
);
33 sk_atm(sigd
)->sk_data_ready(sk_atm(sigd
));
36 static void modify_qos(struct atm_vcc
*vcc
, struct atmsvc_msg
*msg
)
40 if (test_bit(ATM_VF_RELEASED
, &vcc
->flags
) ||
41 !test_bit(ATM_VF_READY
, &vcc
->flags
))
44 if (!vcc
->dev
->ops
->change_qos
)
45 msg
->reply
= -EOPNOTSUPP
;
48 msg
->reply
= vcc
->dev
->ops
->change_qos(vcc
, &msg
->qos
,
54 * Should probably just turn around the old skb. But the, the buffer
55 * space accounting needs to follow the change too. Maybe later.
57 while (!(skb
= alloc_skb(sizeof(struct atmsvc_msg
), GFP_KERNEL
)))
59 *(struct atmsvc_msg
*)skb_put(skb
, sizeof(struct atmsvc_msg
)) = *msg
;
63 static int sigd_send(struct atm_vcc
*vcc
, struct sk_buff
*skb
)
65 struct atmsvc_msg
*msg
;
66 struct atm_vcc
*session_vcc
;
69 msg
= (struct atmsvc_msg
*) skb
->data
;
70 atomic_sub(skb
->truesize
, &sk_atm(vcc
)->sk_wmem_alloc
);
71 vcc
= *(struct atm_vcc
**) &msg
->vcc
;
72 pr_debug("%d (0x%lx)\n", (int)msg
->type
, (unsigned long)vcc
);
77 sk
->sk_err
= -msg
->reply
;
78 clear_bit(ATM_VF_WAITING
, &vcc
->flags
);
79 if (!*vcc
->local
.sas_addr
.prv
&& !*vcc
->local
.sas_addr
.pub
) {
80 vcc
->local
.sas_family
= AF_ATMSVC
;
81 memcpy(vcc
->local
.sas_addr
.prv
,
82 msg
->local
.sas_addr
.prv
, ATM_ESA_LEN
);
83 memcpy(vcc
->local
.sas_addr
.pub
,
84 msg
->local
.sas_addr
.pub
, ATM_E164_LEN
+ 1);
86 session_vcc
= vcc
->session
? vcc
->session
: vcc
;
87 if (session_vcc
->vpi
|| session_vcc
->vci
)
89 session_vcc
->itf
= msg
->pvc
.sap_addr
.itf
;
90 session_vcc
->vpi
= msg
->pvc
.sap_addr
.vpi
;
91 session_vcc
->vci
= msg
->pvc
.sap_addr
.vci
;
92 if (session_vcc
->vpi
|| session_vcc
->vci
)
93 session_vcc
->qos
= msg
->qos
;
96 clear_bit(ATM_VF_REGIS
, &vcc
->flags
);
97 clear_bit(ATM_VF_READY
, &vcc
->flags
);
98 sk
->sk_err
= -msg
->reply
;
99 clear_bit(ATM_VF_WAITING
, &vcc
->flags
);
102 vcc
= *(struct atm_vcc
**)&msg
->listen_vcc
;
104 pr_debug("as_indicate!!!\n");
106 if (sk_acceptq_is_full(sk
)) {
107 sigd_enq(NULL
, as_reject
, vcc
, NULL
, NULL
);
109 goto as_indicate_complete
;
111 sk
->sk_ack_backlog
++;
112 skb_queue_tail(&sk
->sk_receive_queue
, skb
);
113 pr_debug("waking sk_sleep(sk) 0x%p\n", sk_sleep(sk
));
114 sk
->sk_state_change(sk
);
115 as_indicate_complete
:
119 set_bit(ATM_VF_RELEASED
, &vcc
->flags
);
120 vcc_release_async(vcc
, msg
->reply
);
123 modify_qos(vcc
, msg
);
127 sk
->sk_err_soft
= msg
->reply
;
128 /* < 0 failure, otherwise ep_ref */
129 clear_bit(ATM_VF_WAITING
, &vcc
->flags
);
132 pr_alert("bad message type %d\n", (int)msg
->type
);
135 sk
->sk_state_change(sk
);
141 void sigd_enq2(struct atm_vcc
*vcc
, enum atmsvc_msg_type type
,
142 struct atm_vcc
*listen_vcc
, const struct sockaddr_atmpvc
*pvc
,
143 const struct sockaddr_atmsvc
*svc
, const struct atm_qos
*qos
,
147 struct atmsvc_msg
*msg
;
148 static unsigned int session
= 0;
150 pr_debug("%d (0x%p)\n", (int)type
, vcc
);
151 while (!(skb
= alloc_skb(sizeof(struct atmsvc_msg
), GFP_KERNEL
)))
153 msg
= (struct atmsvc_msg
*)skb_put(skb
, sizeof(struct atmsvc_msg
));
154 memset(msg
, 0, sizeof(*msg
));
156 *(struct atm_vcc
**) &msg
->vcc
= vcc
;
157 *(struct atm_vcc
**) &msg
->listen_vcc
= listen_vcc
;
166 msg
->local
= vcc
->local
;
170 if (type
== as_connect
&& test_bit(ATM_VF_SESSION
, &vcc
->flags
))
171 msg
->session
= ++session
;
172 /* every new pmp connect gets the next session number */
176 set_bit(ATM_VF_REGIS
, &vcc
->flags
);
179 void sigd_enq(struct atm_vcc
*vcc
, enum atmsvc_msg_type type
,
180 struct atm_vcc
*listen_vcc
, const struct sockaddr_atmpvc
*pvc
,
181 const struct sockaddr_atmsvc
*svc
)
183 sigd_enq2(vcc
, type
, listen_vcc
, pvc
, svc
, vcc
? &vcc
->qos
: NULL
, 0);
184 /* other ISP applications may use "reply" */
187 static void purge_vcc(struct atm_vcc
*vcc
)
189 if (sk_atm(vcc
)->sk_family
== PF_ATMSVC
&&
190 !test_bit(ATM_VF_META
, &vcc
->flags
)) {
191 set_bit(ATM_VF_RELEASED
, &vcc
->flags
);
192 clear_bit(ATM_VF_REGIS
, &vcc
->flags
);
193 vcc_release_async(vcc
, -EUNATCH
);
197 static void sigd_close(struct atm_vcc
*vcc
)
204 if (skb_peek(&sk_atm(vcc
)->sk_receive_queue
))
205 pr_err("closing with requests pending\n");
206 skb_queue_purge(&sk_atm(vcc
)->sk_receive_queue
);
208 read_lock(&vcc_sklist_lock
);
209 for (i
= 0; i
< VCC_HTABLE_SIZE
; ++i
) {
210 struct hlist_head
*head
= &vcc_hash
[i
];
212 sk_for_each(s
, head
) {
218 read_unlock(&vcc_sklist_lock
);
221 static struct atmdev_ops sigd_dev_ops
= {
226 static struct atm_dev sigd_dev
= {
227 .ops
= &sigd_dev_ops
,
230 .lock
= __SPIN_LOCK_UNLOCKED(sigd_dev
.lock
)
233 int sigd_attach(struct atm_vcc
*vcc
)
239 vcc
->dev
= &sigd_dev
;
240 vcc_insert_socket(sk_atm(vcc
));
241 set_bit(ATM_VF_META
, &vcc
->flags
);
242 set_bit(ATM_VF_READY
, &vcc
->flags
);