0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0023
0024 #include <linux/errno.h>
0025 #include <linux/hdlc.h>
0026 #include <linux/if_arp.h>
0027 #include <linux/inetdevice.h>
0028 #include <linux/init.h>
0029 #include <linux/kernel.h>
0030 #include <linux/module.h>
0031 #include <linux/notifier.h>
0032 #include <linux/pkt_sched.h>
0033 #include <linux/poll.h>
0034 #include <linux/rtnetlink.h>
0035 #include <linux/skbuff.h>
0036 #include <linux/slab.h>
0037 #include <net/net_namespace.h>
0038
0039 static const char *version = "HDLC support module revision 1.22";
0040
0041 #undef DEBUG_LINK
0042
0043 static struct hdlc_proto *first_proto;
0044
0045 static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
0046 struct packet_type *p, struct net_device *orig_dev)
0047 {
0048 struct hdlc_device *hdlc;
0049
0050
0051 if (!(dev->priv_flags & IFF_WAN_HDLC)) {
0052 kfree_skb(skb);
0053 return NET_RX_SUCCESS;
0054 }
0055
0056 hdlc = dev_to_hdlc(dev);
0057
0058 if (!net_eq(dev_net(dev), &init_net)) {
0059 kfree_skb(skb);
0060 return 0;
0061 }
0062
0063 BUG_ON(!hdlc->proto->netif_rx);
0064 return hdlc->proto->netif_rx(skb);
0065 }
0066
0067 netdev_tx_t hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev)
0068 {
0069 hdlc_device *hdlc = dev_to_hdlc(dev);
0070
0071 if (hdlc->proto->xmit)
0072 return hdlc->proto->xmit(skb, dev);
0073
0074 return hdlc->xmit(skb, dev);
0075 }
0076 EXPORT_SYMBOL(hdlc_start_xmit);
0077
0078 static inline void hdlc_proto_start(struct net_device *dev)
0079 {
0080 hdlc_device *hdlc = dev_to_hdlc(dev);
0081
0082 if (hdlc->proto->start)
0083 hdlc->proto->start(dev);
0084 }
0085
0086 static inline void hdlc_proto_stop(struct net_device *dev)
0087 {
0088 hdlc_device *hdlc = dev_to_hdlc(dev);
0089
0090 if (hdlc->proto->stop)
0091 hdlc->proto->stop(dev);
0092 }
0093
0094 static int hdlc_device_event(struct notifier_block *this, unsigned long event,
0095 void *ptr)
0096 {
0097 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
0098 hdlc_device *hdlc;
0099 unsigned long flags;
0100 int on;
0101
0102 if (!net_eq(dev_net(dev), &init_net))
0103 return NOTIFY_DONE;
0104
0105 if (!(dev->priv_flags & IFF_WAN_HDLC))
0106 return NOTIFY_DONE;
0107
0108 if (event != NETDEV_CHANGE)
0109 return NOTIFY_DONE;
0110
0111 on = netif_carrier_ok(dev);
0112
0113 #ifdef DEBUG_LINK
0114 printk(KERN_DEBUG "%s: hdlc_device_event NETDEV_CHANGE, carrier %i\n",
0115 dev->name, on);
0116 #endif
0117
0118 hdlc = dev_to_hdlc(dev);
0119 spin_lock_irqsave(&hdlc->state_lock, flags);
0120
0121 if (hdlc->carrier == on)
0122 goto carrier_exit;
0123
0124 hdlc->carrier = on;
0125
0126 if (!hdlc->open)
0127 goto carrier_exit;
0128
0129 if (hdlc->carrier) {
0130 netdev_info(dev, "Carrier detected\n");
0131 hdlc_proto_start(dev);
0132 } else {
0133 netdev_info(dev, "Carrier lost\n");
0134 hdlc_proto_stop(dev);
0135 }
0136
0137 carrier_exit:
0138 spin_unlock_irqrestore(&hdlc->state_lock, flags);
0139 return NOTIFY_DONE;
0140 }
0141
0142
0143 int hdlc_open(struct net_device *dev)
0144 {
0145 hdlc_device *hdlc = dev_to_hdlc(dev);
0146 #ifdef DEBUG_LINK
0147 printk(KERN_DEBUG "%s: hdlc_open() carrier %i open %i\n", dev->name,
0148 hdlc->carrier, hdlc->open);
0149 #endif
0150
0151 if (!hdlc->proto)
0152 return -ENOSYS;
0153
0154 if (hdlc->proto->open) {
0155 int result = hdlc->proto->open(dev);
0156
0157 if (result)
0158 return result;
0159 }
0160
0161 spin_lock_irq(&hdlc->state_lock);
0162
0163 if (hdlc->carrier) {
0164 netdev_info(dev, "Carrier detected\n");
0165 hdlc_proto_start(dev);
0166 } else {
0167 netdev_info(dev, "No carrier\n");
0168 }
0169
0170 hdlc->open = 1;
0171
0172 spin_unlock_irq(&hdlc->state_lock);
0173 return 0;
0174 }
0175 EXPORT_SYMBOL(hdlc_open);
0176
0177
0178 void hdlc_close(struct net_device *dev)
0179 {
0180 hdlc_device *hdlc = dev_to_hdlc(dev);
0181 #ifdef DEBUG_LINK
0182 printk(KERN_DEBUG "%s: hdlc_close() carrier %i open %i\n", dev->name,
0183 hdlc->carrier, hdlc->open);
0184 #endif
0185
0186 spin_lock_irq(&hdlc->state_lock);
0187
0188 hdlc->open = 0;
0189 if (hdlc->carrier)
0190 hdlc_proto_stop(dev);
0191
0192 spin_unlock_irq(&hdlc->state_lock);
0193
0194 if (hdlc->proto->close)
0195 hdlc->proto->close(dev);
0196 }
0197 EXPORT_SYMBOL(hdlc_close);
0198
0199 int hdlc_ioctl(struct net_device *dev, struct if_settings *ifs)
0200 {
0201 struct hdlc_proto *proto = first_proto;
0202 int result;
0203
0204 if (dev_to_hdlc(dev)->proto) {
0205 result = dev_to_hdlc(dev)->proto->ioctl(dev, ifs);
0206 if (result != -EINVAL)
0207 return result;
0208 }
0209
0210
0211
0212 while (proto) {
0213 result = proto->ioctl(dev, ifs);
0214 if (result != -EINVAL)
0215 return result;
0216 proto = proto->next;
0217 }
0218 return -EINVAL;
0219 }
0220 EXPORT_SYMBOL(hdlc_ioctl);
0221
0222 static const struct header_ops hdlc_null_ops;
0223
0224 static void hdlc_setup_dev(struct net_device *dev)
0225 {
0226
0227
0228
0229 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
0230 dev->priv_flags = IFF_WAN_HDLC;
0231 dev->mtu = HDLC_MAX_MTU;
0232 dev->min_mtu = 68;
0233 dev->max_mtu = HDLC_MAX_MTU;
0234 dev->type = ARPHRD_RAWHDLC;
0235 dev->hard_header_len = 0;
0236 dev->needed_headroom = 0;
0237 dev->addr_len = 0;
0238 dev->header_ops = &hdlc_null_ops;
0239 }
0240
0241 static void hdlc_setup(struct net_device *dev)
0242 {
0243 hdlc_device *hdlc = dev_to_hdlc(dev);
0244
0245 hdlc_setup_dev(dev);
0246 hdlc->carrier = 1;
0247 hdlc->open = 0;
0248 spin_lock_init(&hdlc->state_lock);
0249 }
0250
0251 struct net_device *alloc_hdlcdev(void *priv)
0252 {
0253 struct net_device *dev;
0254
0255 dev = alloc_netdev(sizeof(struct hdlc_device), "hdlc%d",
0256 NET_NAME_UNKNOWN, hdlc_setup);
0257 if (dev)
0258 dev_to_hdlc(dev)->priv = priv;
0259 return dev;
0260 }
0261 EXPORT_SYMBOL(alloc_hdlcdev);
0262
0263 void unregister_hdlc_device(struct net_device *dev)
0264 {
0265 rtnl_lock();
0266 detach_hdlc_protocol(dev);
0267 unregister_netdevice(dev);
0268 rtnl_unlock();
0269 }
0270 EXPORT_SYMBOL(unregister_hdlc_device);
0271
0272 int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
0273 size_t size)
0274 {
0275 int err;
0276
0277 err = detach_hdlc_protocol(dev);
0278 if (err)
0279 return err;
0280
0281 if (!try_module_get(proto->module))
0282 return -ENOSYS;
0283
0284 if (size) {
0285 dev_to_hdlc(dev)->state = kmalloc(size, GFP_KERNEL);
0286 if (!dev_to_hdlc(dev)->state) {
0287 module_put(proto->module);
0288 return -ENOBUFS;
0289 }
0290 }
0291 dev_to_hdlc(dev)->proto = proto;
0292
0293 return 0;
0294 }
0295 EXPORT_SYMBOL(attach_hdlc_protocol);
0296
0297 int detach_hdlc_protocol(struct net_device *dev)
0298 {
0299 hdlc_device *hdlc = dev_to_hdlc(dev);
0300 int err;
0301
0302 if (hdlc->proto) {
0303 err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev);
0304 err = notifier_to_errno(err);
0305 if (err) {
0306 netdev_err(dev, "Refused to change device type\n");
0307 return err;
0308 }
0309
0310 if (hdlc->proto->detach)
0311 hdlc->proto->detach(dev);
0312 module_put(hdlc->proto->module);
0313 hdlc->proto = NULL;
0314 }
0315 kfree(hdlc->state);
0316 hdlc->state = NULL;
0317 hdlc_setup_dev(dev);
0318
0319 return 0;
0320 }
0321 EXPORT_SYMBOL(detach_hdlc_protocol);
0322
0323 void register_hdlc_protocol(struct hdlc_proto *proto)
0324 {
0325 rtnl_lock();
0326 proto->next = first_proto;
0327 first_proto = proto;
0328 rtnl_unlock();
0329 }
0330 EXPORT_SYMBOL(register_hdlc_protocol);
0331
0332 void unregister_hdlc_protocol(struct hdlc_proto *proto)
0333 {
0334 struct hdlc_proto **p;
0335
0336 rtnl_lock();
0337 p = &first_proto;
0338 while (*p != proto) {
0339 BUG_ON(!*p);
0340 p = &((*p)->next);
0341 }
0342 *p = proto->next;
0343 rtnl_unlock();
0344 }
0345 EXPORT_SYMBOL(unregister_hdlc_protocol);
0346
0347 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
0348 MODULE_DESCRIPTION("HDLC support module");
0349 MODULE_LICENSE("GPL v2");
0350
0351 static struct packet_type hdlc_packet_type __read_mostly = {
0352 .type = cpu_to_be16(ETH_P_HDLC),
0353 .func = hdlc_rcv,
0354 };
0355
0356 static struct notifier_block hdlc_notifier = {
0357 .notifier_call = hdlc_device_event,
0358 };
0359
0360 static int __init hdlc_module_init(void)
0361 {
0362 int result;
0363
0364 pr_info("%s\n", version);
0365 result = register_netdevice_notifier(&hdlc_notifier);
0366 if (result)
0367 return result;
0368 dev_add_pack(&hdlc_packet_type);
0369 return 0;
0370 }
0371
0372 static void __exit hdlc_module_exit(void)
0373 {
0374 dev_remove_pack(&hdlc_packet_type);
0375 unregister_netdevice_notifier(&hdlc_notifier);
0376 }
0377
0378 module_init(hdlc_module_init);
0379 module_exit(hdlc_module_exit);