tunnel4.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /* tunnel4.c: Generic IP tunnel transformer.
  2. *
  3. * Copyright (C) 2003 David S. Miller (davem@redhat.com)
  4. */
  5. #include <linux/init.h>
  6. #include <linux/module.h>
  7. #include <linux/mutex.h>
  8. #include <linux/netdevice.h>
  9. #include <linux/skbuff.h>
  10. #include <net/protocol.h>
  11. #include <net/xfrm.h>
  12. static struct xfrm_tunnel *tunnel4_handlers;
  13. static DEFINE_MUTEX(tunnel4_mutex);
  14. int xfrm4_tunnel_register(struct xfrm_tunnel *handler)
  15. {
  16. struct xfrm_tunnel **pprev;
  17. int ret = -EEXIST;
  18. int priority = handler->priority;
  19. mutex_lock(&tunnel4_mutex);
  20. for (pprev = &tunnel4_handlers; *pprev; pprev = &(*pprev)->next) {
  21. if ((*pprev)->priority > priority)
  22. break;
  23. if ((*pprev)->priority == priority)
  24. goto err;
  25. }
  26. handler->next = *pprev;
  27. *pprev = handler;
  28. ret = 0;
  29. err:
  30. mutex_unlock(&tunnel4_mutex);
  31. return ret;
  32. }
  33. EXPORT_SYMBOL(xfrm4_tunnel_register);
  34. int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler)
  35. {
  36. struct xfrm_tunnel **pprev;
  37. int ret = -ENOENT;
  38. mutex_lock(&tunnel4_mutex);
  39. for (pprev = &tunnel4_handlers; *pprev; pprev = &(*pprev)->next) {
  40. if (*pprev == handler) {
  41. *pprev = handler->next;
  42. ret = 0;
  43. break;
  44. }
  45. }
  46. mutex_unlock(&tunnel4_mutex);
  47. synchronize_net();
  48. return ret;
  49. }
  50. EXPORT_SYMBOL(xfrm4_tunnel_deregister);
  51. static int tunnel4_rcv(struct sk_buff *skb)
  52. {
  53. struct xfrm_tunnel *handler;
  54. for (handler = tunnel4_handlers; handler; handler = handler->next)
  55. if (!handler->handler(skb))
  56. return 0;
  57. kfree_skb(skb);
  58. return 0;
  59. }
  60. static void tunnel4_err(struct sk_buff *skb, u32 info)
  61. {
  62. struct xfrm_tunnel *handler;
  63. for (handler = tunnel4_handlers; handler; handler = handler->next)
  64. if (!handler->err_handler(skb, info))
  65. break;
  66. }
  67. static struct net_protocol tunnel4_protocol = {
  68. .handler = tunnel4_rcv,
  69. .err_handler = tunnel4_err,
  70. .no_policy = 1,
  71. };
  72. static int __init tunnel4_init(void)
  73. {
  74. if (inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP)) {
  75. printk(KERN_ERR "tunnel4 init: can't add protocol\n");
  76. return -EAGAIN;
  77. }
  78. return 0;
  79. }
  80. static void __exit tunnel4_fini(void)
  81. {
  82. if (inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP))
  83. printk(KERN_ERR "tunnel4 close: can't remove protocol\n");
  84. }
  85. module_init(tunnel4_init);
  86. module_exit(tunnel4_fini);
  87. MODULE_LICENSE("GPL");