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 = NULL; 47 48 49 static int 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 57 58 59 static struct net_device_stats *hdlc_get_stats(struct net_device *dev) 60 { 61 return hdlc_stats(dev); 62 } 63 64 65 66 static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, 67 struct packet_type *p, struct net_device *orig_dev) 68 { 69 struct hdlc_device *hdlc = dev_to_hdlc(dev); 70 71 if (dev->nd_net != &init_net) { 72 kfree_skb(skb); 73 return 0; 74 } 75 76 BUG_ON(!hdlc->proto->netif_rx); 77 return hdlc->proto->netif_rx(skb); 78 } 79 80 81 82 static inline void hdlc_proto_start(struct net_device *dev) 83 { 84 hdlc_device *hdlc = dev_to_hdlc(dev); 85 if (hdlc->proto->start) 86 hdlc->proto->start(dev); 87 } 88 89 90 91 static inline void hdlc_proto_stop(struct net_device *dev) 92 { 93 hdlc_device *hdlc = dev_to_hdlc(dev); 94 if (hdlc->proto->stop) 95 hdlc->proto->stop(dev); 96 } 97 98 99 100 static int hdlc_device_event(struct notifier_block *this, unsigned long event, 101 void *ptr) 102 { 103 struct net_device *dev = ptr; 104 hdlc_device *hdlc; 105 unsigned long flags; 106 int on; 107 108 if (dev->nd_net != &init_net) 109 return NOTIFY_DONE; 110 111 if (dev->get_stats != hdlc_get_stats) 112 return NOTIFY_DONE; /* not an HDLC device */ 113 114 if (event != NETDEV_CHANGE) 115 return NOTIFY_DONE; /* Only interrested in carrier changes */ 116 117 on = netif_carrier_ok(dev); 118 119 #ifdef DEBUG_LINK 120 printk(KERN_DEBUG "%s: hdlc_device_event NETDEV_CHANGE, carrier %i\n", 121 dev->name, on); 122 #endif 123 124 hdlc = dev_to_hdlc(dev); 125 spin_lock_irqsave(&hdlc->state_lock, flags); 126 127 if (hdlc->carrier == on) 128 goto carrier_exit; /* no change in DCD line level */ 129 130 hdlc->carrier = on; 131 132 if (!hdlc->open) 133 goto carrier_exit; 134 135 if (hdlc->carrier) { 136 printk(KERN_INFO "%s: Carrier detected\n", dev->name); 137 hdlc_proto_start(dev); 138 } else { 139 printk(KERN_INFO "%s: Carrier lost\n", dev->name); 140 hdlc_proto_stop(dev); 141 } 142 143 carrier_exit: 144 spin_unlock_irqrestore(&hdlc->state_lock, flags); 145 return NOTIFY_DONE; 146 } 147 148 149 150 /* Must be called by hardware driver when HDLC device is being opened */ 151 int hdlc_open(struct net_device *dev) 152 { 153 hdlc_device *hdlc = dev_to_hdlc(dev); 154 #ifdef DEBUG_LINK 155 printk(KERN_DEBUG "%s: hdlc_open() carrier %i open %i\n", dev->name, 156 hdlc->carrier, hdlc->open); 157 #endif 158 159 if (hdlc->proto == NULL) 160 return -ENOSYS; /* no protocol attached */ 161 162 if (hdlc->proto->open) { 163 int result = hdlc->proto->open(dev); 164 if (result) 165 return result; 166 } 167 168 spin_lock_irq(&hdlc->state_lock); 169 170 if (hdlc->carrier) { 171 printk(KERN_INFO "%s: Carrier detected\n", dev->name); 172 hdlc_proto_start(dev); 173 } else 174 printk(KERN_INFO "%s: No carrier\n", dev->name); 175 176 hdlc->open = 1; 177 178 spin_unlock_irq(&hdlc->state_lock); 179 return 0; 180 } 181 182 183 184 /* Must be called by hardware driver when HDLC device is being closed */ 185 void hdlc_close(struct net_device *dev) 186 { 187 hdlc_device *hdlc = dev_to_hdlc(dev); 188 #ifdef DEBUG_LINK 189 printk(KERN_DEBUG "%s: hdlc_close() carrier %i open %i\n", dev->name, 190 hdlc->carrier, hdlc->open); 191 #endif 192 193 spin_lock_irq(&hdlc->state_lock); 194 195 hdlc->open = 0; 196 if (hdlc->carrier) 197 hdlc_proto_stop(dev); 198 199 spin_unlock_irq(&hdlc->state_lock); 200 201 if (hdlc->proto->close) 202 hdlc->proto->close(dev); 203 } 204 205 206 207 int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 208 { 209 struct hdlc_proto *proto = first_proto; 210 int result; 211 212 if (cmd != SIOCWANDEV) 213 return -EINVAL; 214 215 if (dev_to_hdlc(dev)->proto) { 216 result = dev_to_hdlc(dev)->proto->ioctl(dev, ifr); 217 if (result != -EINVAL) 218 return result; 219 } 220 221 /* Not handled by currently attached protocol (if any) */ 222 223 while (proto) { 224 if ((result = proto->ioctl(dev, ifr)) != -EINVAL) 225 return result; 226 proto = proto->next; 227 } 228 return -EINVAL; 229 } 230 231 static const struct header_ops hdlc_null_ops; 232 233 static void hdlc_setup_dev(struct net_device *dev) 234 { 235 /* Re-init all variables changed by HDLC protocol drivers, 236 * including ether_setup() called from hdlc_raw_eth.c. 237 */ 238 dev->get_stats = hdlc_get_stats; 239 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 240 dev->mtu = HDLC_MAX_MTU; 241 dev->type = ARPHRD_RAWHDLC; 242 dev->hard_header_len = 16; 243 dev->addr_len = 0; 244 dev->header_ops = &hdlc_null_ops; 245 246 dev->change_mtu = hdlc_change_mtu; 247 } 248 249 static void hdlc_setup(struct net_device *dev) 250 { 251 hdlc_device *hdlc = dev_to_hdlc(dev); 252 253 hdlc_setup_dev(dev); 254 hdlc->carrier = 1; 255 hdlc->open = 0; 256 spin_lock_init(&hdlc->state_lock); 257 } 258 259 struct net_device *alloc_hdlcdev(void *priv) 260 { 261 struct net_device *dev; 262 dev = alloc_netdev(sizeof(struct hdlc_device), "hdlc%d", hdlc_setup); 263 if (dev) 264 dev_to_hdlc(dev)->priv = priv; 265 return dev; 266 } 267 268 void unregister_hdlc_device(struct net_device *dev) 269 { 270 rtnl_lock(); 271 unregister_netdevice(dev); 272 detach_hdlc_protocol(dev); 273 rtnl_unlock(); 274 } 275 276 277 278 int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto, 279 size_t size) 280 { 281 detach_hdlc_protocol(dev); 282 283 if (!try_module_get(proto->module)) 284 return -ENOSYS; 285 286 if (size) 287 if ((dev_to_hdlc(dev)->state = kmalloc(size, 288 GFP_KERNEL)) == NULL) { 289 printk(KERN_WARNING "Memory squeeze on" 290 " hdlc_proto_attach()\n"); 291 module_put(proto->module); 292 return -ENOBUFS; 293 } 294 dev_to_hdlc(dev)->proto = proto; 295 return 0; 296 } 297 298 299 void detach_hdlc_protocol(struct net_device *dev) 300 { 301 hdlc_device *hdlc = dev_to_hdlc(dev); 302 303 if (hdlc->proto) { 304 if (hdlc->proto->detach) 305 hdlc->proto->detach(dev); 306 module_put(hdlc->proto->module); 307 hdlc->proto = NULL; 308 } 309 kfree(hdlc->state); 310 hdlc->state = NULL; 311 hdlc_setup_dev(dev); 312 } 313 314 315 void register_hdlc_protocol(struct hdlc_proto *proto) 316 { 317 proto->next = first_proto; 318 first_proto = proto; 319 } 320 321 322 void unregister_hdlc_protocol(struct hdlc_proto *proto) 323 { 324 struct hdlc_proto **p = &first_proto; 325 while (*p) { 326 if (*p == proto) { 327 *p = proto->next; 328 return; 329 } 330 p = &((*p)->next); 331 } 332 } 333 334 335 336 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); 337 MODULE_DESCRIPTION("HDLC support module"); 338 MODULE_LICENSE("GPL v2"); 339 340 EXPORT_SYMBOL(hdlc_open); 341 EXPORT_SYMBOL(hdlc_close); 342 EXPORT_SYMBOL(hdlc_ioctl); 343 EXPORT_SYMBOL(alloc_hdlcdev); 344 EXPORT_SYMBOL(unregister_hdlc_device); 345 EXPORT_SYMBOL(register_hdlc_protocol); 346 EXPORT_SYMBOL(unregister_hdlc_protocol); 347 EXPORT_SYMBOL(attach_hdlc_protocol); 348 EXPORT_SYMBOL(detach_hdlc_protocol); 349 350 static struct packet_type hdlc_packet_type = { 351 .type = __constant_htons(ETH_P_HDLC), 352 .func = hdlc_rcv, 353 }; 354 355 356 static struct notifier_block hdlc_notifier = { 357 .notifier_call = hdlc_device_event, 358 }; 359 360 361 static int __init hdlc_module_init(void) 362 { 363 int result; 364 365 printk(KERN_INFO "%s\n", version); 366 if ((result = register_netdevice_notifier(&hdlc_notifier)) != 0) 367 return result; 368 dev_add_pack(&hdlc_packet_type); 369 return 0; 370 } 371 372 373 374 static void __exit hdlc_module_exit(void) 375 { 376 dev_remove_pack(&hdlc_packet_type); 377 unregister_netdevice_notifier(&hdlc_notifier); 378 } 379 380 381 module_init(hdlc_module_init); 382 module_exit(hdlc_module_exit); 383