ethertap_kern.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
  3. * James Leu (jleu@mindspring.net).
  4. * Copyright (C) 2001 by various other people who didn't put their name here.
  5. * Licensed under the GPL.
  6. */
  7. #include "linux/init.h"
  8. #include "linux/netdevice.h"
  9. #include "linux/etherdevice.h"
  10. #include "net_kern.h"
  11. #include "net_user.h"
  12. #include "etap.h"
  13. struct ethertap_init {
  14. char *dev_name;
  15. char *gate_addr;
  16. };
  17. static void etap_init(struct net_device *dev, void *data)
  18. {
  19. struct uml_net_private *pri;
  20. struct ethertap_data *epri;
  21. struct ethertap_init *init = data;
  22. pri = dev->priv;
  23. epri = (struct ethertap_data *) pri->user;
  24. epri->dev_name = init->dev_name;
  25. epri->gate_addr = init->gate_addr;
  26. epri->data_fd = -1;
  27. epri->control_fd = -1;
  28. epri->dev = dev;
  29. printk("ethertap backend - %s", epri->dev_name);
  30. if (epri->gate_addr != NULL)
  31. printk(", IP = %s", epri->gate_addr);
  32. printk("\n");
  33. }
  34. static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
  35. {
  36. int len;
  37. *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
  38. if(*skb == NULL) return(-ENOMEM);
  39. len = net_recvfrom(fd, (*skb)->mac.raw,
  40. (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
  41. if(len <= 0) return(len);
  42. skb_pull(*skb, 2);
  43. len -= 2;
  44. return(len);
  45. }
  46. static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
  47. {
  48. if(skb_headroom(*skb) < 2){
  49. struct sk_buff *skb2;
  50. skb2 = skb_realloc_headroom(*skb, 2);
  51. dev_kfree_skb(*skb);
  52. if (skb2 == NULL) return(-ENOMEM);
  53. *skb = skb2;
  54. }
  55. skb_push(*skb, 2);
  56. return(net_send(fd, (*skb)->data, (*skb)->len));
  57. }
  58. struct net_kern_info ethertap_kern_info = {
  59. .init = etap_init,
  60. .protocol = eth_protocol,
  61. .read = etap_read,
  62. .write = etap_write,
  63. };
  64. int ethertap_setup(char *str, char **mac_out, void *data)
  65. {
  66. struct ethertap_init *init = data;
  67. *init = ((struct ethertap_init)
  68. { .dev_name = NULL,
  69. .gate_addr = NULL });
  70. if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
  71. &init->gate_addr))
  72. return(0);
  73. if(init->dev_name == NULL){
  74. printk("ethertap_setup : Missing tap device name\n");
  75. return(0);
  76. }
  77. return(1);
  78. }
  79. static struct transport ethertap_transport = {
  80. .list = LIST_HEAD_INIT(ethertap_transport.list),
  81. .name = "ethertap",
  82. .setup = ethertap_setup,
  83. .user = &ethertap_user_info,
  84. .kern = &ethertap_kern_info,
  85. .private_size = sizeof(struct ethertap_data),
  86. };
  87. static int register_ethertap(void)
  88. {
  89. register_transport(&ethertap_transport);
  90. return(1);
  91. }
  92. __initcall(register_ethertap);
  93. /*
  94. * Overrides for Emacs so that we follow Linus's tabbing style.
  95. * Emacs will notice this stuff at the end of the file and automatically
  96. * adjust the settings for this buffer only. This must remain at the end
  97. * of the file.
  98. * ---------------------------------------------------------------------------
  99. * Local variables:
  100. * c-file-style: "linux"
  101. * End:
  102. */