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