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