19a393b5dSSainath Grandhi #include <linux/etherdevice.h> 29a393b5dSSainath Grandhi #include <linux/if_macvlan.h> 39a393b5dSSainath Grandhi #include <linux/if_tap.h> 49a393b5dSSainath Grandhi #include <linux/if_vlan.h> 59a393b5dSSainath Grandhi #include <linux/interrupt.h> 69a393b5dSSainath Grandhi #include <linux/nsproxy.h> 79a393b5dSSainath Grandhi #include <linux/compat.h> 89a393b5dSSainath Grandhi #include <linux/if_tun.h> 99a393b5dSSainath Grandhi #include <linux/module.h> 109a393b5dSSainath Grandhi #include <linux/skbuff.h> 119a393b5dSSainath Grandhi #include <linux/cache.h> 12*174cd4b1SIngo Molnar #include <linux/sched/signal.h> 139a393b5dSSainath Grandhi #include <linux/types.h> 149a393b5dSSainath Grandhi #include <linux/slab.h> 159a393b5dSSainath Grandhi #include <linux/wait.h> 169a393b5dSSainath Grandhi #include <linux/cdev.h> 179a393b5dSSainath Grandhi #include <linux/idr.h> 189a393b5dSSainath Grandhi #include <linux/fs.h> 199a393b5dSSainath Grandhi #include <linux/uio.h> 209a393b5dSSainath Grandhi 219a393b5dSSainath Grandhi #include <net/net_namespace.h> 229a393b5dSSainath Grandhi #include <net/rtnetlink.h> 239a393b5dSSainath Grandhi #include <net/sock.h> 249a393b5dSSainath Grandhi #include <linux/virtio_net.h> 259a393b5dSSainath Grandhi #include <linux/skb_array.h> 269a393b5dSSainath Grandhi 279a393b5dSSainath Grandhi struct macvtap_dev { 289a393b5dSSainath Grandhi struct macvlan_dev vlan; 299a393b5dSSainath Grandhi struct tap_dev tap; 309a393b5dSSainath Grandhi }; 319a393b5dSSainath Grandhi 329a393b5dSSainath Grandhi /* 339a393b5dSSainath Grandhi * Variables for dealing with macvtaps device numbers. 349a393b5dSSainath Grandhi */ 359a393b5dSSainath Grandhi static dev_t macvtap_major; 369a393b5dSSainath Grandhi 379a393b5dSSainath Grandhi static const void *macvtap_net_namespace(struct device *d) 389a393b5dSSainath Grandhi { 399a393b5dSSainath Grandhi struct net_device *dev = to_net_dev(d->parent); 409a393b5dSSainath Grandhi return dev_net(dev); 419a393b5dSSainath Grandhi } 429a393b5dSSainath Grandhi 439a393b5dSSainath Grandhi static struct class macvtap_class = { 449a393b5dSSainath Grandhi .name = "macvtap", 459a393b5dSSainath Grandhi .owner = THIS_MODULE, 469a393b5dSSainath Grandhi .ns_type = &net_ns_type_operations, 479a393b5dSSainath Grandhi .namespace = macvtap_net_namespace, 489a393b5dSSainath Grandhi }; 499a393b5dSSainath Grandhi static struct cdev macvtap_cdev; 509a393b5dSSainath Grandhi 519a393b5dSSainath Grandhi #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ 529a393b5dSSainath Grandhi NETIF_F_TSO6 | NETIF_F_UFO) 539a393b5dSSainath Grandhi 549a393b5dSSainath Grandhi static void macvtap_count_tx_dropped(struct tap_dev *tap) 559a393b5dSSainath Grandhi { 569a393b5dSSainath Grandhi struct macvtap_dev *vlantap = container_of(tap, struct macvtap_dev, tap); 579a393b5dSSainath Grandhi struct macvlan_dev *vlan = &vlantap->vlan; 589a393b5dSSainath Grandhi 599a393b5dSSainath Grandhi this_cpu_inc(vlan->pcpu_stats->tx_dropped); 609a393b5dSSainath Grandhi } 619a393b5dSSainath Grandhi 629a393b5dSSainath Grandhi static void macvtap_count_rx_dropped(struct tap_dev *tap) 639a393b5dSSainath Grandhi { 649a393b5dSSainath Grandhi struct macvtap_dev *vlantap = container_of(tap, struct macvtap_dev, tap); 659a393b5dSSainath Grandhi struct macvlan_dev *vlan = &vlantap->vlan; 669a393b5dSSainath Grandhi 679a393b5dSSainath Grandhi macvlan_count_rx(vlan, 0, 0, 0); 689a393b5dSSainath Grandhi } 699a393b5dSSainath Grandhi 709a393b5dSSainath Grandhi static void macvtap_update_features(struct tap_dev *tap, 719a393b5dSSainath Grandhi netdev_features_t features) 729a393b5dSSainath Grandhi { 739a393b5dSSainath Grandhi struct macvtap_dev *vlantap = container_of(tap, struct macvtap_dev, tap); 749a393b5dSSainath Grandhi struct macvlan_dev *vlan = &vlantap->vlan; 759a393b5dSSainath Grandhi 769a393b5dSSainath Grandhi vlan->set_features = features; 779a393b5dSSainath Grandhi netdev_update_features(vlan->dev); 789a393b5dSSainath Grandhi } 799a393b5dSSainath Grandhi 809a393b5dSSainath Grandhi static int macvtap_newlink(struct net *src_net, 819a393b5dSSainath Grandhi struct net_device *dev, 829a393b5dSSainath Grandhi struct nlattr *tb[], 839a393b5dSSainath Grandhi struct nlattr *data[]) 849a393b5dSSainath Grandhi { 859a393b5dSSainath Grandhi struct macvtap_dev *vlantap = netdev_priv(dev); 869a393b5dSSainath Grandhi int err; 879a393b5dSSainath Grandhi 889a393b5dSSainath Grandhi INIT_LIST_HEAD(&vlantap->tap.queue_list); 899a393b5dSSainath Grandhi 909a393b5dSSainath Grandhi /* Since macvlan supports all offloads by default, make 919a393b5dSSainath Grandhi * tap support all offloads also. 929a393b5dSSainath Grandhi */ 939a393b5dSSainath Grandhi vlantap->tap.tap_features = TUN_OFFLOADS; 949a393b5dSSainath Grandhi 959a393b5dSSainath Grandhi /* Register callbacks for rx/tx drops accounting and updating 969a393b5dSSainath Grandhi * net_device features 979a393b5dSSainath Grandhi */ 989a393b5dSSainath Grandhi vlantap->tap.count_tx_dropped = macvtap_count_tx_dropped; 999a393b5dSSainath Grandhi vlantap->tap.count_rx_dropped = macvtap_count_rx_dropped; 1009a393b5dSSainath Grandhi vlantap->tap.update_features = macvtap_update_features; 1019a393b5dSSainath Grandhi 1029a393b5dSSainath Grandhi err = netdev_rx_handler_register(dev, tap_handle_frame, &vlantap->tap); 1039a393b5dSSainath Grandhi if (err) 1049a393b5dSSainath Grandhi return err; 1059a393b5dSSainath Grandhi 1069a393b5dSSainath Grandhi /* Don't put anything that may fail after macvlan_common_newlink 1079a393b5dSSainath Grandhi * because we can't undo what it does. 1089a393b5dSSainath Grandhi */ 1099a393b5dSSainath Grandhi err = macvlan_common_newlink(src_net, dev, tb, data); 1109a393b5dSSainath Grandhi if (err) { 1119a393b5dSSainath Grandhi netdev_rx_handler_unregister(dev); 1129a393b5dSSainath Grandhi return err; 1139a393b5dSSainath Grandhi } 1149a393b5dSSainath Grandhi 1159a393b5dSSainath Grandhi vlantap->tap.dev = vlantap->vlan.dev; 1169a393b5dSSainath Grandhi 1179a393b5dSSainath Grandhi return 0; 1189a393b5dSSainath Grandhi } 1199a393b5dSSainath Grandhi 1209a393b5dSSainath Grandhi static void macvtap_dellink(struct net_device *dev, 1219a393b5dSSainath Grandhi struct list_head *head) 1229a393b5dSSainath Grandhi { 1239a393b5dSSainath Grandhi struct macvtap_dev *vlantap = netdev_priv(dev); 1249a393b5dSSainath Grandhi 1259a393b5dSSainath Grandhi netdev_rx_handler_unregister(dev); 1269a393b5dSSainath Grandhi tap_del_queues(&vlantap->tap); 1279a393b5dSSainath Grandhi macvlan_dellink(dev, head); 1289a393b5dSSainath Grandhi } 1299a393b5dSSainath Grandhi 1309a393b5dSSainath Grandhi static void macvtap_setup(struct net_device *dev) 1319a393b5dSSainath Grandhi { 1329a393b5dSSainath Grandhi macvlan_common_setup(dev); 1339a393b5dSSainath Grandhi dev->tx_queue_len = TUN_READQ_SIZE; 1349a393b5dSSainath Grandhi } 1359a393b5dSSainath Grandhi 1369a393b5dSSainath Grandhi static struct rtnl_link_ops macvtap_link_ops __read_mostly = { 1379a393b5dSSainath Grandhi .kind = "macvtap", 1389a393b5dSSainath Grandhi .setup = macvtap_setup, 1399a393b5dSSainath Grandhi .newlink = macvtap_newlink, 1409a393b5dSSainath Grandhi .dellink = macvtap_dellink, 1419a393b5dSSainath Grandhi .priv_size = sizeof(struct macvtap_dev), 1429a393b5dSSainath Grandhi }; 1439a393b5dSSainath Grandhi 1449a393b5dSSainath Grandhi static int macvtap_device_event(struct notifier_block *unused, 1459a393b5dSSainath Grandhi unsigned long event, void *ptr) 1469a393b5dSSainath Grandhi { 1479a393b5dSSainath Grandhi struct net_device *dev = netdev_notifier_info_to_dev(ptr); 1489a393b5dSSainath Grandhi struct macvtap_dev *vlantap; 1499a393b5dSSainath Grandhi struct device *classdev; 1509a393b5dSSainath Grandhi dev_t devt; 1519a393b5dSSainath Grandhi int err; 1529a393b5dSSainath Grandhi char tap_name[IFNAMSIZ]; 1539a393b5dSSainath Grandhi 1549a393b5dSSainath Grandhi if (dev->rtnl_link_ops != &macvtap_link_ops) 1559a393b5dSSainath Grandhi return NOTIFY_DONE; 1569a393b5dSSainath Grandhi 1579a393b5dSSainath Grandhi snprintf(tap_name, IFNAMSIZ, "tap%d", dev->ifindex); 1589a393b5dSSainath Grandhi vlantap = netdev_priv(dev); 1599a393b5dSSainath Grandhi 1609a393b5dSSainath Grandhi switch (event) { 1619a393b5dSSainath Grandhi case NETDEV_REGISTER: 1629a393b5dSSainath Grandhi /* Create the device node here after the network device has 1639a393b5dSSainath Grandhi * been registered but before register_netdevice has 1649a393b5dSSainath Grandhi * finished running. 1659a393b5dSSainath Grandhi */ 1669a393b5dSSainath Grandhi err = tap_get_minor(macvtap_major, &vlantap->tap); 1679a393b5dSSainath Grandhi if (err) 1689a393b5dSSainath Grandhi return notifier_from_errno(err); 1699a393b5dSSainath Grandhi 1709a393b5dSSainath Grandhi devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor); 1719a393b5dSSainath Grandhi classdev = device_create(&macvtap_class, &dev->dev, devt, 1729a393b5dSSainath Grandhi dev, tap_name); 1739a393b5dSSainath Grandhi if (IS_ERR(classdev)) { 1749a393b5dSSainath Grandhi tap_free_minor(macvtap_major, &vlantap->tap); 1759a393b5dSSainath Grandhi return notifier_from_errno(PTR_ERR(classdev)); 1769a393b5dSSainath Grandhi } 1779a393b5dSSainath Grandhi err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj, 1789a393b5dSSainath Grandhi tap_name); 1799a393b5dSSainath Grandhi if (err) 1809a393b5dSSainath Grandhi return notifier_from_errno(err); 1819a393b5dSSainath Grandhi break; 1829a393b5dSSainath Grandhi case NETDEV_UNREGISTER: 1839a393b5dSSainath Grandhi /* vlan->minor == 0 if NETDEV_REGISTER above failed */ 1849a393b5dSSainath Grandhi if (vlantap->tap.minor == 0) 1859a393b5dSSainath Grandhi break; 1869a393b5dSSainath Grandhi sysfs_remove_link(&dev->dev.kobj, tap_name); 1879a393b5dSSainath Grandhi devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor); 1889a393b5dSSainath Grandhi device_destroy(&macvtap_class, devt); 1899a393b5dSSainath Grandhi tap_free_minor(macvtap_major, &vlantap->tap); 1909a393b5dSSainath Grandhi break; 1919a393b5dSSainath Grandhi case NETDEV_CHANGE_TX_QUEUE_LEN: 1929a393b5dSSainath Grandhi if (tap_queue_resize(&vlantap->tap)) 1939a393b5dSSainath Grandhi return NOTIFY_BAD; 1949a393b5dSSainath Grandhi break; 1959a393b5dSSainath Grandhi } 1969a393b5dSSainath Grandhi 1979a393b5dSSainath Grandhi return NOTIFY_DONE; 1989a393b5dSSainath Grandhi } 1999a393b5dSSainath Grandhi 2009a393b5dSSainath Grandhi static struct notifier_block macvtap_notifier_block __read_mostly = { 2019a393b5dSSainath Grandhi .notifier_call = macvtap_device_event, 2029a393b5dSSainath Grandhi }; 2039a393b5dSSainath Grandhi 2049a393b5dSSainath Grandhi static int macvtap_init(void) 2059a393b5dSSainath Grandhi { 2069a393b5dSSainath Grandhi int err; 2079a393b5dSSainath Grandhi 2089a393b5dSSainath Grandhi err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap"); 2099a393b5dSSainath Grandhi 2109a393b5dSSainath Grandhi if (err) 2119a393b5dSSainath Grandhi goto out1; 2129a393b5dSSainath Grandhi 2139a393b5dSSainath Grandhi err = class_register(&macvtap_class); 2149a393b5dSSainath Grandhi if (err) 2159a393b5dSSainath Grandhi goto out2; 2169a393b5dSSainath Grandhi 2179a393b5dSSainath Grandhi err = register_netdevice_notifier(&macvtap_notifier_block); 2189a393b5dSSainath Grandhi if (err) 2199a393b5dSSainath Grandhi goto out3; 2209a393b5dSSainath Grandhi 2219a393b5dSSainath Grandhi err = macvlan_link_register(&macvtap_link_ops); 2229a393b5dSSainath Grandhi if (err) 2239a393b5dSSainath Grandhi goto out4; 2249a393b5dSSainath Grandhi 2259a393b5dSSainath Grandhi return 0; 2269a393b5dSSainath Grandhi 2279a393b5dSSainath Grandhi out4: 2289a393b5dSSainath Grandhi unregister_netdevice_notifier(&macvtap_notifier_block); 2299a393b5dSSainath Grandhi out3: 2309a393b5dSSainath Grandhi class_unregister(&macvtap_class); 2319a393b5dSSainath Grandhi out2: 2329a393b5dSSainath Grandhi tap_destroy_cdev(macvtap_major, &macvtap_cdev); 2339a393b5dSSainath Grandhi out1: 2349a393b5dSSainath Grandhi return err; 2359a393b5dSSainath Grandhi } 2369a393b5dSSainath Grandhi module_init(macvtap_init); 2379a393b5dSSainath Grandhi 2389a393b5dSSainath Grandhi static void macvtap_exit(void) 2399a393b5dSSainath Grandhi { 2409a393b5dSSainath Grandhi rtnl_link_unregister(&macvtap_link_ops); 2419a393b5dSSainath Grandhi unregister_netdevice_notifier(&macvtap_notifier_block); 2429a393b5dSSainath Grandhi class_unregister(&macvtap_class); 2439a393b5dSSainath Grandhi tap_destroy_cdev(macvtap_major, &macvtap_cdev); 2449a393b5dSSainath Grandhi } 2459a393b5dSSainath Grandhi module_exit(macvtap_exit); 2469a393b5dSSainath Grandhi 2479a393b5dSSainath Grandhi MODULE_ALIAS_RTNL_LINK("macvtap"); 2489a393b5dSSainath Grandhi MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>"); 2499a393b5dSSainath Grandhi MODULE_LICENSE("GPL"); 250