0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0019
0020 #include <linux/errno.h>
0021 #include <linux/types.h>
0022 #include <linux/socket.h>
0023 #include <linux/in.h>
0024 #include <linux/slab.h>
0025 #include <linux/kernel.h>
0026 #include <linux/string.h>
0027 #include <linux/net.h>
0028 #include <linux/inet.h>
0029 #include <linux/netdevice.h>
0030 #include <linux/if_arp.h>
0031 #include <linux/skbuff.h>
0032 #include <net/sock.h>
0033 #include <linux/uaccess.h>
0034 #include <linux/mm.h>
0035 #include <linux/interrupt.h>
0036 #include <linux/notifier.h>
0037 #include <linux/stat.h>
0038 #include <linux/module.h>
0039 #include <linux/lapb.h>
0040 #include <linux/init.h>
0041
0042 #include <net/x25device.h>
0043
0044 static const u8 bcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
0045
0046
0047
0048
0049 #define MAXLAPBDEV 100
0050
0051 struct lapbethdev {
0052 struct list_head node;
0053 struct net_device *ethdev;
0054 struct net_device *axdev;
0055 bool up;
0056 spinlock_t up_lock;
0057 struct sk_buff_head rx_queue;
0058 struct napi_struct napi;
0059 };
0060
0061 static LIST_HEAD(lapbeth_devices);
0062
0063 static void lapbeth_connected(struct net_device *dev, int reason);
0064 static void lapbeth_disconnected(struct net_device *dev, int reason);
0065
0066
0067
0068
0069
0070 static struct lapbethdev *lapbeth_get_x25_dev(struct net_device *dev)
0071 {
0072 struct lapbethdev *lapbeth;
0073
0074 list_for_each_entry_rcu(lapbeth, &lapbeth_devices, node, lockdep_rtnl_is_held()) {
0075 if (lapbeth->ethdev == dev)
0076 return lapbeth;
0077 }
0078 return NULL;
0079 }
0080
0081 static __inline__ int dev_is_ethdev(struct net_device *dev)
0082 {
0083 return dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5);
0084 }
0085
0086
0087
0088 static int lapbeth_napi_poll(struct napi_struct *napi, int budget)
0089 {
0090 struct lapbethdev *lapbeth = container_of(napi, struct lapbethdev,
0091 napi);
0092 struct sk_buff *skb;
0093 int processed = 0;
0094
0095 for (; processed < budget; ++processed) {
0096 skb = skb_dequeue(&lapbeth->rx_queue);
0097 if (!skb)
0098 break;
0099 netif_receive_skb_core(skb);
0100 }
0101
0102 if (processed < budget)
0103 napi_complete(napi);
0104
0105 return processed;
0106 }
0107
0108
0109
0110 static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev,
0111 struct packet_type *ptype, struct net_device *orig_dev)
0112 {
0113 int len, err;
0114 struct lapbethdev *lapbeth;
0115
0116 if (dev_net(dev) != &init_net)
0117 goto drop;
0118
0119 skb = skb_share_check(skb, GFP_ATOMIC);
0120 if (!skb)
0121 return NET_RX_DROP;
0122
0123 if (!pskb_may_pull(skb, 2))
0124 goto drop;
0125
0126 rcu_read_lock();
0127 lapbeth = lapbeth_get_x25_dev(dev);
0128 if (!lapbeth)
0129 goto drop_unlock_rcu;
0130 spin_lock_bh(&lapbeth->up_lock);
0131 if (!lapbeth->up)
0132 goto drop_unlock;
0133
0134 len = skb->data[0] + skb->data[1] * 256;
0135 dev->stats.rx_packets++;
0136 dev->stats.rx_bytes += len;
0137
0138 skb_pull(skb, 2);
0139 skb_trim(skb, len);
0140
0141 err = lapb_data_received(lapbeth->axdev, skb);
0142 if (err != LAPB_OK) {
0143 printk(KERN_DEBUG "lapbether: lapb_data_received err - %d\n", err);
0144 goto drop_unlock;
0145 }
0146 out:
0147 spin_unlock_bh(&lapbeth->up_lock);
0148 rcu_read_unlock();
0149 return 0;
0150 drop_unlock:
0151 kfree_skb(skb);
0152 goto out;
0153 drop_unlock_rcu:
0154 rcu_read_unlock();
0155 drop:
0156 kfree_skb(skb);
0157 return 0;
0158 }
0159
0160 static int lapbeth_data_indication(struct net_device *dev, struct sk_buff *skb)
0161 {
0162 struct lapbethdev *lapbeth = netdev_priv(dev);
0163 unsigned char *ptr;
0164
0165 if (skb_cow(skb, 1)) {
0166 kfree_skb(skb);
0167 return NET_RX_DROP;
0168 }
0169
0170 skb_push(skb, 1);
0171
0172 ptr = skb->data;
0173 *ptr = X25_IFACE_DATA;
0174
0175 skb->protocol = x25_type_trans(skb, dev);
0176
0177 skb_queue_tail(&lapbeth->rx_queue, skb);
0178 napi_schedule(&lapbeth->napi);
0179 return NET_RX_SUCCESS;
0180 }
0181
0182
0183
0184 static netdev_tx_t lapbeth_xmit(struct sk_buff *skb,
0185 struct net_device *dev)
0186 {
0187 struct lapbethdev *lapbeth = netdev_priv(dev);
0188 int err;
0189
0190 spin_lock_bh(&lapbeth->up_lock);
0191 if (!lapbeth->up)
0192 goto drop;
0193
0194
0195
0196
0197 if (skb->len < 1)
0198 goto drop;
0199
0200 switch (skb->data[0]) {
0201 case X25_IFACE_DATA:
0202 break;
0203 case X25_IFACE_CONNECT:
0204 err = lapb_connect_request(dev);
0205 if (err == LAPB_CONNECTED)
0206 lapbeth_connected(dev, LAPB_OK);
0207 else if (err != LAPB_OK)
0208 pr_err("lapb_connect_request error: %d\n", err);
0209 goto drop;
0210 case X25_IFACE_DISCONNECT:
0211 err = lapb_disconnect_request(dev);
0212 if (err == LAPB_NOTCONNECTED)
0213 lapbeth_disconnected(dev, LAPB_OK);
0214 else if (err != LAPB_OK)
0215 pr_err("lapb_disconnect_request err: %d\n", err);
0216 fallthrough;
0217 default:
0218 goto drop;
0219 }
0220
0221 skb_pull(skb, 1);
0222
0223 err = lapb_data_request(dev, skb);
0224 if (err != LAPB_OK) {
0225 pr_err("lapb_data_request error - %d\n", err);
0226 goto drop;
0227 }
0228 out:
0229 spin_unlock_bh(&lapbeth->up_lock);
0230 return NETDEV_TX_OK;
0231 drop:
0232 kfree_skb(skb);
0233 goto out;
0234 }
0235
0236 static void lapbeth_data_transmit(struct net_device *ndev, struct sk_buff *skb)
0237 {
0238 struct lapbethdev *lapbeth = netdev_priv(ndev);
0239 unsigned char *ptr;
0240 struct net_device *dev;
0241 int size = skb->len;
0242
0243 ptr = skb_push(skb, 2);
0244
0245 *ptr++ = size % 256;
0246 *ptr++ = size / 256;
0247
0248 ndev->stats.tx_packets++;
0249 ndev->stats.tx_bytes += size;
0250
0251 skb->dev = dev = lapbeth->ethdev;
0252
0253 skb->protocol = htons(ETH_P_DEC);
0254
0255 skb_reset_network_header(skb);
0256
0257 dev_hard_header(skb, dev, ETH_P_DEC, bcast_addr, NULL, 0);
0258
0259 dev_queue_xmit(skb);
0260 }
0261
0262 static void lapbeth_connected(struct net_device *dev, int reason)
0263 {
0264 struct lapbethdev *lapbeth = netdev_priv(dev);
0265 unsigned char *ptr;
0266 struct sk_buff *skb = __dev_alloc_skb(1, GFP_ATOMIC | __GFP_NOMEMALLOC);
0267
0268 if (!skb)
0269 return;
0270
0271 ptr = skb_put(skb, 1);
0272 *ptr = X25_IFACE_CONNECT;
0273
0274 skb->protocol = x25_type_trans(skb, dev);
0275
0276 skb_queue_tail(&lapbeth->rx_queue, skb);
0277 napi_schedule(&lapbeth->napi);
0278 }
0279
0280 static void lapbeth_disconnected(struct net_device *dev, int reason)
0281 {
0282 struct lapbethdev *lapbeth = netdev_priv(dev);
0283 unsigned char *ptr;
0284 struct sk_buff *skb = __dev_alloc_skb(1, GFP_ATOMIC | __GFP_NOMEMALLOC);
0285
0286 if (!skb)
0287 return;
0288
0289 ptr = skb_put(skb, 1);
0290 *ptr = X25_IFACE_DISCONNECT;
0291
0292 skb->protocol = x25_type_trans(skb, dev);
0293
0294 skb_queue_tail(&lapbeth->rx_queue, skb);
0295 napi_schedule(&lapbeth->napi);
0296 }
0297
0298
0299
0300 static int lapbeth_set_mac_address(struct net_device *dev, void *addr)
0301 {
0302 struct sockaddr *sa = addr;
0303
0304 dev_addr_set(dev, sa->sa_data);
0305 return 0;
0306 }
0307
0308 static const struct lapb_register_struct lapbeth_callbacks = {
0309 .connect_confirmation = lapbeth_connected,
0310 .connect_indication = lapbeth_connected,
0311 .disconnect_confirmation = lapbeth_disconnected,
0312 .disconnect_indication = lapbeth_disconnected,
0313 .data_indication = lapbeth_data_indication,
0314 .data_transmit = lapbeth_data_transmit,
0315 };
0316
0317
0318
0319 static int lapbeth_open(struct net_device *dev)
0320 {
0321 struct lapbethdev *lapbeth = netdev_priv(dev);
0322 int err;
0323
0324 napi_enable(&lapbeth->napi);
0325
0326 err = lapb_register(dev, &lapbeth_callbacks);
0327 if (err != LAPB_OK) {
0328 pr_err("lapb_register error: %d\n", err);
0329 return -ENODEV;
0330 }
0331
0332 spin_lock_bh(&lapbeth->up_lock);
0333 lapbeth->up = true;
0334 spin_unlock_bh(&lapbeth->up_lock);
0335
0336 return 0;
0337 }
0338
0339 static int lapbeth_close(struct net_device *dev)
0340 {
0341 struct lapbethdev *lapbeth = netdev_priv(dev);
0342 int err;
0343
0344 spin_lock_bh(&lapbeth->up_lock);
0345 lapbeth->up = false;
0346 spin_unlock_bh(&lapbeth->up_lock);
0347
0348 err = lapb_unregister(dev);
0349 if (err != LAPB_OK)
0350 pr_err("lapb_unregister error: %d\n", err);
0351
0352 napi_disable(&lapbeth->napi);
0353
0354 return 0;
0355 }
0356
0357
0358
0359 static const struct net_device_ops lapbeth_netdev_ops = {
0360 .ndo_open = lapbeth_open,
0361 .ndo_stop = lapbeth_close,
0362 .ndo_start_xmit = lapbeth_xmit,
0363 .ndo_set_mac_address = lapbeth_set_mac_address,
0364 };
0365
0366 static void lapbeth_setup(struct net_device *dev)
0367 {
0368 dev->netdev_ops = &lapbeth_netdev_ops;
0369 dev->needs_free_netdev = true;
0370 dev->type = ARPHRD_X25;
0371 dev->hard_header_len = 0;
0372 dev->mtu = 1000;
0373 dev->addr_len = 0;
0374 }
0375
0376
0377
0378 static int lapbeth_new_device(struct net_device *dev)
0379 {
0380 struct net_device *ndev;
0381 struct lapbethdev *lapbeth;
0382 int rc = -ENOMEM;
0383
0384 ASSERT_RTNL();
0385
0386 ndev = alloc_netdev(sizeof(*lapbeth), "lapb%d", NET_NAME_UNKNOWN,
0387 lapbeth_setup);
0388 if (!ndev)
0389 goto out;
0390
0391
0392
0393
0394
0395
0396
0397 ndev->needed_headroom = -1 + 3 + 2 + dev->hard_header_len
0398 + dev->needed_headroom;
0399 ndev->needed_tailroom = dev->needed_tailroom;
0400
0401 lapbeth = netdev_priv(ndev);
0402 lapbeth->axdev = ndev;
0403
0404 dev_hold(dev);
0405 lapbeth->ethdev = dev;
0406
0407 lapbeth->up = false;
0408 spin_lock_init(&lapbeth->up_lock);
0409
0410 skb_queue_head_init(&lapbeth->rx_queue);
0411 netif_napi_add_weight(ndev, &lapbeth->napi, lapbeth_napi_poll, 16);
0412
0413 rc = -EIO;
0414 if (register_netdevice(ndev))
0415 goto fail;
0416
0417 list_add_rcu(&lapbeth->node, &lapbeth_devices);
0418 rc = 0;
0419 out:
0420 return rc;
0421 fail:
0422 dev_put(dev);
0423 free_netdev(ndev);
0424 goto out;
0425 }
0426
0427
0428
0429 static void lapbeth_free_device(struct lapbethdev *lapbeth)
0430 {
0431 dev_put(lapbeth->ethdev);
0432 list_del_rcu(&lapbeth->node);
0433 unregister_netdevice(lapbeth->axdev);
0434 }
0435
0436
0437
0438
0439
0440 static int lapbeth_device_event(struct notifier_block *this,
0441 unsigned long event, void *ptr)
0442 {
0443 struct lapbethdev *lapbeth;
0444 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
0445
0446 if (dev_net(dev) != &init_net)
0447 return NOTIFY_DONE;
0448
0449 if (!dev_is_ethdev(dev))
0450 return NOTIFY_DONE;
0451
0452 switch (event) {
0453 case NETDEV_UP:
0454
0455 if (!lapbeth_get_x25_dev(dev))
0456 lapbeth_new_device(dev);
0457 break;
0458 case NETDEV_GOING_DOWN:
0459
0460 lapbeth = lapbeth_get_x25_dev(dev);
0461 if (lapbeth)
0462 dev_close(lapbeth->axdev);
0463 break;
0464 case NETDEV_UNREGISTER:
0465
0466 lapbeth = lapbeth_get_x25_dev(dev);
0467 if (lapbeth)
0468 lapbeth_free_device(lapbeth);
0469 break;
0470 }
0471
0472 return NOTIFY_DONE;
0473 }
0474
0475
0476
0477 static struct packet_type lapbeth_packet_type __read_mostly = {
0478 .type = cpu_to_be16(ETH_P_DEC),
0479 .func = lapbeth_rcv,
0480 };
0481
0482 static struct notifier_block lapbeth_dev_notifier = {
0483 .notifier_call = lapbeth_device_event,
0484 };
0485
0486 static const char banner[] __initconst =
0487 KERN_INFO "LAPB Ethernet driver version 0.02\n";
0488
0489 static int __init lapbeth_init_driver(void)
0490 {
0491 dev_add_pack(&lapbeth_packet_type);
0492
0493 register_netdevice_notifier(&lapbeth_dev_notifier);
0494
0495 printk(banner);
0496
0497 return 0;
0498 }
0499 module_init(lapbeth_init_driver);
0500
0501 static void __exit lapbeth_cleanup_driver(void)
0502 {
0503 struct lapbethdev *lapbeth;
0504 struct list_head *entry, *tmp;
0505
0506 dev_remove_pack(&lapbeth_packet_type);
0507 unregister_netdevice_notifier(&lapbeth_dev_notifier);
0508
0509 rtnl_lock();
0510 list_for_each_safe(entry, tmp, &lapbeth_devices) {
0511 lapbeth = list_entry(entry, struct lapbethdev, node);
0512
0513 dev_put(lapbeth->ethdev);
0514 unregister_netdevice(lapbeth->axdev);
0515 }
0516 rtnl_unlock();
0517 }
0518 module_exit(lapbeth_cleanup_driver);
0519
0520 MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
0521 MODULE_DESCRIPTION("The unofficial LAPB over Ethernet driver");
0522 MODULE_LICENSE("GPL");