1/* 2 * Generic HDLC support routines for Linux 3 * 4 * Copyright (C) 1999 - 2008 Krzysztof Halasa <khc@pm.waw.pl> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of version 2 of the GNU General Public License 8 * as published by the Free Software Foundation. 9 * 10 * Currently supported: 11 * * raw IP-in-HDLC 12 * * Cisco HDLC 13 * * Frame Relay with ANSI or CCITT LMI (both user and network side) 14 * * PPP 15 * * X.25 16 * 17 * Use sethdlc utility to set line parameters, protocol and PVCs 18 * 19 * How does it work: 20 * - proto->open(), close(), start(), stop() calls are serialized. 21 * The order is: open, [ start, stop ... ] close ... 22 * - proto->start() and stop() are called with spin_lock_irq held. 23 */ 24 25#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 26 27#include <linux/errno.h> 28#include <linux/hdlc.h> 29#include <linux/if_arp.h> 30#include <linux/inetdevice.h> 31#include <linux/init.h> 32#include <linux/kernel.h> 33#include <linux/module.h> 34#include <linux/notifier.h> 35#include <linux/pkt_sched.h> 36#include <linux/poll.h> 37#include <linux/rtnetlink.h> 38#include <linux/skbuff.h> 39#include <linux/slab.h> 40#include <net/net_namespace.h> 41 42 43static const char* version = "HDLC support module revision 1.22"; 44 45#undef DEBUG_LINK 46 47static struct hdlc_proto *first_proto; 48 49int hdlc_change_mtu(struct net_device *dev, int new_mtu) 50{ 51 if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU)) 52 return -EINVAL; 53 dev->mtu = new_mtu; 54 return 0; 55} 56 57static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, 58 struct packet_type *p, struct net_device *orig_dev) 59{ 60 struct hdlc_device *hdlc = dev_to_hdlc(dev); 61 62 if (!net_eq(dev_net(dev), &init_net)) { 63 kfree_skb(skb); 64 return 0; 65 } 66 67 BUG_ON(!hdlc->proto->netif_rx); 68 return hdlc->proto->netif_rx(skb); 69} 70 71netdev_tx_t hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev) 72{ 73 hdlc_device *hdlc = dev_to_hdlc(dev); 74 75 if (hdlc->proto->xmit) 76 return hdlc->proto->xmit(skb, dev); 77 78 return hdlc->xmit(skb, dev); /* call hardware driver directly */ 79} 80 81static inline void hdlc_proto_start(struct net_device *dev) 82{ 83 hdlc_device *hdlc = dev_to_hdlc(dev); 84 if (hdlc->proto->start) 85 hdlc->proto->start(dev); 86} 87 88 89 90static inline void hdlc_proto_stop(struct net_device *dev) 91{ 92 hdlc_device *hdlc = dev_to_hdlc(dev); 93 if (hdlc->proto->stop) 94 hdlc->proto->stop(dev); 95} 96 97 98 99static int hdlc_device_event(struct notifier_block *this, unsigned long event, 100 void *ptr) 101{ 102 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 103 hdlc_device *hdlc; 104 unsigned long flags; 105 int on; 106 107 if (!net_eq(dev_net(dev), &init_net)) 108 return NOTIFY_DONE; 109 110 if (!(dev->priv_flags & IFF_WAN_HDLC)) 111 return NOTIFY_DONE; /* not an HDLC device */ 112 113 if (event != NETDEV_CHANGE) 114 return NOTIFY_DONE; /* Only interested in carrier changes */ 115 116 on = netif_carrier_ok(dev); 117 118#ifdef DEBUG_LINK 119 printk(KERN_DEBUG "%s: hdlc_device_event NETDEV_CHANGE, carrier %i\n", 120 dev->name, on); 121#endif 122 123 hdlc = dev_to_hdlc(dev); 124 spin_lock_irqsave(&hdlc->state_lock, flags); 125 126 if (hdlc->carrier == on) 127 goto carrier_exit; /* no change in DCD line level */ 128 129 hdlc->carrier = on; 130 131 if (!hdlc->open) 132 goto carrier_exit; 133 134 if (hdlc->carrier) { 135 netdev_info(dev, "Carrier detected\n"); 136 hdlc_proto_start(dev); 137 } else { 138 netdev_info(dev, "Carrier lost\n"); 139 hdlc_proto_stop(dev); 140 } 141 142carrier_exit: 143 spin_unlock_irqrestore(&hdlc->state_lock, flags); 144 return NOTIFY_DONE; 145} 146 147 148 149/* Must be called by hardware driver when HDLC device is being opened */ 150int hdlc_open(struct net_device *dev) 151{ 152 hdlc_device *hdlc = dev_to_hdlc(dev); 153#ifdef DEBUG_LINK 154 printk(KERN_DEBUG "%s: hdlc_open() carrier %i open %i\n", dev->name, 155 hdlc->carrier, hdlc->open); 156#endif 157 158 if (hdlc->proto == NULL) 159 return -ENOSYS; /* no protocol attached */ 160 161 if (hdlc->proto->open) { 162 int result = hdlc->proto->open(dev); 163 if (result) 164 return result; 165 } 166 167 spin_lock_irq(&hdlc->state_lock); 168 169 if (hdlc->carrier) { 170 netdev_info(dev, "Carrier detected\n"); 171 hdlc_proto_start(dev); 172 } else 173 netdev_info(dev, "No carrier\n"); 174 175 hdlc->open = 1; 176 177 spin_unlock_irq(&hdlc->state_lock); 178 return 0; 179} 180 181 182 183/* Must be called by hardware driver when HDLC device is being closed */ 184void hdlc_close(struct net_device *dev) 185{ 186 hdlc_device *hdlc = dev_to_hdlc(dev); 187#ifdef DEBUG_LINK 188 printk(KERN_DEBUG "%s: hdlc_close() carrier %i open %i\n", dev->name, 189 hdlc->carrier, hdlc->open); 190#endif 191 192 spin_lock_irq(&hdlc->state_lock); 193 194 hdlc->open = 0; 195 if (hdlc->carrier) 196 hdlc_proto_stop(dev); 197 198 spin_unlock_irq(&hdlc->state_lock); 199 200 if (hdlc->proto->close) 201 hdlc->proto->close(dev); 202} 203 204 205 206int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 207{ 208 struct hdlc_proto *proto = first_proto; 209 int result; 210 211 if (cmd != SIOCWANDEV) 212 return -EINVAL; 213 214 if (dev_to_hdlc(dev)->proto) { 215 result = dev_to_hdlc(dev)->proto->ioctl(dev, ifr); 216 if (result != -EINVAL) 217 return result; 218 } 219 220 /* Not handled by currently attached protocol (if any) */ 221 222 while (proto) { 223 if ((result = proto->ioctl(dev, ifr)) != -EINVAL) 224 return result; 225 proto = proto->next; 226 } 227 return -EINVAL; 228} 229 230static const struct header_ops hdlc_null_ops; 231 232static void hdlc_setup_dev(struct net_device *dev) 233{ 234 /* Re-init all variables changed by HDLC protocol drivers, 235 * including ether_setup() called from hdlc_raw_eth.c. 236 */ 237 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 238 dev->priv_flags = IFF_WAN_HDLC; 239 dev->mtu = HDLC_MAX_MTU; 240 dev->type = ARPHRD_RAWHDLC; 241 dev->hard_header_len = 16; 242 dev->addr_len = 0; 243 dev->header_ops = &hdlc_null_ops; 244} 245 246static void hdlc_setup(struct net_device *dev) 247{ 248 hdlc_device *hdlc = dev_to_hdlc(dev); 249 250 hdlc_setup_dev(dev); 251 hdlc->carrier = 1; 252 hdlc->open = 0; 253 spin_lock_init(&hdlc->state_lock); 254} 255 256struct net_device *alloc_hdlcdev(void *priv) 257{ 258 struct net_device *dev; 259 dev = alloc_netdev(sizeof(struct hdlc_device), "hdlc%d", 260 NET_NAME_UNKNOWN, hdlc_setup); 261 if (dev) 262 dev_to_hdlc(dev)->priv = priv; 263 return dev; 264} 265 266void unregister_hdlc_device(struct net_device *dev) 267{ 268 rtnl_lock(); 269 unregister_netdevice(dev); 270 detach_hdlc_protocol(dev); 271 rtnl_unlock(); 272} 273 274 275 276int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto, 277 size_t size) 278{ 279 detach_hdlc_protocol(dev); 280 281 if (!try_module_get(proto->module)) 282 return -ENOSYS; 283 284 if (size) { 285 dev_to_hdlc(dev)->state = kmalloc(size, GFP_KERNEL); 286 if (dev_to_hdlc(dev)->state == NULL) { 287 module_put(proto->module); 288 return -ENOBUFS; 289 } 290 } 291 dev_to_hdlc(dev)->proto = proto; 292 return 0; 293} 294 295 296void detach_hdlc_protocol(struct net_device *dev) 297{ 298 hdlc_device *hdlc = dev_to_hdlc(dev); 299 300 if (hdlc->proto) { 301 if (hdlc->proto->detach) 302 hdlc->proto->detach(dev); 303 module_put(hdlc->proto->module); 304 hdlc->proto = NULL; 305 } 306 kfree(hdlc->state); 307 hdlc->state = NULL; 308 hdlc_setup_dev(dev); 309} 310 311 312void register_hdlc_protocol(struct hdlc_proto *proto) 313{ 314 rtnl_lock(); 315 proto->next = first_proto; 316 first_proto = proto; 317 rtnl_unlock(); 318} 319 320 321void unregister_hdlc_protocol(struct hdlc_proto *proto) 322{ 323 struct hdlc_proto **p; 324 325 rtnl_lock(); 326 p = &first_proto; 327 while (*p != proto) { 328 BUG_ON(!*p); 329 p = &((*p)->next); 330 } 331 *p = proto->next; 332 rtnl_unlock(); 333} 334 335 336 337MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); 338MODULE_DESCRIPTION("HDLC support module"); 339MODULE_LICENSE("GPL v2"); 340 341EXPORT_SYMBOL(hdlc_change_mtu); 342EXPORT_SYMBOL(hdlc_start_xmit); 343EXPORT_SYMBOL(hdlc_open); 344EXPORT_SYMBOL(hdlc_close); 345EXPORT_SYMBOL(hdlc_ioctl); 346EXPORT_SYMBOL(alloc_hdlcdev); 347EXPORT_SYMBOL(unregister_hdlc_device); 348EXPORT_SYMBOL(register_hdlc_protocol); 349EXPORT_SYMBOL(unregister_hdlc_protocol); 350EXPORT_SYMBOL(attach_hdlc_protocol); 351EXPORT_SYMBOL(detach_hdlc_protocol); 352 353static struct packet_type hdlc_packet_type __read_mostly = { 354 .type = cpu_to_be16(ETH_P_HDLC), 355 .func = hdlc_rcv, 356}; 357 358 359static struct notifier_block hdlc_notifier = { 360 .notifier_call = hdlc_device_event, 361}; 362 363 364static int __init hdlc_module_init(void) 365{ 366 int result; 367 368 pr_info("%s\n", version); 369 if ((result = register_netdevice_notifier(&hdlc_notifier)) != 0) 370 return result; 371 dev_add_pack(&hdlc_packet_type); 372 return 0; 373} 374 375 376 377static void __exit hdlc_module_exit(void) 378{ 379 dev_remove_pack(&hdlc_packet_type); 380 unregister_netdevice_notifier(&hdlc_notifier); 381} 382 383 384module_init(hdlc_module_init); 385module_exit(hdlc_module_exit); 386