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 #include <linux/module.h> 26 #include <linux/kernel.h> 27 #include <linux/slab.h> 28 #include <linux/poll.h> 29 #include <linux/errno.h> 30 #include <linux/if_arp.h> 31 #include <linux/init.h> 32 #include <linux/skbuff.h> 33 #include <linux/pkt_sched.h> 34 #include <linux/inetdevice.h> 35 #include <linux/lapb.h> 36 #include <linux/rtnetlink.h> 37 #include <linux/notifier.h> 38 #include <linux/hdlc.h> 39 #include <net/net_namespace.h> 40 41 42 static const char* version = "HDLC support module revision 1.22"; 43 44 #undef DEBUG_LINK 45 46 static struct hdlc_proto *first_proto; 47 48 static int hdlc_change_mtu(struct net_device *dev, int new_mtu) 49 { 50 if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU)) 51 return -EINVAL; 52 dev->mtu = new_mtu; 53 return 0; 54 } 55 56 57 58 static struct net_device_stats *hdlc_get_stats(struct net_device *dev) 59 { 60 return &dev->stats; 61 } 62 63 64 65 static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, 66 struct packet_type *p, struct net_device *orig_dev) 67 { 68 struct hdlc_device *hdlc = dev_to_hdlc(dev); 69 70 if (dev_net(dev) != &init_net) { 71 kfree_skb(skb); 72 return 0; 73 } 74 75 BUG_ON(!hdlc->proto->netif_rx); 76 return hdlc->proto->netif_rx(skb); 77 } 78 79 80 81 static 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 90 static 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 99 static int hdlc_device_event(struct notifier_block *this, unsigned long event, 100 void *ptr) 101 { 102 struct net_device *dev = ptr; 103 hdlc_device *hdlc; 104 unsigned long flags; 105 int on; 106 107 if (dev_net(dev) != &init_net) 108 return NOTIFY_DONE; 109 110 if (dev->get_stats != hdlc_get_stats) 111 return NOTIFY_DONE; /* not an HDLC device */ 112 113 if (event != NETDEV_CHANGE) 114 return NOTIFY_DONE; /* Only interrested 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 printk(KERN_INFO "%s: Carrier detected\n", dev->name); 136 hdlc_proto_start(dev); 137 } else { 138 printk(KERN_INFO "%s: Carrier lost\n", dev->name); 139 hdlc_proto_stop(dev); 140 } 141 142 carrier_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 */ 150 int 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 printk(KERN_INFO "%s: Carrier detected\n", dev->name); 171 hdlc_proto_start(dev); 172 } else 173 printk(KERN_INFO "%s: No carrier\n", dev->name); 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 */ 184 void 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 206 int 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 230 static const struct header_ops hdlc_null_ops; 231 232 static 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->get_stats = hdlc_get_stats; 238 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 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 dev->change_mtu = hdlc_change_mtu; 246 } 247 248 static void hdlc_setup(struct net_device *dev) 249 { 250 hdlc_device *hdlc = dev_to_hdlc(dev); 251 252 hdlc_setup_dev(dev); 253 hdlc->carrier = 1; 254 hdlc->open = 0; 255 spin_lock_init(&hdlc->state_lock); 256 } 257 258 struct net_device *alloc_hdlcdev(void *priv) 259 { 260 struct net_device *dev; 261 dev = alloc_netdev(sizeof(struct hdlc_device), "hdlc%d", hdlc_setup); 262 if (dev) 263 dev_to_hdlc(dev)->priv = priv; 264 return dev; 265 } 266 267 void unregister_hdlc_device(struct net_device *dev) 268 { 269 rtnl_lock(); 270 unregister_netdevice(dev); 271 detach_hdlc_protocol(dev); 272 rtnl_unlock(); 273 } 274 275 276 277 int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto, 278 size_t size) 279 { 280 detach_hdlc_protocol(dev); 281 282 if (!try_module_get(proto->module)) 283 return -ENOSYS; 284 285 if (size) 286 if ((dev_to_hdlc(dev)->state = kmalloc(size, 287 GFP_KERNEL)) == NULL) { 288 printk(KERN_WARNING "Memory squeeze on" 289 " hdlc_proto_attach()\n"); 290 module_put(proto->module); 291 return -ENOBUFS; 292 } 293 dev_to_hdlc(dev)->proto = proto; 294 return 0; 295 } 296 297 298 void detach_hdlc_protocol(struct net_device *dev) 299 { 300 hdlc_device *hdlc = dev_to_hdlc(dev); 301 302 if (hdlc->proto) { 303 if (hdlc->proto->detach) 304 hdlc->proto->detach(dev); 305 module_put(hdlc->proto->module); 306 hdlc->proto = NULL; 307 } 308 kfree(hdlc->state); 309 hdlc->state = NULL; 310 hdlc_setup_dev(dev); 311 } 312 313 314 void register_hdlc_protocol(struct hdlc_proto *proto) 315 { 316 rtnl_lock(); 317 proto->next = first_proto; 318 first_proto = proto; 319 rtnl_unlock(); 320 } 321 322 323 void unregister_hdlc_protocol(struct hdlc_proto *proto) 324 { 325 struct hdlc_proto **p; 326 327 rtnl_lock(); 328 p = &first_proto; 329 while (*p != proto) { 330 BUG_ON(!*p); 331 p = &((*p)->next); 332 } 333 *p = proto->next; 334 rtnl_unlock(); 335 } 336 337 338 339 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); 340 MODULE_DESCRIPTION("HDLC support module"); 341 MODULE_LICENSE("GPL v2"); 342 343 EXPORT_SYMBOL(hdlc_open); 344 EXPORT_SYMBOL(hdlc_close); 345 EXPORT_SYMBOL(hdlc_ioctl); 346 EXPORT_SYMBOL(alloc_hdlcdev); 347 EXPORT_SYMBOL(unregister_hdlc_device); 348 EXPORT_SYMBOL(register_hdlc_protocol); 349 EXPORT_SYMBOL(unregister_hdlc_protocol); 350 EXPORT_SYMBOL(attach_hdlc_protocol); 351 EXPORT_SYMBOL(detach_hdlc_protocol); 352 353 static struct packet_type hdlc_packet_type = { 354 .type = __constant_htons(ETH_P_HDLC), 355 .func = hdlc_rcv, 356 }; 357 358 359 static struct notifier_block hdlc_notifier = { 360 .notifier_call = hdlc_device_event, 361 }; 362 363 364 static int __init hdlc_module_init(void) 365 { 366 int result; 367 368 printk(KERN_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 377 static void __exit hdlc_module_exit(void) 378 { 379 dev_remove_pack(&hdlc_packet_type); 380 unregister_netdevice_notifier(&hdlc_notifier); 381 } 382 383 384 module_init(hdlc_module_init); 385 module_exit(hdlc_module_exit); 386