1*9a393b5dSSainath Grandhi #include <linux/etherdevice.h> 2*9a393b5dSSainath Grandhi #include <linux/if_macvlan.h> 3*9a393b5dSSainath Grandhi #include <linux/if_tap.h> 4*9a393b5dSSainath Grandhi #include <linux/if_vlan.h> 5*9a393b5dSSainath Grandhi #include <linux/interrupt.h> 6*9a393b5dSSainath Grandhi #include <linux/nsproxy.h> 7*9a393b5dSSainath Grandhi #include <linux/compat.h> 8*9a393b5dSSainath Grandhi #include <linux/if_tun.h> 9*9a393b5dSSainath Grandhi #include <linux/module.h> 10*9a393b5dSSainath Grandhi #include <linux/skbuff.h> 11*9a393b5dSSainath Grandhi #include <linux/cache.h> 12*9a393b5dSSainath Grandhi #include <linux/sched.h> 13*9a393b5dSSainath Grandhi #include <linux/types.h> 14*9a393b5dSSainath Grandhi #include <linux/slab.h> 15*9a393b5dSSainath Grandhi #include <linux/wait.h> 16*9a393b5dSSainath Grandhi #include <linux/cdev.h> 17*9a393b5dSSainath Grandhi #include <linux/idr.h> 18*9a393b5dSSainath Grandhi #include <linux/fs.h> 19*9a393b5dSSainath Grandhi #include <linux/uio.h> 20*9a393b5dSSainath Grandhi 21*9a393b5dSSainath Grandhi #include <net/net_namespace.h> 22*9a393b5dSSainath Grandhi #include <net/rtnetlink.h> 23*9a393b5dSSainath Grandhi #include <net/sock.h> 24*9a393b5dSSainath Grandhi #include <linux/virtio_net.h> 25*9a393b5dSSainath Grandhi #include <linux/skb_array.h> 26*9a393b5dSSainath Grandhi 27*9a393b5dSSainath Grandhi struct macvtap_dev { 28*9a393b5dSSainath Grandhi struct macvlan_dev vlan; 29*9a393b5dSSainath Grandhi struct tap_dev tap; 30*9a393b5dSSainath Grandhi }; 31*9a393b5dSSainath Grandhi 32*9a393b5dSSainath Grandhi /* 33*9a393b5dSSainath Grandhi * Variables for dealing with macvtaps device numbers. 34*9a393b5dSSainath Grandhi */ 35*9a393b5dSSainath Grandhi static dev_t macvtap_major; 36*9a393b5dSSainath Grandhi 37*9a393b5dSSainath Grandhi static const void *macvtap_net_namespace(struct device *d) 38*9a393b5dSSainath Grandhi { 39*9a393b5dSSainath Grandhi struct net_device *dev = to_net_dev(d->parent); 40*9a393b5dSSainath Grandhi return dev_net(dev); 41*9a393b5dSSainath Grandhi } 42*9a393b5dSSainath Grandhi 43*9a393b5dSSainath Grandhi static struct class macvtap_class = { 44*9a393b5dSSainath Grandhi .name = "macvtap", 45*9a393b5dSSainath Grandhi .owner = THIS_MODULE, 46*9a393b5dSSainath Grandhi .ns_type = &net_ns_type_operations, 47*9a393b5dSSainath Grandhi .namespace = macvtap_net_namespace, 48*9a393b5dSSainath Grandhi }; 49*9a393b5dSSainath Grandhi static struct cdev macvtap_cdev; 50*9a393b5dSSainath Grandhi 51*9a393b5dSSainath Grandhi #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ 52*9a393b5dSSainath Grandhi NETIF_F_TSO6 | NETIF_F_UFO) 53*9a393b5dSSainath Grandhi 54*9a393b5dSSainath Grandhi static void macvtap_count_tx_dropped(struct tap_dev *tap) 55*9a393b5dSSainath Grandhi { 56*9a393b5dSSainath Grandhi struct macvtap_dev *vlantap = container_of(tap, struct macvtap_dev, tap); 57*9a393b5dSSainath Grandhi struct macvlan_dev *vlan = &vlantap->vlan; 58*9a393b5dSSainath Grandhi 59*9a393b5dSSainath Grandhi this_cpu_inc(vlan->pcpu_stats->tx_dropped); 60*9a393b5dSSainath Grandhi } 61*9a393b5dSSainath Grandhi 62*9a393b5dSSainath Grandhi static void macvtap_count_rx_dropped(struct tap_dev *tap) 63*9a393b5dSSainath Grandhi { 64*9a393b5dSSainath Grandhi struct macvtap_dev *vlantap = container_of(tap, struct macvtap_dev, tap); 65*9a393b5dSSainath Grandhi struct macvlan_dev *vlan = &vlantap->vlan; 66*9a393b5dSSainath Grandhi 67*9a393b5dSSainath Grandhi macvlan_count_rx(vlan, 0, 0, 0); 68*9a393b5dSSainath Grandhi } 69*9a393b5dSSainath Grandhi 70*9a393b5dSSainath Grandhi static void macvtap_update_features(struct tap_dev *tap, 71*9a393b5dSSainath Grandhi netdev_features_t features) 72*9a393b5dSSainath Grandhi { 73*9a393b5dSSainath Grandhi struct macvtap_dev *vlantap = container_of(tap, struct macvtap_dev, tap); 74*9a393b5dSSainath Grandhi struct macvlan_dev *vlan = &vlantap->vlan; 75*9a393b5dSSainath Grandhi 76*9a393b5dSSainath Grandhi vlan->set_features = features; 77*9a393b5dSSainath Grandhi netdev_update_features(vlan->dev); 78*9a393b5dSSainath Grandhi } 79*9a393b5dSSainath Grandhi 80*9a393b5dSSainath Grandhi static int macvtap_newlink(struct net *src_net, 81*9a393b5dSSainath Grandhi struct net_device *dev, 82*9a393b5dSSainath Grandhi struct nlattr *tb[], 83*9a393b5dSSainath Grandhi struct nlattr *data[]) 84*9a393b5dSSainath Grandhi { 85*9a393b5dSSainath Grandhi struct macvtap_dev *vlantap = netdev_priv(dev); 86*9a393b5dSSainath Grandhi int err; 87*9a393b5dSSainath Grandhi 88*9a393b5dSSainath Grandhi INIT_LIST_HEAD(&vlantap->tap.queue_list); 89*9a393b5dSSainath Grandhi 90*9a393b5dSSainath Grandhi /* Since macvlan supports all offloads by default, make 91*9a393b5dSSainath Grandhi * tap support all offloads also. 92*9a393b5dSSainath Grandhi */ 93*9a393b5dSSainath Grandhi vlantap->tap.tap_features = TUN_OFFLOADS; 94*9a393b5dSSainath Grandhi 95*9a393b5dSSainath Grandhi /* Register callbacks for rx/tx drops accounting and updating 96*9a393b5dSSainath Grandhi * net_device features 97*9a393b5dSSainath Grandhi */ 98*9a393b5dSSainath Grandhi vlantap->tap.count_tx_dropped = macvtap_count_tx_dropped; 99*9a393b5dSSainath Grandhi vlantap->tap.count_rx_dropped = macvtap_count_rx_dropped; 100*9a393b5dSSainath Grandhi vlantap->tap.update_features = macvtap_update_features; 101*9a393b5dSSainath Grandhi 102*9a393b5dSSainath Grandhi err = netdev_rx_handler_register(dev, tap_handle_frame, &vlantap->tap); 103*9a393b5dSSainath Grandhi if (err) 104*9a393b5dSSainath Grandhi return err; 105*9a393b5dSSainath Grandhi 106*9a393b5dSSainath Grandhi /* Don't put anything that may fail after macvlan_common_newlink 107*9a393b5dSSainath Grandhi * because we can't undo what it does. 108*9a393b5dSSainath Grandhi */ 109*9a393b5dSSainath Grandhi err = macvlan_common_newlink(src_net, dev, tb, data); 110*9a393b5dSSainath Grandhi if (err) { 111*9a393b5dSSainath Grandhi netdev_rx_handler_unregister(dev); 112*9a393b5dSSainath Grandhi return err; 113*9a393b5dSSainath Grandhi } 114*9a393b5dSSainath Grandhi 115*9a393b5dSSainath Grandhi vlantap->tap.dev = vlantap->vlan.dev; 116*9a393b5dSSainath Grandhi 117*9a393b5dSSainath Grandhi return 0; 118*9a393b5dSSainath Grandhi } 119*9a393b5dSSainath Grandhi 120*9a393b5dSSainath Grandhi static void macvtap_dellink(struct net_device *dev, 121*9a393b5dSSainath Grandhi struct list_head *head) 122*9a393b5dSSainath Grandhi { 123*9a393b5dSSainath Grandhi struct macvtap_dev *vlantap = netdev_priv(dev); 124*9a393b5dSSainath Grandhi 125*9a393b5dSSainath Grandhi netdev_rx_handler_unregister(dev); 126*9a393b5dSSainath Grandhi tap_del_queues(&vlantap->tap); 127*9a393b5dSSainath Grandhi macvlan_dellink(dev, head); 128*9a393b5dSSainath Grandhi } 129*9a393b5dSSainath Grandhi 130*9a393b5dSSainath Grandhi static void macvtap_setup(struct net_device *dev) 131*9a393b5dSSainath Grandhi { 132*9a393b5dSSainath Grandhi macvlan_common_setup(dev); 133*9a393b5dSSainath Grandhi dev->tx_queue_len = TUN_READQ_SIZE; 134*9a393b5dSSainath Grandhi } 135*9a393b5dSSainath Grandhi 136*9a393b5dSSainath Grandhi static struct rtnl_link_ops macvtap_link_ops __read_mostly = { 137*9a393b5dSSainath Grandhi .kind = "macvtap", 138*9a393b5dSSainath Grandhi .setup = macvtap_setup, 139*9a393b5dSSainath Grandhi .newlink = macvtap_newlink, 140*9a393b5dSSainath Grandhi .dellink = macvtap_dellink, 141*9a393b5dSSainath Grandhi .priv_size = sizeof(struct macvtap_dev), 142*9a393b5dSSainath Grandhi }; 143*9a393b5dSSainath Grandhi 144*9a393b5dSSainath Grandhi static int macvtap_device_event(struct notifier_block *unused, 145*9a393b5dSSainath Grandhi unsigned long event, void *ptr) 146*9a393b5dSSainath Grandhi { 147*9a393b5dSSainath Grandhi struct net_device *dev = netdev_notifier_info_to_dev(ptr); 148*9a393b5dSSainath Grandhi struct macvtap_dev *vlantap; 149*9a393b5dSSainath Grandhi struct device *classdev; 150*9a393b5dSSainath Grandhi dev_t devt; 151*9a393b5dSSainath Grandhi int err; 152*9a393b5dSSainath Grandhi char tap_name[IFNAMSIZ]; 153*9a393b5dSSainath Grandhi 154*9a393b5dSSainath Grandhi if (dev->rtnl_link_ops != &macvtap_link_ops) 155*9a393b5dSSainath Grandhi return NOTIFY_DONE; 156*9a393b5dSSainath Grandhi 157*9a393b5dSSainath Grandhi snprintf(tap_name, IFNAMSIZ, "tap%d", dev->ifindex); 158*9a393b5dSSainath Grandhi vlantap = netdev_priv(dev); 159*9a393b5dSSainath Grandhi 160*9a393b5dSSainath Grandhi switch (event) { 161*9a393b5dSSainath Grandhi case NETDEV_REGISTER: 162*9a393b5dSSainath Grandhi /* Create the device node here after the network device has 163*9a393b5dSSainath Grandhi * been registered but before register_netdevice has 164*9a393b5dSSainath Grandhi * finished running. 165*9a393b5dSSainath Grandhi */ 166*9a393b5dSSainath Grandhi err = tap_get_minor(macvtap_major, &vlantap->tap); 167*9a393b5dSSainath Grandhi if (err) 168*9a393b5dSSainath Grandhi return notifier_from_errno(err); 169*9a393b5dSSainath Grandhi 170*9a393b5dSSainath Grandhi devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor); 171*9a393b5dSSainath Grandhi classdev = device_create(&macvtap_class, &dev->dev, devt, 172*9a393b5dSSainath Grandhi dev, tap_name); 173*9a393b5dSSainath Grandhi if (IS_ERR(classdev)) { 174*9a393b5dSSainath Grandhi tap_free_minor(macvtap_major, &vlantap->tap); 175*9a393b5dSSainath Grandhi return notifier_from_errno(PTR_ERR(classdev)); 176*9a393b5dSSainath Grandhi } 177*9a393b5dSSainath Grandhi err = sysfs_create_link(&dev->dev.kobj, &classdev->kobj, 178*9a393b5dSSainath Grandhi tap_name); 179*9a393b5dSSainath Grandhi if (err) 180*9a393b5dSSainath Grandhi return notifier_from_errno(err); 181*9a393b5dSSainath Grandhi break; 182*9a393b5dSSainath Grandhi case NETDEV_UNREGISTER: 183*9a393b5dSSainath Grandhi /* vlan->minor == 0 if NETDEV_REGISTER above failed */ 184*9a393b5dSSainath Grandhi if (vlantap->tap.minor == 0) 185*9a393b5dSSainath Grandhi break; 186*9a393b5dSSainath Grandhi sysfs_remove_link(&dev->dev.kobj, tap_name); 187*9a393b5dSSainath Grandhi devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor); 188*9a393b5dSSainath Grandhi device_destroy(&macvtap_class, devt); 189*9a393b5dSSainath Grandhi tap_free_minor(macvtap_major, &vlantap->tap); 190*9a393b5dSSainath Grandhi break; 191*9a393b5dSSainath Grandhi case NETDEV_CHANGE_TX_QUEUE_LEN: 192*9a393b5dSSainath Grandhi if (tap_queue_resize(&vlantap->tap)) 193*9a393b5dSSainath Grandhi return NOTIFY_BAD; 194*9a393b5dSSainath Grandhi break; 195*9a393b5dSSainath Grandhi } 196*9a393b5dSSainath Grandhi 197*9a393b5dSSainath Grandhi return NOTIFY_DONE; 198*9a393b5dSSainath Grandhi } 199*9a393b5dSSainath Grandhi 200*9a393b5dSSainath Grandhi static struct notifier_block macvtap_notifier_block __read_mostly = { 201*9a393b5dSSainath Grandhi .notifier_call = macvtap_device_event, 202*9a393b5dSSainath Grandhi }; 203*9a393b5dSSainath Grandhi 204*9a393b5dSSainath Grandhi static int macvtap_init(void) 205*9a393b5dSSainath Grandhi { 206*9a393b5dSSainath Grandhi int err; 207*9a393b5dSSainath Grandhi 208*9a393b5dSSainath Grandhi err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap"); 209*9a393b5dSSainath Grandhi 210*9a393b5dSSainath Grandhi if (err) 211*9a393b5dSSainath Grandhi goto out1; 212*9a393b5dSSainath Grandhi 213*9a393b5dSSainath Grandhi err = class_register(&macvtap_class); 214*9a393b5dSSainath Grandhi if (err) 215*9a393b5dSSainath Grandhi goto out2; 216*9a393b5dSSainath Grandhi 217*9a393b5dSSainath Grandhi err = register_netdevice_notifier(&macvtap_notifier_block); 218*9a393b5dSSainath Grandhi if (err) 219*9a393b5dSSainath Grandhi goto out3; 220*9a393b5dSSainath Grandhi 221*9a393b5dSSainath Grandhi err = macvlan_link_register(&macvtap_link_ops); 222*9a393b5dSSainath Grandhi if (err) 223*9a393b5dSSainath Grandhi goto out4; 224*9a393b5dSSainath Grandhi 225*9a393b5dSSainath Grandhi return 0; 226*9a393b5dSSainath Grandhi 227*9a393b5dSSainath Grandhi out4: 228*9a393b5dSSainath Grandhi unregister_netdevice_notifier(&macvtap_notifier_block); 229*9a393b5dSSainath Grandhi out3: 230*9a393b5dSSainath Grandhi class_unregister(&macvtap_class); 231*9a393b5dSSainath Grandhi out2: 232*9a393b5dSSainath Grandhi tap_destroy_cdev(macvtap_major, &macvtap_cdev); 233*9a393b5dSSainath Grandhi out1: 234*9a393b5dSSainath Grandhi return err; 235*9a393b5dSSainath Grandhi } 236*9a393b5dSSainath Grandhi module_init(macvtap_init); 237*9a393b5dSSainath Grandhi 238*9a393b5dSSainath Grandhi static void macvtap_exit(void) 239*9a393b5dSSainath Grandhi { 240*9a393b5dSSainath Grandhi rtnl_link_unregister(&macvtap_link_ops); 241*9a393b5dSSainath Grandhi unregister_netdevice_notifier(&macvtap_notifier_block); 242*9a393b5dSSainath Grandhi class_unregister(&macvtap_class); 243*9a393b5dSSainath Grandhi tap_destroy_cdev(macvtap_major, &macvtap_cdev); 244*9a393b5dSSainath Grandhi } 245*9a393b5dSSainath Grandhi module_exit(macvtap_exit); 246*9a393b5dSSainath Grandhi 247*9a393b5dSSainath Grandhi MODULE_ALIAS_RTNL_LINK("macvtap"); 248*9a393b5dSSainath Grandhi MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>"); 249*9a393b5dSSainath Grandhi MODULE_LICENSE("GPL"); 250