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> 12174cd4b1SIngo 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 | \ 52*fb652fdfSDavid S. Miller NETIF_F_TSO6) 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 807a3f4a18SMatthias Schiffer static int macvtap_newlink(struct net *src_net, struct net_device *dev, 817a3f4a18SMatthias Schiffer struct nlattr *tb[], struct nlattr *data[], 827a3f4a18SMatthias Schiffer struct netlink_ext_ack *extack) 839a393b5dSSainath Grandhi { 849a393b5dSSainath Grandhi struct macvtap_dev *vlantap = netdev_priv(dev); 859a393b5dSSainath Grandhi int err; 869a393b5dSSainath Grandhi 879a393b5dSSainath Grandhi INIT_LIST_HEAD(&vlantap->tap.queue_list); 889a393b5dSSainath Grandhi 899a393b5dSSainath Grandhi /* Since macvlan supports all offloads by default, make 909a393b5dSSainath Grandhi * tap support all offloads also. 919a393b5dSSainath Grandhi */ 929a393b5dSSainath Grandhi vlantap->tap.tap_features = TUN_OFFLOADS; 939a393b5dSSainath Grandhi 949a393b5dSSainath Grandhi /* Register callbacks for rx/tx drops accounting and updating 959a393b5dSSainath Grandhi * net_device features 969a393b5dSSainath Grandhi */ 979a393b5dSSainath Grandhi vlantap->tap.count_tx_dropped = macvtap_count_tx_dropped; 989a393b5dSSainath Grandhi vlantap->tap.count_rx_dropped = macvtap_count_rx_dropped; 999a393b5dSSainath Grandhi vlantap->tap.update_features = macvtap_update_features; 1009a393b5dSSainath Grandhi 1019a393b5dSSainath Grandhi err = netdev_rx_handler_register(dev, tap_handle_frame, &vlantap->tap); 1029a393b5dSSainath Grandhi if (err) 1039a393b5dSSainath Grandhi return err; 1049a393b5dSSainath Grandhi 1059a393b5dSSainath Grandhi /* Don't put anything that may fail after macvlan_common_newlink 1069a393b5dSSainath Grandhi * because we can't undo what it does. 1079a393b5dSSainath Grandhi */ 1089a393b5dSSainath Grandhi err = macvlan_common_newlink(src_net, dev, tb, data); 1099a393b5dSSainath Grandhi if (err) { 1109a393b5dSSainath Grandhi netdev_rx_handler_unregister(dev); 1119a393b5dSSainath Grandhi return err; 1129a393b5dSSainath Grandhi } 1139a393b5dSSainath Grandhi 1149a393b5dSSainath Grandhi vlantap->tap.dev = vlantap->vlan.dev; 1159a393b5dSSainath Grandhi 1169a393b5dSSainath Grandhi return 0; 1179a393b5dSSainath Grandhi } 1189a393b5dSSainath Grandhi 1199a393b5dSSainath Grandhi static void macvtap_dellink(struct net_device *dev, 1209a393b5dSSainath Grandhi struct list_head *head) 1219a393b5dSSainath Grandhi { 1229a393b5dSSainath Grandhi struct macvtap_dev *vlantap = netdev_priv(dev); 1239a393b5dSSainath Grandhi 1249a393b5dSSainath Grandhi netdev_rx_handler_unregister(dev); 1259a393b5dSSainath Grandhi tap_del_queues(&vlantap->tap); 1269a393b5dSSainath Grandhi macvlan_dellink(dev, head); 1279a393b5dSSainath Grandhi } 1289a393b5dSSainath Grandhi 1299a393b5dSSainath Grandhi static void macvtap_setup(struct net_device *dev) 1309a393b5dSSainath Grandhi { 1319a393b5dSSainath Grandhi macvlan_common_setup(dev); 1329a393b5dSSainath Grandhi dev->tx_queue_len = TUN_READQ_SIZE; 1339a393b5dSSainath Grandhi } 1349a393b5dSSainath Grandhi 1359a393b5dSSainath Grandhi static struct rtnl_link_ops macvtap_link_ops __read_mostly = { 1369a393b5dSSainath Grandhi .kind = "macvtap", 1379a393b5dSSainath Grandhi .setup = macvtap_setup, 1389a393b5dSSainath Grandhi .newlink = macvtap_newlink, 1399a393b5dSSainath Grandhi .dellink = macvtap_dellink, 1409a393b5dSSainath Grandhi .priv_size = sizeof(struct macvtap_dev), 1419a393b5dSSainath Grandhi }; 1429a393b5dSSainath Grandhi 1439a393b5dSSainath Grandhi static int macvtap_device_event(struct notifier_block *unused, 1449a393b5dSSainath Grandhi unsigned long event, void *ptr) 1459a393b5dSSainath Grandhi { 1469a393b5dSSainath Grandhi struct net_device *dev = netdev_notifier_info_to_dev(ptr); 1479a393b5dSSainath Grandhi struct macvtap_dev *vlantap; 1489a393b5dSSainath Grandhi struct device *classdev; 1499a393b5dSSainath Grandhi dev_t devt; 1509a393b5dSSainath Grandhi int err; 1519a393b5dSSainath Grandhi char tap_name[IFNAMSIZ]; 1529a393b5dSSainath Grandhi 1539a393b5dSSainath Grandhi if (dev->rtnl_link_ops != &macvtap_link_ops) 1549a393b5dSSainath Grandhi return NOTIFY_DONE; 1559a393b5dSSainath Grandhi 1569a393b5dSSainath Grandhi snprintf(tap_name, IFNAMSIZ, "tap%d", dev->ifindex); 1579a393b5dSSainath Grandhi vlantap = netdev_priv(dev); 1589a393b5dSSainath Grandhi 1599a393b5dSSainath Grandhi switch (event) { 1609a393b5dSSainath Grandhi case NETDEV_REGISTER: 1619a393b5dSSainath Grandhi /* Create the device node here after the network device has 1629a393b5dSSainath Grandhi * been registered but before register_netdevice has 1639a393b5dSSainath Grandhi * finished running. 1649a393b5dSSainath Grandhi */ 1659a393b5dSSainath Grandhi err = tap_get_minor(macvtap_major, &vlantap->tap); 1669a393b5dSSainath Grandhi if (err) 1679a393b5dSSainath Grandhi return notifier_from_errno(err); 1689a393b5dSSainath Grandhi 1699a393b5dSSainath Grandhi devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor); 1709a393b5dSSainath Grandhi classdev = device_create(&macvtap_class, &dev->dev, devt, 1719a393b5dSSainath Grandhi dev, tap_name); 1729a393b5dSSainath Grandhi if (IS_ERR(classdev)) { 1739a393b5dSSainath Grandhi tap_free_minor(macvtap_major, &vlantap->tap); 1749a393b5dSSainath Grandhi return notifier_from_errno(PTR_ERR(classdev)); 1759a393b5dSSainath Grandhi } 1769a393b5dSSainath Grandhi err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj, 1779a393b5dSSainath Grandhi tap_name); 1789a393b5dSSainath Grandhi if (err) 1799a393b5dSSainath Grandhi return notifier_from_errno(err); 1809a393b5dSSainath Grandhi break; 1819a393b5dSSainath Grandhi case NETDEV_UNREGISTER: 1829a393b5dSSainath Grandhi /* vlan->minor == 0 if NETDEV_REGISTER above failed */ 1839a393b5dSSainath Grandhi if (vlantap->tap.minor == 0) 1849a393b5dSSainath Grandhi break; 1859a393b5dSSainath Grandhi sysfs_remove_link(&dev->dev.kobj, tap_name); 1869a393b5dSSainath Grandhi devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor); 1879a393b5dSSainath Grandhi device_destroy(&macvtap_class, devt); 1889a393b5dSSainath Grandhi tap_free_minor(macvtap_major, &vlantap->tap); 1899a393b5dSSainath Grandhi break; 1909a393b5dSSainath Grandhi case NETDEV_CHANGE_TX_QUEUE_LEN: 1919a393b5dSSainath Grandhi if (tap_queue_resize(&vlantap->tap)) 1929a393b5dSSainath Grandhi return NOTIFY_BAD; 1939a393b5dSSainath Grandhi break; 1949a393b5dSSainath Grandhi } 1959a393b5dSSainath Grandhi 1969a393b5dSSainath Grandhi return NOTIFY_DONE; 1979a393b5dSSainath Grandhi } 1989a393b5dSSainath Grandhi 1999a393b5dSSainath Grandhi static struct notifier_block macvtap_notifier_block __read_mostly = { 2009a393b5dSSainath Grandhi .notifier_call = macvtap_device_event, 2019a393b5dSSainath Grandhi }; 2029a393b5dSSainath Grandhi 2039a393b5dSSainath Grandhi static int macvtap_init(void) 2049a393b5dSSainath Grandhi { 2059a393b5dSSainath Grandhi int err; 2069a393b5dSSainath Grandhi 2079a393b5dSSainath Grandhi err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap"); 2089a393b5dSSainath Grandhi 2099a393b5dSSainath Grandhi if (err) 2109a393b5dSSainath Grandhi goto out1; 2119a393b5dSSainath Grandhi 2129a393b5dSSainath Grandhi err = class_register(&macvtap_class); 2139a393b5dSSainath Grandhi if (err) 2149a393b5dSSainath Grandhi goto out2; 2159a393b5dSSainath Grandhi 2169a393b5dSSainath Grandhi err = register_netdevice_notifier(&macvtap_notifier_block); 2179a393b5dSSainath Grandhi if (err) 2189a393b5dSSainath Grandhi goto out3; 2199a393b5dSSainath Grandhi 2209a393b5dSSainath Grandhi err = macvlan_link_register(&macvtap_link_ops); 2219a393b5dSSainath Grandhi if (err) 2229a393b5dSSainath Grandhi goto out4; 2239a393b5dSSainath Grandhi 2249a393b5dSSainath Grandhi return 0; 2259a393b5dSSainath Grandhi 2269a393b5dSSainath Grandhi out4: 2279a393b5dSSainath Grandhi unregister_netdevice_notifier(&macvtap_notifier_block); 2289a393b5dSSainath Grandhi out3: 2299a393b5dSSainath Grandhi class_unregister(&macvtap_class); 2309a393b5dSSainath Grandhi out2: 2319a393b5dSSainath Grandhi tap_destroy_cdev(macvtap_major, &macvtap_cdev); 2329a393b5dSSainath Grandhi out1: 2339a393b5dSSainath Grandhi return err; 2349a393b5dSSainath Grandhi } 2359a393b5dSSainath Grandhi module_init(macvtap_init); 2369a393b5dSSainath Grandhi 2379a393b5dSSainath Grandhi static void macvtap_exit(void) 2389a393b5dSSainath Grandhi { 2399a393b5dSSainath Grandhi rtnl_link_unregister(&macvtap_link_ops); 2409a393b5dSSainath Grandhi unregister_netdevice_notifier(&macvtap_notifier_block); 2419a393b5dSSainath Grandhi class_unregister(&macvtap_class); 2429a393b5dSSainath Grandhi tap_destroy_cdev(macvtap_major, &macvtap_cdev); 2439a393b5dSSainath Grandhi } 2449a393b5dSSainath Grandhi module_exit(macvtap_exit); 2459a393b5dSSainath Grandhi 2469a393b5dSSainath Grandhi MODULE_ALIAS_RTNL_LINK("macvtap"); 2479a393b5dSSainath Grandhi MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>"); 2489a393b5dSSainath Grandhi MODULE_LICENSE("GPL"); 249