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