macvtap_main.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include <linux/etherdevice.h>
  2. #include <linux/if_macvlan.h>
  3. #include <linux/if_tap.h>
  4. #include <linux/if_vlan.h>
  5. #include <linux/interrupt.h>
  6. #include <linux/nsproxy.h>
  7. #include <linux/compat.h>
  8. #include <linux/if_tun.h>
  9. #include <linux/module.h>
  10. #include <linux/skbuff.h>
  11. #include <linux/cache.h>
  12. #include <linux/sched.h>
  13. #include <linux/types.h>
  14. #include <linux/slab.h>
  15. #include <linux/wait.h>
  16. #include <linux/cdev.h>
  17. #include <linux/idr.h>
  18. #include <linux/fs.h>
  19. #include <linux/uio.h>
  20. #include <net/net_namespace.h>
  21. #include <net/rtnetlink.h>
  22. #include <net/sock.h>
  23. #include <linux/virtio_net.h>
  24. #include <linux/skb_array.h>
  25. /*
  26. * Variables for dealing with macvtaps device numbers.
  27. */
  28. static dev_t macvtap_major;
  29. static const void *macvtap_net_namespace(struct device *d)
  30. {
  31. struct net_device *dev = to_net_dev(d->parent);
  32. return dev_net(dev);
  33. }
  34. static struct class macvtap_class = {
  35. .name = "macvtap",
  36. .owner = THIS_MODULE,
  37. .ns_type = &net_ns_type_operations,
  38. .namespace = macvtap_net_namespace,
  39. };
  40. static struct cdev macvtap_cdev;
  41. #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
  42. NETIF_F_TSO6 | NETIF_F_UFO)
  43. static int macvtap_newlink(struct net *src_net,
  44. struct net_device *dev,
  45. struct nlattr *tb[],
  46. struct nlattr *data[])
  47. {
  48. struct macvlan_dev *vlan = netdev_priv(dev);
  49. int err;
  50. INIT_LIST_HEAD(&vlan->queue_list);
  51. /* Since macvlan supports all offloads by default, make
  52. * tap support all offloads also.
  53. */
  54. vlan->tap_features = TUN_OFFLOADS;
  55. err = netdev_rx_handler_register(dev, tap_handle_frame, vlan);
  56. if (err)
  57. return err;
  58. /* Don't put anything that may fail after macvlan_common_newlink
  59. * because we can't undo what it does.
  60. */
  61. err = macvlan_common_newlink(src_net, dev, tb, data);
  62. if (err) {
  63. netdev_rx_handler_unregister(dev);
  64. return err;
  65. }
  66. return 0;
  67. }
  68. static void macvtap_dellink(struct net_device *dev,
  69. struct list_head *head)
  70. {
  71. netdev_rx_handler_unregister(dev);
  72. tap_del_queues(dev);
  73. macvlan_dellink(dev, head);
  74. }
  75. static void macvtap_setup(struct net_device *dev)
  76. {
  77. macvlan_common_setup(dev);
  78. dev->tx_queue_len = TUN_READQ_SIZE;
  79. }
  80. static struct rtnl_link_ops macvtap_link_ops __read_mostly = {
  81. .kind = "macvtap",
  82. .setup = macvtap_setup,
  83. .newlink = macvtap_newlink,
  84. .dellink = macvtap_dellink,
  85. };
  86. static int macvtap_device_event(struct notifier_block *unused,
  87. unsigned long event, void *ptr)
  88. {
  89. struct net_device *dev = netdev_notifier_info_to_dev(ptr);
  90. struct macvlan_dev *vlan;
  91. struct device *classdev;
  92. dev_t devt;
  93. int err;
  94. char tap_name[IFNAMSIZ];
  95. if (dev->rtnl_link_ops != &macvtap_link_ops)
  96. return NOTIFY_DONE;
  97. snprintf(tap_name, IFNAMSIZ, "tap%d", dev->ifindex);
  98. vlan = netdev_priv(dev);
  99. switch (event) {
  100. case NETDEV_REGISTER:
  101. /* Create the device node here after the network device has
  102. * been registered but before register_netdevice has
  103. * finished running.
  104. */
  105. err = tap_get_minor(vlan);
  106. if (err)
  107. return notifier_from_errno(err);
  108. devt = MKDEV(MAJOR(macvtap_major), vlan->minor);
  109. classdev = device_create(&macvtap_class, &dev->dev, devt,
  110. dev, tap_name);
  111. if (IS_ERR(classdev)) {
  112. tap_free_minor(vlan);
  113. return notifier_from_errno(PTR_ERR(classdev));
  114. }
  115. err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj,
  116. tap_name);
  117. if (err)
  118. return notifier_from_errno(err);
  119. break;
  120. case NETDEV_UNREGISTER:
  121. /* vlan->minor == 0 if NETDEV_REGISTER above failed */
  122. if (vlan->minor == 0)
  123. break;
  124. sysfs_remove_link(&dev->dev.kobj, tap_name);
  125. devt = MKDEV(MAJOR(macvtap_major), vlan->minor);
  126. device_destroy(&macvtap_class, devt);
  127. tap_free_minor(vlan);
  128. break;
  129. case NETDEV_CHANGE_TX_QUEUE_LEN:
  130. if (tap_queue_resize(vlan))
  131. return NOTIFY_BAD;
  132. break;
  133. }
  134. return NOTIFY_DONE;
  135. }
  136. static struct notifier_block macvtap_notifier_block __read_mostly = {
  137. .notifier_call = macvtap_device_event,
  138. };
  139. static int macvtap_init(void)
  140. {
  141. int err;
  142. err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap");
  143. if (err)
  144. goto out1;
  145. err = class_register(&macvtap_class);
  146. if (err)
  147. goto out2;
  148. err = register_netdevice_notifier(&macvtap_notifier_block);
  149. if (err)
  150. goto out3;
  151. err = macvlan_link_register(&macvtap_link_ops);
  152. if (err)
  153. goto out4;
  154. return 0;
  155. out4:
  156. unregister_netdevice_notifier(&macvtap_notifier_block);
  157. out3:
  158. class_unregister(&macvtap_class);
  159. out2:
  160. tap_destroy_cdev(macvtap_major, &macvtap_cdev);
  161. out1:
  162. return err;
  163. }
  164. module_init(macvtap_init);
  165. static void macvtap_exit(void)
  166. {
  167. rtnl_link_unregister(&macvtap_link_ops);
  168. unregister_netdevice_notifier(&macvtap_notifier_block);
  169. class_unregister(&macvtap_class);
  170. tap_destroy_cdev(macvtap_major, &macvtap_cdev);
  171. }
  172. module_exit(macvtap_exit);
  173. MODULE_ALIAS_RTNL_LINK("macvtap");
  174. MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>");
  175. MODULE_LICENSE("GPL");