lapb_iface.c (11671B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * LAPB release 002 4 * 5 * This code REQUIRES 2.1.15 or higher/ NET3.038 6 * 7 * History 8 * LAPB 001 Jonathan Naylor Started Coding 9 * LAPB 002 Jonathan Naylor New timer architecture. 10 * 2000-10-29 Henner Eisen lapb_data_indication() return status. 11 */ 12 13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 14 15#include <linux/module.h> 16#include <linux/errno.h> 17#include <linux/types.h> 18#include <linux/socket.h> 19#include <linux/in.h> 20#include <linux/kernel.h> 21#include <linux/jiffies.h> 22#include <linux/timer.h> 23#include <linux/string.h> 24#include <linux/sockios.h> 25#include <linux/net.h> 26#include <linux/inet.h> 27#include <linux/if_arp.h> 28#include <linux/skbuff.h> 29#include <linux/slab.h> 30#include <net/sock.h> 31#include <linux/uaccess.h> 32#include <linux/fcntl.h> 33#include <linux/mm.h> 34#include <linux/interrupt.h> 35#include <linux/stat.h> 36#include <linux/init.h> 37#include <net/lapb.h> 38 39static LIST_HEAD(lapb_list); 40static DEFINE_RWLOCK(lapb_list_lock); 41 42/* 43 * Free an allocated lapb control block. 44 */ 45static void lapb_free_cb(struct lapb_cb *lapb) 46{ 47 kfree(lapb); 48} 49 50static __inline__ void lapb_hold(struct lapb_cb *lapb) 51{ 52 refcount_inc(&lapb->refcnt); 53} 54 55static __inline__ void lapb_put(struct lapb_cb *lapb) 56{ 57 if (refcount_dec_and_test(&lapb->refcnt)) 58 lapb_free_cb(lapb); 59} 60 61/* 62 * Socket removal during an interrupt is now safe. 63 */ 64static void __lapb_remove_cb(struct lapb_cb *lapb) 65{ 66 if (lapb->node.next) { 67 list_del(&lapb->node); 68 lapb_put(lapb); 69 } 70} 71 72/* 73 * Add a socket to the bound sockets list. 74 */ 75static void __lapb_insert_cb(struct lapb_cb *lapb) 76{ 77 list_add(&lapb->node, &lapb_list); 78 lapb_hold(lapb); 79} 80 81static struct lapb_cb *__lapb_devtostruct(struct net_device *dev) 82{ 83 struct lapb_cb *lapb, *use = NULL; 84 85 list_for_each_entry(lapb, &lapb_list, node) { 86 if (lapb->dev == dev) { 87 use = lapb; 88 break; 89 } 90 } 91 92 if (use) 93 lapb_hold(use); 94 95 return use; 96} 97 98static struct lapb_cb *lapb_devtostruct(struct net_device *dev) 99{ 100 struct lapb_cb *rc; 101 102 read_lock_bh(&lapb_list_lock); 103 rc = __lapb_devtostruct(dev); 104 read_unlock_bh(&lapb_list_lock); 105 106 return rc; 107} 108/* 109 * Create an empty LAPB control block. 110 */ 111static struct lapb_cb *lapb_create_cb(void) 112{ 113 struct lapb_cb *lapb = kzalloc(sizeof(*lapb), GFP_ATOMIC); 114 115 if (!lapb) 116 goto out; 117 118 skb_queue_head_init(&lapb->write_queue); 119 skb_queue_head_init(&lapb->ack_queue); 120 121 timer_setup(&lapb->t1timer, NULL, 0); 122 timer_setup(&lapb->t2timer, NULL, 0); 123 lapb->t1timer_running = false; 124 lapb->t2timer_running = false; 125 126 lapb->t1 = LAPB_DEFAULT_T1; 127 lapb->t2 = LAPB_DEFAULT_T2; 128 lapb->n2 = LAPB_DEFAULT_N2; 129 lapb->mode = LAPB_DEFAULT_MODE; 130 lapb->window = LAPB_DEFAULT_WINDOW; 131 lapb->state = LAPB_STATE_0; 132 133 spin_lock_init(&lapb->lock); 134 refcount_set(&lapb->refcnt, 1); 135out: 136 return lapb; 137} 138 139int lapb_register(struct net_device *dev, 140 const struct lapb_register_struct *callbacks) 141{ 142 struct lapb_cb *lapb; 143 int rc = LAPB_BADTOKEN; 144 145 write_lock_bh(&lapb_list_lock); 146 147 lapb = __lapb_devtostruct(dev); 148 if (lapb) { 149 lapb_put(lapb); 150 goto out; 151 } 152 153 lapb = lapb_create_cb(); 154 rc = LAPB_NOMEM; 155 if (!lapb) 156 goto out; 157 158 lapb->dev = dev; 159 lapb->callbacks = callbacks; 160 161 __lapb_insert_cb(lapb); 162 163 lapb_start_t1timer(lapb); 164 165 rc = LAPB_OK; 166out: 167 write_unlock_bh(&lapb_list_lock); 168 return rc; 169} 170EXPORT_SYMBOL(lapb_register); 171 172int lapb_unregister(struct net_device *dev) 173{ 174 struct lapb_cb *lapb; 175 int rc = LAPB_BADTOKEN; 176 177 write_lock_bh(&lapb_list_lock); 178 lapb = __lapb_devtostruct(dev); 179 if (!lapb) 180 goto out; 181 lapb_put(lapb); 182 183 /* Wait for other refs to "lapb" to drop */ 184 while (refcount_read(&lapb->refcnt) > 2) 185 usleep_range(1, 10); 186 187 spin_lock_bh(&lapb->lock); 188 189 lapb_stop_t1timer(lapb); 190 lapb_stop_t2timer(lapb); 191 192 lapb_clear_queues(lapb); 193 194 spin_unlock_bh(&lapb->lock); 195 196 /* Wait for running timers to stop */ 197 del_timer_sync(&lapb->t1timer); 198 del_timer_sync(&lapb->t2timer); 199 200 __lapb_remove_cb(lapb); 201 202 lapb_put(lapb); 203 rc = LAPB_OK; 204out: 205 write_unlock_bh(&lapb_list_lock); 206 return rc; 207} 208EXPORT_SYMBOL(lapb_unregister); 209 210int lapb_getparms(struct net_device *dev, struct lapb_parms_struct *parms) 211{ 212 int rc = LAPB_BADTOKEN; 213 struct lapb_cb *lapb = lapb_devtostruct(dev); 214 215 if (!lapb) 216 goto out; 217 218 spin_lock_bh(&lapb->lock); 219 220 parms->t1 = lapb->t1 / HZ; 221 parms->t2 = lapb->t2 / HZ; 222 parms->n2 = lapb->n2; 223 parms->n2count = lapb->n2count; 224 parms->state = lapb->state; 225 parms->window = lapb->window; 226 parms->mode = lapb->mode; 227 228 if (!timer_pending(&lapb->t1timer)) 229 parms->t1timer = 0; 230 else 231 parms->t1timer = (lapb->t1timer.expires - jiffies) / HZ; 232 233 if (!timer_pending(&lapb->t2timer)) 234 parms->t2timer = 0; 235 else 236 parms->t2timer = (lapb->t2timer.expires - jiffies) / HZ; 237 238 spin_unlock_bh(&lapb->lock); 239 lapb_put(lapb); 240 rc = LAPB_OK; 241out: 242 return rc; 243} 244EXPORT_SYMBOL(lapb_getparms); 245 246int lapb_setparms(struct net_device *dev, struct lapb_parms_struct *parms) 247{ 248 int rc = LAPB_BADTOKEN; 249 struct lapb_cb *lapb = lapb_devtostruct(dev); 250 251 if (!lapb) 252 goto out; 253 254 spin_lock_bh(&lapb->lock); 255 256 rc = LAPB_INVALUE; 257 if (parms->t1 < 1 || parms->t2 < 1 || parms->n2 < 1) 258 goto out_put; 259 260 if (lapb->state == LAPB_STATE_0) { 261 if (parms->mode & LAPB_EXTENDED) { 262 if (parms->window < 1 || parms->window > 127) 263 goto out_put; 264 } else { 265 if (parms->window < 1 || parms->window > 7) 266 goto out_put; 267 } 268 lapb->mode = parms->mode; 269 lapb->window = parms->window; 270 } 271 272 lapb->t1 = parms->t1 * HZ; 273 lapb->t2 = parms->t2 * HZ; 274 lapb->n2 = parms->n2; 275 276 rc = LAPB_OK; 277out_put: 278 spin_unlock_bh(&lapb->lock); 279 lapb_put(lapb); 280out: 281 return rc; 282} 283EXPORT_SYMBOL(lapb_setparms); 284 285int lapb_connect_request(struct net_device *dev) 286{ 287 struct lapb_cb *lapb = lapb_devtostruct(dev); 288 int rc = LAPB_BADTOKEN; 289 290 if (!lapb) 291 goto out; 292 293 spin_lock_bh(&lapb->lock); 294 295 rc = LAPB_OK; 296 if (lapb->state == LAPB_STATE_1) 297 goto out_put; 298 299 rc = LAPB_CONNECTED; 300 if (lapb->state == LAPB_STATE_3 || lapb->state == LAPB_STATE_4) 301 goto out_put; 302 303 lapb_establish_data_link(lapb); 304 305 lapb_dbg(0, "(%p) S0 -> S1\n", lapb->dev); 306 lapb->state = LAPB_STATE_1; 307 308 rc = LAPB_OK; 309out_put: 310 spin_unlock_bh(&lapb->lock); 311 lapb_put(lapb); 312out: 313 return rc; 314} 315EXPORT_SYMBOL(lapb_connect_request); 316 317static int __lapb_disconnect_request(struct lapb_cb *lapb) 318{ 319 switch (lapb->state) { 320 case LAPB_STATE_0: 321 return LAPB_NOTCONNECTED; 322 323 case LAPB_STATE_1: 324 lapb_dbg(1, "(%p) S1 TX DISC(1)\n", lapb->dev); 325 lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev); 326 lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND); 327 lapb->state = LAPB_STATE_0; 328 lapb_start_t1timer(lapb); 329 return LAPB_NOTCONNECTED; 330 331 case LAPB_STATE_2: 332 return LAPB_OK; 333 } 334 335 lapb_clear_queues(lapb); 336 lapb->n2count = 0; 337 lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND); 338 lapb_start_t1timer(lapb); 339 lapb_stop_t2timer(lapb); 340 lapb->state = LAPB_STATE_2; 341 342 lapb_dbg(1, "(%p) S3 DISC(1)\n", lapb->dev); 343 lapb_dbg(0, "(%p) S3 -> S2\n", lapb->dev); 344 345 return LAPB_OK; 346} 347 348int lapb_disconnect_request(struct net_device *dev) 349{ 350 struct lapb_cb *lapb = lapb_devtostruct(dev); 351 int rc = LAPB_BADTOKEN; 352 353 if (!lapb) 354 goto out; 355 356 spin_lock_bh(&lapb->lock); 357 358 rc = __lapb_disconnect_request(lapb); 359 360 spin_unlock_bh(&lapb->lock); 361 lapb_put(lapb); 362out: 363 return rc; 364} 365EXPORT_SYMBOL(lapb_disconnect_request); 366 367int lapb_data_request(struct net_device *dev, struct sk_buff *skb) 368{ 369 struct lapb_cb *lapb = lapb_devtostruct(dev); 370 int rc = LAPB_BADTOKEN; 371 372 if (!lapb) 373 goto out; 374 375 spin_lock_bh(&lapb->lock); 376 377 rc = LAPB_NOTCONNECTED; 378 if (lapb->state != LAPB_STATE_3 && lapb->state != LAPB_STATE_4) 379 goto out_put; 380 381 skb_queue_tail(&lapb->write_queue, skb); 382 lapb_kick(lapb); 383 rc = LAPB_OK; 384out_put: 385 spin_unlock_bh(&lapb->lock); 386 lapb_put(lapb); 387out: 388 return rc; 389} 390EXPORT_SYMBOL(lapb_data_request); 391 392int lapb_data_received(struct net_device *dev, struct sk_buff *skb) 393{ 394 struct lapb_cb *lapb = lapb_devtostruct(dev); 395 int rc = LAPB_BADTOKEN; 396 397 if (lapb) { 398 spin_lock_bh(&lapb->lock); 399 lapb_data_input(lapb, skb); 400 spin_unlock_bh(&lapb->lock); 401 lapb_put(lapb); 402 rc = LAPB_OK; 403 } 404 405 return rc; 406} 407EXPORT_SYMBOL(lapb_data_received); 408 409void lapb_connect_confirmation(struct lapb_cb *lapb, int reason) 410{ 411 if (lapb->callbacks->connect_confirmation) 412 lapb->callbacks->connect_confirmation(lapb->dev, reason); 413} 414 415void lapb_connect_indication(struct lapb_cb *lapb, int reason) 416{ 417 if (lapb->callbacks->connect_indication) 418 lapb->callbacks->connect_indication(lapb->dev, reason); 419} 420 421void lapb_disconnect_confirmation(struct lapb_cb *lapb, int reason) 422{ 423 if (lapb->callbacks->disconnect_confirmation) 424 lapb->callbacks->disconnect_confirmation(lapb->dev, reason); 425} 426 427void lapb_disconnect_indication(struct lapb_cb *lapb, int reason) 428{ 429 if (lapb->callbacks->disconnect_indication) 430 lapb->callbacks->disconnect_indication(lapb->dev, reason); 431} 432 433int lapb_data_indication(struct lapb_cb *lapb, struct sk_buff *skb) 434{ 435 if (lapb->callbacks->data_indication) 436 return lapb->callbacks->data_indication(lapb->dev, skb); 437 438 kfree_skb(skb); 439 return NET_RX_SUCCESS; /* For now; must be != NET_RX_DROP */ 440} 441 442int lapb_data_transmit(struct lapb_cb *lapb, struct sk_buff *skb) 443{ 444 int used = 0; 445 446 if (lapb->callbacks->data_transmit) { 447 lapb->callbacks->data_transmit(lapb->dev, skb); 448 used = 1; 449 } 450 451 return used; 452} 453 454/* Handle device status changes. */ 455static int lapb_device_event(struct notifier_block *this, unsigned long event, 456 void *ptr) 457{ 458 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 459 struct lapb_cb *lapb; 460 461 if (!net_eq(dev_net(dev), &init_net)) 462 return NOTIFY_DONE; 463 464 if (dev->type != ARPHRD_X25) 465 return NOTIFY_DONE; 466 467 lapb = lapb_devtostruct(dev); 468 if (!lapb) 469 return NOTIFY_DONE; 470 471 spin_lock_bh(&lapb->lock); 472 473 switch (event) { 474 case NETDEV_UP: 475 lapb_dbg(0, "(%p) Interface up: %s\n", dev, dev->name); 476 477 if (netif_carrier_ok(dev)) { 478 lapb_dbg(0, "(%p): Carrier is already up: %s\n", dev, 479 dev->name); 480 if (lapb->mode & LAPB_DCE) { 481 lapb_start_t1timer(lapb); 482 } else { 483 if (lapb->state == LAPB_STATE_0) { 484 lapb->state = LAPB_STATE_1; 485 lapb_establish_data_link(lapb); 486 } 487 } 488 } 489 break; 490 case NETDEV_GOING_DOWN: 491 if (netif_carrier_ok(dev)) 492 __lapb_disconnect_request(lapb); 493 break; 494 case NETDEV_DOWN: 495 lapb_dbg(0, "(%p) Interface down: %s\n", dev, dev->name); 496 lapb_dbg(0, "(%p) S%d -> S0\n", dev, lapb->state); 497 lapb_clear_queues(lapb); 498 lapb->state = LAPB_STATE_0; 499 lapb->n2count = 0; 500 lapb_stop_t1timer(lapb); 501 lapb_stop_t2timer(lapb); 502 break; 503 case NETDEV_CHANGE: 504 if (netif_carrier_ok(dev)) { 505 lapb_dbg(0, "(%p): Carrier detected: %s\n", dev, 506 dev->name); 507 if (lapb->mode & LAPB_DCE) { 508 lapb_start_t1timer(lapb); 509 } else { 510 if (lapb->state == LAPB_STATE_0) { 511 lapb->state = LAPB_STATE_1; 512 lapb_establish_data_link(lapb); 513 } 514 } 515 } else { 516 lapb_dbg(0, "(%p) Carrier lost: %s\n", dev, dev->name); 517 lapb_dbg(0, "(%p) S%d -> S0\n", dev, lapb->state); 518 lapb_clear_queues(lapb); 519 lapb->state = LAPB_STATE_0; 520 lapb->n2count = 0; 521 lapb_stop_t1timer(lapb); 522 lapb_stop_t2timer(lapb); 523 } 524 break; 525 } 526 527 spin_unlock_bh(&lapb->lock); 528 lapb_put(lapb); 529 return NOTIFY_DONE; 530} 531 532static struct notifier_block lapb_dev_notifier = { 533 .notifier_call = lapb_device_event, 534}; 535 536static int __init lapb_init(void) 537{ 538 return register_netdevice_notifier(&lapb_dev_notifier); 539} 540 541static void __exit lapb_exit(void) 542{ 543 WARN_ON(!list_empty(&lapb_list)); 544 545 unregister_netdevice_notifier(&lapb_dev_notifier); 546} 547 548MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>"); 549MODULE_DESCRIPTION("The X.25 Link Access Procedure B link layer protocol"); 550MODULE_LICENSE("GPL"); 551 552module_init(lapb_init); 553module_exit(lapb_exit);