1 /* net/atm/signaling.c - ATM signaling */ 2 3 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ 4 5 6 #include <linux/errno.h> /* error codes */ 7 #include <linux/kernel.h> /* printk */ 8 #include <linux/skbuff.h> 9 #include <linux/wait.h> 10 #include <linux/sched.h> /* jiffies and HZ */ 11 #include <linux/atm.h> /* ATM stuff */ 12 #include <linux/atmsap.h> 13 #include <linux/atmsvc.h> 14 #include <linux/atmdev.h> 15 #include <linux/bitops.h> 16 17 #include "resources.h" 18 #include "signaling.h" 19 20 21 #undef WAIT_FOR_DEMON /* #define this if system calls on SVC sockets 22 should block until the demon runs. 23 Danger: may cause nasty hangs if the demon 24 crashes. */ 25 26 struct atm_vcc *sigd = NULL; 27 #ifdef WAIT_FOR_DEMON 28 static DECLARE_WAIT_QUEUE_HEAD(sigd_sleep); 29 #endif 30 31 32 static void sigd_put_skb(struct sk_buff *skb) 33 { 34 #ifdef WAIT_FOR_DEMON 35 DECLARE_WAITQUEUE(wait,current); 36 37 add_wait_queue(&sigd_sleep,&wait); 38 while (!sigd) { 39 set_current_state(TASK_UNINTERRUPTIBLE); 40 pr_debug("atmsvc: waiting for signaling demon...\n"); 41 schedule(); 42 } 43 current->state = TASK_RUNNING; 44 remove_wait_queue(&sigd_sleep,&wait); 45 #else 46 if (!sigd) { 47 pr_debug("atmsvc: no signaling demon\n"); 48 kfree_skb(skb); 49 return; 50 } 51 #endif 52 atm_force_charge(sigd,skb->truesize); 53 skb_queue_tail(&sk_atm(sigd)->sk_receive_queue,skb); 54 sk_atm(sigd)->sk_data_ready(sk_atm(sigd), skb->len); 55 } 56 57 58 static void modify_qos(struct atm_vcc *vcc,struct atmsvc_msg *msg) 59 { 60 struct sk_buff *skb; 61 62 if (test_bit(ATM_VF_RELEASED,&vcc->flags) || 63 !test_bit(ATM_VF_READY,&vcc->flags)) 64 return; 65 msg->type = as_error; 66 if (!vcc->dev->ops->change_qos) msg->reply = -EOPNOTSUPP; 67 else { 68 /* should lock VCC */ 69 msg->reply = vcc->dev->ops->change_qos(vcc,&msg->qos, 70 msg->reply); 71 if (!msg->reply) msg->type = as_okay; 72 } 73 /* 74 * Should probably just turn around the old skb. But the, the buffer 75 * space accounting needs to follow the change too. Maybe later. 76 */ 77 while (!(skb = alloc_skb(sizeof(struct atmsvc_msg),GFP_KERNEL))) 78 schedule(); 79 *(struct atmsvc_msg *) skb_put(skb,sizeof(struct atmsvc_msg)) = *msg; 80 sigd_put_skb(skb); 81 } 82 83 84 static int sigd_send(struct atm_vcc *vcc,struct sk_buff *skb) 85 { 86 struct atmsvc_msg *msg; 87 struct atm_vcc *session_vcc; 88 struct sock *sk; 89 90 msg = (struct atmsvc_msg *) skb->data; 91 atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc); 92 vcc = *(struct atm_vcc **) &msg->vcc; 93 pr_debug("sigd_send %d (0x%lx)\n",(int) msg->type, 94 (unsigned long) vcc); 95 sk = sk_atm(vcc); 96 97 switch (msg->type) { 98 case as_okay: 99 sk->sk_err = -msg->reply; 100 clear_bit(ATM_VF_WAITING, &vcc->flags); 101 if (!*vcc->local.sas_addr.prv && 102 !*vcc->local.sas_addr.pub) { 103 vcc->local.sas_family = AF_ATMSVC; 104 memcpy(vcc->local.sas_addr.prv, 105 msg->local.sas_addr.prv,ATM_ESA_LEN); 106 memcpy(vcc->local.sas_addr.pub, 107 msg->local.sas_addr.pub,ATM_E164_LEN+1); 108 } 109 session_vcc = vcc->session ? vcc->session : vcc; 110 if (session_vcc->vpi || session_vcc->vci) break; 111 session_vcc->itf = msg->pvc.sap_addr.itf; 112 session_vcc->vpi = msg->pvc.sap_addr.vpi; 113 session_vcc->vci = msg->pvc.sap_addr.vci; 114 if (session_vcc->vpi || session_vcc->vci) 115 session_vcc->qos = msg->qos; 116 break; 117 case as_error: 118 clear_bit(ATM_VF_REGIS,&vcc->flags); 119 clear_bit(ATM_VF_READY,&vcc->flags); 120 sk->sk_err = -msg->reply; 121 clear_bit(ATM_VF_WAITING, &vcc->flags); 122 break; 123 case as_indicate: 124 vcc = *(struct atm_vcc **) &msg->listen_vcc; 125 sk = sk_atm(vcc); 126 pr_debug("as_indicate!!!\n"); 127 lock_sock(sk); 128 if (sk_acceptq_is_full(sk)) { 129 sigd_enq(NULL,as_reject,vcc,NULL,NULL); 130 dev_kfree_skb(skb); 131 goto as_indicate_complete; 132 } 133 sk->sk_ack_backlog++; 134 skb_queue_tail(&sk->sk_receive_queue, skb); 135 pr_debug("waking sk->sk_sleep 0x%p\n", sk->sk_sleep); 136 sk->sk_state_change(sk); 137 as_indicate_complete: 138 release_sock(sk); 139 return 0; 140 case as_close: 141 set_bit(ATM_VF_RELEASED,&vcc->flags); 142 vcc_release_async(vcc, msg->reply); 143 goto out; 144 case as_modify: 145 modify_qos(vcc,msg); 146 break; 147 case as_addparty: 148 case as_dropparty: 149 sk->sk_err_soft = msg->reply; /* < 0 failure, otherwise ep_ref */ 150 clear_bit(ATM_VF_WAITING, &vcc->flags); 151 break; 152 default: 153 printk(KERN_ALERT "sigd_send: bad message type %d\n", 154 (int) msg->type); 155 return -EINVAL; 156 } 157 sk->sk_state_change(sk); 158 out: 159 dev_kfree_skb(skb); 160 return 0; 161 } 162 163 164 void sigd_enq2(struct atm_vcc *vcc,enum atmsvc_msg_type type, 165 struct atm_vcc *listen_vcc,const struct sockaddr_atmpvc *pvc, 166 const struct sockaddr_atmsvc *svc,const struct atm_qos *qos,int reply) 167 { 168 struct sk_buff *skb; 169 struct atmsvc_msg *msg; 170 static unsigned session = 0; 171 172 pr_debug("sigd_enq %d (0x%p)\n",(int) type,vcc); 173 while (!(skb = alloc_skb(sizeof(struct atmsvc_msg),GFP_KERNEL))) 174 schedule(); 175 msg = (struct atmsvc_msg *) skb_put(skb,sizeof(struct atmsvc_msg)); 176 memset(msg,0,sizeof(*msg)); 177 msg->type = type; 178 *(struct atm_vcc **) &msg->vcc = vcc; 179 *(struct atm_vcc **) &msg->listen_vcc = listen_vcc; 180 msg->reply = reply; 181 if (qos) msg->qos = *qos; 182 if (vcc) msg->sap = vcc->sap; 183 if (svc) msg->svc = *svc; 184 if (vcc) msg->local = vcc->local; 185 if (pvc) msg->pvc = *pvc; 186 if (vcc) { 187 if (type == as_connect && test_bit(ATM_VF_SESSION, &vcc->flags)) 188 msg->session = ++session; 189 /* every new pmp connect gets the next session number */ 190 } 191 sigd_put_skb(skb); 192 if (vcc) set_bit(ATM_VF_REGIS,&vcc->flags); 193 } 194 195 196 void sigd_enq(struct atm_vcc *vcc,enum atmsvc_msg_type type, 197 struct atm_vcc *listen_vcc,const struct sockaddr_atmpvc *pvc, 198 const struct sockaddr_atmsvc *svc) 199 { 200 sigd_enq2(vcc,type,listen_vcc,pvc,svc,vcc ? &vcc->qos : NULL,0); 201 /* other ISP applications may use "reply" */ 202 } 203 204 205 static void purge_vcc(struct atm_vcc *vcc) 206 { 207 if (sk_atm(vcc)->sk_family == PF_ATMSVC && 208 !test_bit(ATM_VF_META, &vcc->flags)) { 209 set_bit(ATM_VF_RELEASED, &vcc->flags); 210 clear_bit(ATM_VF_REGIS, &vcc->flags); 211 vcc_release_async(vcc, -EUNATCH); 212 } 213 } 214 215 216 static void sigd_close(struct atm_vcc *vcc) 217 { 218 struct hlist_node *node; 219 struct sock *s; 220 int i; 221 222 pr_debug("sigd_close\n"); 223 sigd = NULL; 224 if (skb_peek(&sk_atm(vcc)->sk_receive_queue)) 225 printk(KERN_ERR "sigd_close: closing with requests pending\n"); 226 skb_queue_purge(&sk_atm(vcc)->sk_receive_queue); 227 228 read_lock(&vcc_sklist_lock); 229 for(i = 0; i < VCC_HTABLE_SIZE; ++i) { 230 struct hlist_head *head = &vcc_hash[i]; 231 232 sk_for_each(s, node, head) { 233 vcc = atm_sk(s); 234 235 purge_vcc(vcc); 236 } 237 } 238 read_unlock(&vcc_sklist_lock); 239 } 240 241 242 static struct atmdev_ops sigd_dev_ops = { 243 .close = sigd_close, 244 .send = sigd_send 245 }; 246 247 248 static struct atm_dev sigd_dev = { 249 .ops = &sigd_dev_ops, 250 .type = "sig", 251 .number = 999, 252 .lock = __SPIN_LOCK_UNLOCKED(sigd_dev.lock) 253 }; 254 255 256 int sigd_attach(struct atm_vcc *vcc) 257 { 258 if (sigd) return -EADDRINUSE; 259 pr_debug("sigd_attach\n"); 260 sigd = vcc; 261 vcc->dev = &sigd_dev; 262 vcc_insert_socket(sk_atm(vcc)); 263 set_bit(ATM_VF_META,&vcc->flags); 264 set_bit(ATM_VF_READY,&vcc->flags); 265 #ifdef WAIT_FOR_DEMON 266 wake_up(&sigd_sleep); 267 #endif 268 return 0; 269 } 270