root/drivers/net/hamradio/bpqether.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bpq_get_ether_dev
  2. bpq_get_ax25_dev
  3. dev_is_ethdev
  4. bpq_rcv
  5. bpq_xmit
  6. bpq_set_mac_address
  7. bpq_ioctl
  8. bpq_open
  9. bpq_close
  10. bpq_seq_start
  11. bpq_seq_next
  12. bpq_seq_stop
  13. bpq_seq_show
  14. bpq_setup
  15. bpq_new_device
  16. bpq_free_device
  17. bpq_device_event
  18. bpq_init_driver
  19. bpq_cleanup_driver

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *      G8BPQ compatible "AX.25 via ethernet" driver release 004
   4  *
   5  *      This code REQUIRES 2.0.0 or higher/ NET3.029
   6  *
   7  *      This is a "pseudo" network driver to allow AX.25 over Ethernet
   8  *      using G8BPQ encapsulation. It has been extracted from the protocol
   9  *      implementation because
  10  *
  11  *              - things got unreadable within the protocol stack
  12  *              - to cure the protocol stack from "feature-ism"
  13  *              - a protocol implementation shouldn't need to know on
  14  *                which hardware it is running
  15  *              - user-level programs like the AX.25 utilities shouldn't
  16  *                need to know about the hardware.
  17  *              - IP over ethernet encapsulated AX.25 was impossible
  18  *              - rxecho.c did not work
  19  *              - to have room for extensions
  20  *              - it just deserves to "live" as an own driver
  21  *
  22  *      This driver can use any ethernet destination address, and can be
  23  *      limited to accept frames from one dedicated ethernet card only.
  24  *
  25  *      Note that the driver sets up the BPQ devices automagically on
  26  *      startup or (if started before the "insmod" of an ethernet device)
  27  *      on "ifconfig up". It hopefully will remove the BPQ on "rmmod"ing
  28  *      the ethernet device (in fact: as soon as another ethernet or bpq
  29  *      device gets "ifconfig"ured).
  30  *
  31  *      I have heard that several people are thinking of experiments
  32  *      with highspeed packet radio using existing ethernet cards.
  33  *      Well, this driver is prepared for this purpose, just add
  34  *      your tx key control and a txdelay / tailtime algorithm,
  35  *      probably some buffering, and /voila/...
  36  *
  37  *      History
  38  *      BPQ   001       Joerg(DL1BKE)           Extracted BPQ code from AX.25
  39  *                                              protocol stack and added my own
  40  *                                              yet existing patches
  41  *      BPQ   002       Joerg(DL1BKE)           Scan network device list on
  42  *                                              startup.
  43  *      BPQ   003       Joerg(DL1BKE)           Ethernet destination address
  44  *                                              and accepted source address
  45  *                                              can be configured by an ioctl()
  46  *                                              call.
  47  *                                              Fixed to match Linux networking
  48  *                                              changes - 2.1.15.
  49  *      BPQ   004       Joerg(DL1BKE)           Fixed to not lock up on ifconfig.
  50  */
  51 
  52 #include <linux/errno.h>
  53 #include <linux/types.h>
  54 #include <linux/socket.h>
  55 #include <linux/in.h>
  56 #include <linux/kernel.h>
  57 #include <linux/string.h>
  58 #include <linux/net.h>
  59 #include <linux/slab.h>
  60 #include <net/ax25.h>
  61 #include <linux/inet.h>
  62 #include <linux/netdevice.h>
  63 #include <linux/etherdevice.h>
  64 #include <linux/if_arp.h>
  65 #include <linux/skbuff.h>
  66 #include <net/sock.h>
  67 #include <linux/uaccess.h>
  68 #include <linux/mm.h>
  69 #include <linux/interrupt.h>
  70 #include <linux/notifier.h>
  71 #include <linux/proc_fs.h>
  72 #include <linux/seq_file.h>
  73 #include <linux/stat.h>
  74 #include <linux/module.h>
  75 #include <linux/init.h>
  76 #include <linux/rtnetlink.h>
  77 
  78 #include <net/ip.h>
  79 #include <net/arp.h>
  80 #include <net/net_namespace.h>
  81 
  82 #include <linux/bpqether.h>
  83 
  84 static const char banner[] __initconst = KERN_INFO \
  85         "AX.25: bpqether driver version 004\n";
  86 
  87 static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
  88 static int bpq_device_event(struct notifier_block *, unsigned long, void *);
  89 
  90 static struct packet_type bpq_packet_type __read_mostly = {
  91         .type   = cpu_to_be16(ETH_P_BPQ),
  92         .func   = bpq_rcv,
  93 };
  94 
  95 static struct notifier_block bpq_dev_notifier = {
  96         .notifier_call = bpq_device_event,
  97 };
  98 
  99 
 100 struct bpqdev {
 101         struct list_head bpq_list;      /* list of bpq devices chain */
 102         struct net_device *ethdev;      /* link to ethernet device */
 103         struct net_device *axdev;       /* bpq device (bpq#) */
 104         char   dest_addr[6];            /* ether destination address */
 105         char   acpt_addr[6];            /* accept ether frames from this address only */
 106 };
 107 
 108 static LIST_HEAD(bpq_devices);
 109 
 110 /* ------------------------------------------------------------------------ */
 111 
 112 
 113 /*
 114  *      Get the ethernet device for a BPQ device
 115  */
 116 static inline struct net_device *bpq_get_ether_dev(struct net_device *dev)
 117 {
 118         struct bpqdev *bpq = netdev_priv(dev);
 119 
 120         return bpq ? bpq->ethdev : NULL;
 121 }
 122 
 123 /*
 124  *      Get the BPQ device for the ethernet device
 125  */
 126 static inline struct net_device *bpq_get_ax25_dev(struct net_device *dev)
 127 {
 128         struct bpqdev *bpq;
 129 
 130         list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list,
 131                                 lockdep_rtnl_is_held()) {
 132                 if (bpq->ethdev == dev)
 133                         return bpq->axdev;
 134         }
 135         return NULL;
 136 }
 137 
 138 static inline int dev_is_ethdev(struct net_device *dev)
 139 {
 140         return dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5);
 141 }
 142 
 143 /* ------------------------------------------------------------------------ */
 144 
 145 
 146 /*
 147  *      Receive an AX.25 frame via an ethernet interface.
 148  */
 149 static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev)
 150 {
 151         int len;
 152         char * ptr;
 153         struct ethhdr *eth;
 154         struct bpqdev *bpq;
 155 
 156         if (!net_eq(dev_net(dev), &init_net))
 157                 goto drop;
 158 
 159         if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
 160                 return NET_RX_DROP;
 161 
 162         if (!pskb_may_pull(skb, sizeof(struct ethhdr)))
 163                 goto drop;
 164 
 165         rcu_read_lock();
 166         dev = bpq_get_ax25_dev(dev);
 167 
 168         if (dev == NULL || !netif_running(dev)) 
 169                 goto drop_unlock;
 170 
 171         /*
 172          * if we want to accept frames from just one ethernet device
 173          * we check the source address of the sender.
 174          */
 175 
 176         bpq = netdev_priv(dev);
 177 
 178         eth = eth_hdr(skb);
 179 
 180         if (!(bpq->acpt_addr[0] & 0x01) &&
 181             !ether_addr_equal(eth->h_source, bpq->acpt_addr))
 182                 goto drop_unlock;
 183 
 184         if (skb_cow(skb, sizeof(struct ethhdr)))
 185                 goto drop_unlock;
 186 
 187         len = skb->data[0] + skb->data[1] * 256 - 5;
 188 
 189         skb_pull(skb, 2);       /* Remove the length bytes */
 190         skb_trim(skb, len);     /* Set the length of the data */
 191 
 192         dev->stats.rx_packets++;
 193         dev->stats.rx_bytes += len;
 194 
 195         ptr = skb_push(skb, 1);
 196         *ptr = 0;
 197 
 198         skb->protocol = ax25_type_trans(skb, dev);
 199         netif_rx(skb);
 200 unlock:
 201 
 202         rcu_read_unlock();
 203 
 204         return 0;
 205 drop_unlock:
 206         kfree_skb(skb);
 207         goto unlock;
 208 
 209 drop:
 210         kfree_skb(skb);
 211         return 0;
 212 }
 213 
 214 /*
 215  *      Send an AX.25 frame via an ethernet interface
 216  */
 217 static netdev_tx_t bpq_xmit(struct sk_buff *skb, struct net_device *dev)
 218 {
 219         unsigned char *ptr;
 220         struct bpqdev *bpq;
 221         struct net_device *orig_dev;
 222         int size;
 223 
 224         if (skb->protocol == htons(ETH_P_IP))
 225                 return ax25_ip_xmit(skb);
 226 
 227         /*
 228          * Just to be *really* sure not to send anything if the interface
 229          * is down, the ethernet device may have gone.
 230          */
 231         if (!netif_running(dev)) {
 232                 kfree_skb(skb);
 233                 return NETDEV_TX_OK;
 234         }
 235 
 236         skb_pull(skb, 1);                       /* Drop KISS byte */
 237         size = skb->len;
 238 
 239         /*
 240          * We're about to mess with the skb which may still shared with the
 241          * generic networking code so unshare and ensure it's got enough
 242          * space for the BPQ headers.
 243          */
 244         if (skb_cow(skb, AX25_BPQ_HEADER_LEN)) {
 245                 if (net_ratelimit())
 246                         pr_err("bpqether: out of memory\n");
 247                 kfree_skb(skb);
 248 
 249                 return NETDEV_TX_OK;
 250         }
 251 
 252         ptr = skb_push(skb, 2);                 /* Make space for length */
 253 
 254         *ptr++ = (size + 5) % 256;
 255         *ptr++ = (size + 5) / 256;
 256 
 257         bpq = netdev_priv(dev);
 258 
 259         orig_dev = dev;
 260         if ((dev = bpq_get_ether_dev(dev)) == NULL) {
 261                 orig_dev->stats.tx_dropped++;
 262                 kfree_skb(skb);
 263                 return NETDEV_TX_OK;
 264         }
 265 
 266         skb->protocol = ax25_type_trans(skb, dev);
 267         skb_reset_network_header(skb);
 268         dev_hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
 269         dev->stats.tx_packets++;
 270         dev->stats.tx_bytes+=skb->len;
 271   
 272         dev_queue_xmit(skb);
 273         netif_wake_queue(dev);
 274         return NETDEV_TX_OK;
 275 }
 276 
 277 /*
 278  *      Set AX.25 callsign
 279  */
 280 static int bpq_set_mac_address(struct net_device *dev, void *addr)
 281 {
 282     struct sockaddr *sa = (struct sockaddr *)addr;
 283 
 284     memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
 285 
 286     return 0;
 287 }
 288 
 289 /*      Ioctl commands
 290  *
 291  *              SIOCSBPQETHOPT          reserved for enhancements
 292  *              SIOCSBPQETHADDR         set the destination and accepted
 293  *                                      source ethernet address (broadcast
 294  *                                      or multicast: accept all)
 295  */
 296 static int bpq_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 297 {
 298         struct bpq_ethaddr __user *ethaddr = ifr->ifr_data;
 299         struct bpqdev *bpq = netdev_priv(dev);
 300         struct bpq_req req;
 301 
 302         if (!capable(CAP_NET_ADMIN))
 303                 return -EPERM;
 304 
 305         switch (cmd) {
 306                 case SIOCSBPQETHOPT:
 307                         if (copy_from_user(&req, ifr->ifr_data, sizeof(struct bpq_req)))
 308                                 return -EFAULT;
 309                         switch (req.cmd) {
 310                                 case SIOCGBPQETHPARAM:
 311                                 case SIOCSBPQETHPARAM:
 312                                 default:
 313                                         return -EINVAL;
 314                         }
 315 
 316                         break;
 317 
 318                 case SIOCSBPQETHADDR:
 319                         if (copy_from_user(bpq->dest_addr, ethaddr->destination, ETH_ALEN))
 320                                 return -EFAULT;
 321                         if (copy_from_user(bpq->acpt_addr, ethaddr->accept, ETH_ALEN))
 322                                 return -EFAULT;
 323                         break;
 324 
 325                 default:
 326                         return -EINVAL;
 327         }
 328 
 329         return 0;
 330 }
 331 
 332 /*
 333  * open/close a device
 334  */
 335 static int bpq_open(struct net_device *dev)
 336 {
 337         netif_start_queue(dev);
 338         return 0;
 339 }
 340 
 341 static int bpq_close(struct net_device *dev)
 342 {
 343         netif_stop_queue(dev);
 344         return 0;
 345 }
 346 
 347 
 348 /* ------------------------------------------------------------------------ */
 349 
 350 
 351 /*
 352  *      Proc filesystem
 353  */
 354 static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
 355         __acquires(RCU)
 356 {
 357         int i = 1;
 358         struct bpqdev *bpqdev;
 359 
 360         rcu_read_lock();
 361 
 362         if (*pos == 0)
 363                 return SEQ_START_TOKEN;
 364         
 365         list_for_each_entry_rcu(bpqdev, &bpq_devices, bpq_list) {
 366                 if (i == *pos)
 367                         return bpqdev;
 368         }
 369         return NULL;
 370 }
 371 
 372 static void *bpq_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 373 {
 374         struct list_head *p;
 375         struct bpqdev *bpqdev = v;
 376 
 377         ++*pos;
 378 
 379         if (v == SEQ_START_TOKEN)
 380                 p = rcu_dereference(list_next_rcu(&bpq_devices));
 381         else
 382                 p = rcu_dereference(list_next_rcu(&bpqdev->bpq_list));
 383 
 384         return (p == &bpq_devices) ? NULL 
 385                 : list_entry(p, struct bpqdev, bpq_list);
 386 }
 387 
 388 static void bpq_seq_stop(struct seq_file *seq, void *v)
 389         __releases(RCU)
 390 {
 391         rcu_read_unlock();
 392 }
 393 
 394 
 395 static int bpq_seq_show(struct seq_file *seq, void *v)
 396 {
 397         if (v == SEQ_START_TOKEN)
 398                 seq_puts(seq, 
 399                          "dev   ether      destination        accept from\n");
 400         else {
 401                 const struct bpqdev *bpqdev = v;
 402 
 403                 seq_printf(seq, "%-5s %-10s %pM  ",
 404                         bpqdev->axdev->name, bpqdev->ethdev->name,
 405                         bpqdev->dest_addr);
 406 
 407                 if (is_multicast_ether_addr(bpqdev->acpt_addr))
 408                         seq_printf(seq, "*\n");
 409                 else
 410                         seq_printf(seq, "%pM\n", bpqdev->acpt_addr);
 411 
 412         }
 413         return 0;
 414 }
 415 
 416 static const struct seq_operations bpq_seqops = {
 417         .start = bpq_seq_start,
 418         .next = bpq_seq_next,
 419         .stop = bpq_seq_stop,
 420         .show = bpq_seq_show,
 421 };
 422 
 423 /* ------------------------------------------------------------------------ */
 424 
 425 static const struct net_device_ops bpq_netdev_ops = {
 426         .ndo_open            = bpq_open,
 427         .ndo_stop            = bpq_close,
 428         .ndo_start_xmit      = bpq_xmit,
 429         .ndo_set_mac_address = bpq_set_mac_address,
 430         .ndo_do_ioctl        = bpq_ioctl,
 431 };
 432 
 433 static void bpq_setup(struct net_device *dev)
 434 {
 435         dev->netdev_ops      = &bpq_netdev_ops;
 436         dev->needs_free_netdev = true;
 437 
 438         memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
 439         memcpy(dev->dev_addr,  &ax25_defaddr, AX25_ADDR_LEN);
 440 
 441         dev->flags      = 0;
 442         dev->features   = NETIF_F_LLTX; /* Allow recursion */
 443 
 444 #if IS_ENABLED(CONFIG_AX25)
 445         dev->header_ops      = &ax25_header_ops;
 446 #endif
 447 
 448         dev->type            = ARPHRD_AX25;
 449         dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
 450         dev->mtu             = AX25_DEF_PACLEN;
 451         dev->addr_len        = AX25_ADDR_LEN;
 452 
 453 }
 454 
 455 /*
 456  *      Setup a new device.
 457  */
 458 static int bpq_new_device(struct net_device *edev)
 459 {
 460         int err;
 461         struct net_device *ndev;
 462         struct bpqdev *bpq;
 463 
 464         ndev = alloc_netdev(sizeof(struct bpqdev), "bpq%d", NET_NAME_UNKNOWN,
 465                             bpq_setup);
 466         if (!ndev)
 467                 return -ENOMEM;
 468 
 469                 
 470         bpq = netdev_priv(ndev);
 471         dev_hold(edev);
 472         bpq->ethdev = edev;
 473         bpq->axdev = ndev;
 474 
 475         eth_broadcast_addr(bpq->dest_addr);
 476         eth_broadcast_addr(bpq->acpt_addr);
 477 
 478         err = register_netdevice(ndev);
 479         if (err)
 480                 goto error;
 481 
 482         /* List protected by RTNL */
 483         list_add_rcu(&bpq->bpq_list, &bpq_devices);
 484         return 0;
 485 
 486  error:
 487         dev_put(edev);
 488         free_netdev(ndev);
 489         return err;
 490         
 491 }
 492 
 493 static void bpq_free_device(struct net_device *ndev)
 494 {
 495         struct bpqdev *bpq = netdev_priv(ndev);
 496 
 497         dev_put(bpq->ethdev);
 498         list_del_rcu(&bpq->bpq_list);
 499 
 500         unregister_netdevice(ndev);
 501 }
 502 
 503 /*
 504  *      Handle device status changes.
 505  */
 506 static int bpq_device_event(struct notifier_block *this,
 507                             unsigned long event, void *ptr)
 508 {
 509         struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 510 
 511         if (!net_eq(dev_net(dev), &init_net))
 512                 return NOTIFY_DONE;
 513 
 514         if (!dev_is_ethdev(dev))
 515                 return NOTIFY_DONE;
 516 
 517         switch (event) {
 518         case NETDEV_UP:         /* new ethernet device -> new BPQ interface */
 519                 if (bpq_get_ax25_dev(dev) == NULL)
 520                         bpq_new_device(dev);
 521                 break;
 522 
 523         case NETDEV_DOWN:       /* ethernet device closed -> close BPQ interface */
 524                 if ((dev = bpq_get_ax25_dev(dev)) != NULL)
 525                         dev_close(dev);
 526                 break;
 527 
 528         case NETDEV_UNREGISTER: /* ethernet device removed -> free BPQ interface */
 529                 if ((dev = bpq_get_ax25_dev(dev)) != NULL)
 530                         bpq_free_device(dev);
 531                 break;
 532         default:
 533                 break;
 534         }
 535 
 536         return NOTIFY_DONE;
 537 }
 538 
 539 
 540 /* ------------------------------------------------------------------------ */
 541 
 542 /*
 543  * Initialize driver. To be called from af_ax25 if not compiled as a
 544  * module
 545  */
 546 static int __init bpq_init_driver(void)
 547 {
 548 #ifdef CONFIG_PROC_FS
 549         if (!proc_create_seq("bpqether", 0444, init_net.proc_net, &bpq_seqops)) {
 550                 printk(KERN_ERR
 551                         "bpq: cannot create /proc/net/bpqether entry.\n");
 552                 return -ENOENT;
 553         }
 554 #endif  /* CONFIG_PROC_FS */
 555 
 556         dev_add_pack(&bpq_packet_type);
 557 
 558         register_netdevice_notifier(&bpq_dev_notifier);
 559 
 560         printk(banner);
 561 
 562         return 0;
 563 }
 564 
 565 static void __exit bpq_cleanup_driver(void)
 566 {
 567         struct bpqdev *bpq;
 568 
 569         dev_remove_pack(&bpq_packet_type);
 570 
 571         unregister_netdevice_notifier(&bpq_dev_notifier);
 572 
 573         remove_proc_entry("bpqether", init_net.proc_net);
 574 
 575         rtnl_lock();
 576         while (!list_empty(&bpq_devices)) {
 577                 bpq = list_entry(bpq_devices.next, struct bpqdev, bpq_list);
 578                 bpq_free_device(bpq->axdev);
 579         }
 580         rtnl_unlock();
 581 }
 582 
 583 MODULE_AUTHOR("Joerg Reuter DL1BKE <jreuter@yaina.de>");
 584 MODULE_DESCRIPTION("Transmit and receive AX.25 packets over Ethernet");
 585 MODULE_LICENSE("GPL");
 586 module_init(bpq_init_driver);
 587 module_exit(bpq_cleanup_driver);

/* [<][>][^][v][top][bottom][index][help] */