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