xref: /linux/drivers/net/can/vxcan.c (revision 7093c3b8314a4ef7405c4066a2521398c455efe7)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * vxcan.c - Virtual CAN Tunnel for cross namespace communication
4  *
5  * This code is derived from drivers/net/can/vcan.c for the virtual CAN
6  * specific parts and from drivers/net/veth.c to implement the netlink API
7  * for network interface pairs in a common and established way.
8  *
9  * Copyright (c) 2017 Oliver Hartkopp <socketcan@hartkopp.net>
10  */
11 
12 #include <linux/ethtool.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/netdevice.h>
16 #include <linux/if_arp.h>
17 #include <linux/if_ether.h>
18 #include <linux/can.h>
19 #include <linux/can/dev.h>
20 #include <linux/can/skb.h>
21 #include <linux/can/vxcan.h>
22 #include <linux/can/can-ml.h>
23 #include <linux/slab.h>
24 #include <net/can.h>
25 #include <net/rtnetlink.h>
26 
27 #define DRV_NAME "vxcan"
28 
29 MODULE_DESCRIPTION("Virtual CAN Tunnel");
30 MODULE_LICENSE("GPL");
31 MODULE_AUTHOR("Oliver Hartkopp <socketcan@hartkopp.net>");
32 MODULE_ALIAS_RTNL_LINK(DRV_NAME);
33 
34 struct vxcan_priv {
35 	struct net_device __rcu	*peer;
36 	netdevice_tracker peer_tracker;
37 };
38 
39 static netdev_tx_t vxcan_xmit(struct sk_buff *oskb, struct net_device *dev)
40 {
41 	struct vxcan_priv *priv = netdev_priv(dev);
42 	struct net_device *peer;
43 	struct net_device_stats *peerstats, *srcstats = &dev->stats;
44 	struct can_skb_ext *csx;
45 	struct sk_buff *skb;
46 	unsigned int len;
47 
48 	if (can_dropped_invalid_skb(dev, oskb))
49 		return NETDEV_TX_OK;
50 
51 	rcu_read_lock();
52 	peer = rcu_dereference(priv->peer);
53 	if (unlikely(!peer)) {
54 		kfree_skb(oskb);
55 		dev->stats.tx_dropped++;
56 		goto out_unlock;
57 	}
58 
59 	skb_tx_timestamp(oskb);
60 
61 	skb = skb_clone(oskb, GFP_ATOMIC);
62 	if (skb) {
63 		consume_skb(oskb);
64 	} else {
65 		kfree_skb(oskb);
66 		goto out_unlock;
67 	}
68 
69 	/* the cloned skb points to the skb extension of the already cloned
70 	 * oskb with an increased refcount. skb_ext_add() creates a copy to
71 	 * separate the skb extension data which is needed to start with a
72 	 * fresh can_gw_hops counter in the other namespace.
73 	 */
74 	csx = skb_ext_add(skb, SKB_EXT_CAN);
75 	if (!csx) {
76 		kfree_skb(skb);
77 		goto out_unlock;
78 	}
79 
80 	/* reset CAN GW hop counter */
81 	csx->can_gw_hops = 0;
82 	/* start with new CAN skb UID in the other namespace */
83 	csx->can_skb_uid = 0;
84 
85 	skb->pkt_type   = PACKET_BROADCAST;
86 	skb->dev        = peer;
87 	skb->ip_summed  = CHECKSUM_UNNECESSARY;
88 
89 	len = can_skb_get_data_len(skb);
90 	if (netif_rx(skb) == NET_RX_SUCCESS) {
91 		srcstats->tx_packets++;
92 		srcstats->tx_bytes += len;
93 		peerstats = &peer->stats;
94 		peerstats->rx_packets++;
95 		peerstats->rx_bytes += len;
96 	}
97 
98 out_unlock:
99 	rcu_read_unlock();
100 	return NETDEV_TX_OK;
101 }
102 
103 
104 static int vxcan_open(struct net_device *dev)
105 {
106 	struct vxcan_priv *priv = netdev_priv(dev);
107 	struct net_device *peer = rtnl_dereference(priv->peer);
108 
109 	if (!peer)
110 		return -ENOTCONN;
111 
112 	if (peer->flags & IFF_UP) {
113 		netif_carrier_on(dev);
114 		netif_carrier_on(peer);
115 	}
116 	return 0;
117 }
118 
119 static int vxcan_close(struct net_device *dev)
120 {
121 	struct vxcan_priv *priv = netdev_priv(dev);
122 	struct net_device *peer = rtnl_dereference(priv->peer);
123 
124 	netif_carrier_off(dev);
125 	if (peer)
126 		netif_carrier_off(peer);
127 
128 	return 0;
129 }
130 
131 static int vxcan_get_iflink(const struct net_device *dev)
132 {
133 	struct vxcan_priv *priv = netdev_priv(dev);
134 	struct net_device *peer;
135 	int iflink;
136 
137 	rcu_read_lock();
138 	peer = rcu_dereference(priv->peer);
139 	iflink = peer ? READ_ONCE(peer->ifindex) : 0;
140 	rcu_read_unlock();
141 
142 	return iflink;
143 }
144 
145 static void vxcan_set_cap_info(struct net_device *dev)
146 {
147 	u32 can_cap = CAN_CAP_CC;
148 
149 	if (dev->mtu > CAN_MTU)
150 		can_cap |= CAN_CAP_FD;
151 
152 	if (dev->mtu >= CANXL_MIN_MTU)
153 		can_cap |= CAN_CAP_XL;
154 
155 	can_set_cap(dev, can_cap);
156 }
157 
158 static int vxcan_change_mtu(struct net_device *dev, int new_mtu)
159 {
160 	/* Do not allow changing the MTU while running */
161 	if (dev->flags & IFF_UP)
162 		return -EBUSY;
163 
164 	if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU &&
165 	    !can_is_canxl_dev_mtu(new_mtu))
166 		return -EINVAL;
167 
168 	WRITE_ONCE(dev->mtu, new_mtu);
169 	vxcan_set_cap_info(dev);
170 	return 0;
171 }
172 
173 static const struct net_device_ops vxcan_netdev_ops = {
174 	.ndo_open	= vxcan_open,
175 	.ndo_stop	= vxcan_close,
176 	.ndo_start_xmit	= vxcan_xmit,
177 	.ndo_get_iflink	= vxcan_get_iflink,
178 	.ndo_change_mtu = vxcan_change_mtu,
179 };
180 
181 static const struct ethtool_ops vxcan_ethtool_ops = {
182 	.get_ts_info = ethtool_op_get_ts_info,
183 };
184 
185 static void vxcan_setup(struct net_device *dev)
186 {
187 	struct can_ml_priv *can_ml;
188 
189 	dev->type		= ARPHRD_CAN;
190 	dev->mtu		= CANXL_MTU;
191 	dev->hard_header_len	= 0;
192 	dev->addr_len		= 0;
193 	dev->tx_queue_len	= 0;
194 	dev->flags		= IFF_NOARP;
195 	dev->netdev_ops		= &vxcan_netdev_ops;
196 	dev->ethtool_ops	= &vxcan_ethtool_ops;
197 	dev->needs_free_netdev	= true;
198 
199 	can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN);
200 	can_set_ml_priv(dev, can_ml);
201 	vxcan_set_cap_info(dev);
202 }
203 
204 /* forward declaration for rtnl_create_link() */
205 static struct rtnl_link_ops vxcan_link_ops;
206 
207 static int vxcan_newlink(struct net_device *dev,
208 			 struct rtnl_newlink_params *params,
209 			 struct netlink_ext_ack *extack)
210 {
211 	struct net *peer_net = rtnl_newlink_peer_net(params);
212 	struct nlattr **data = params->data;
213 	struct nlattr **tb = params->tb;
214 	struct vxcan_priv *priv;
215 	struct net_device *peer;
216 
217 	struct nlattr *peer_tb[IFLA_MAX + 1], **tbp = tb;
218 	char ifname[IFNAMSIZ];
219 	unsigned char name_assign_type;
220 	struct ifinfomsg *ifmp = NULL;
221 	int err;
222 
223 	/* register peer device */
224 	if (data && data[VXCAN_INFO_PEER]) {
225 		struct nlattr *nla_peer = data[VXCAN_INFO_PEER];
226 
227 		ifmp = nla_data(nla_peer);
228 		rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack);
229 		tbp = peer_tb;
230 	}
231 
232 	if (ifmp && tbp[IFLA_IFNAME]) {
233 		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
234 		name_assign_type = NET_NAME_USER;
235 	} else {
236 		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
237 		name_assign_type = NET_NAME_ENUM;
238 	}
239 
240 	peer = rtnl_create_link(peer_net, ifname, name_assign_type,
241 				&vxcan_link_ops, tbp, extack);
242 	if (IS_ERR(peer))
243 		return PTR_ERR(peer);
244 
245 	if (ifmp && dev->ifindex)
246 		peer->ifindex = ifmp->ifi_index;
247 
248 	err = register_netdevice(peer);
249 	if (err < 0) {
250 		free_netdev(peer);
251 		return err;
252 	}
253 
254 	netif_carrier_off(peer);
255 
256 	err = rtnl_configure_link(peer, ifmp, 0, NULL);
257 	if (err < 0)
258 		goto unregister_network_device;
259 
260 	/* register first device */
261 	if (tb[IFLA_IFNAME])
262 		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
263 	else
264 		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
265 
266 	err = register_netdevice(dev);
267 	if (err < 0)
268 		goto unregister_network_device;
269 
270 	netif_carrier_off(dev);
271 
272 	/* cross link the device pair */
273 	priv = netdev_priv(dev);
274 	rcu_assign_pointer(priv->peer, peer);
275 	netdev_hold(peer, &priv->peer_tracker, GFP_KERNEL);
276 
277 	priv = netdev_priv(peer);
278 	rcu_assign_pointer(priv->peer, dev);
279 	netdev_hold(dev, &priv->peer_tracker, GFP_KERNEL);
280 
281 	return 0;
282 
283 unregister_network_device:
284 	unregister_netdevice(peer);
285 	return err;
286 }
287 
288 static void vxcan_dellink(struct net_device *dev, struct list_head *head)
289 {
290 	netdevice_tracker *peer_tracker;
291 	struct vxcan_priv *priv;
292 	struct net_device *peer;
293 
294 	priv = netdev_priv(dev);
295 	peer_tracker = &priv->peer_tracker;
296 	peer = unrcu_pointer(xchg(&priv->peer, NULL));
297 	if (!peer)
298 		return;
299 
300 	unregister_netdevice_queue(dev, head);
301 
302 	priv = netdev_priv(peer);
303 	dev = unrcu_pointer(xchg(&priv->peer, NULL));
304 	if (dev)
305 		unregister_netdevice_queue_net(dev_net(dev), peer, head);
306 
307 	netdev_put(peer, peer_tracker);
308 	netdev_put(dev, &priv->peer_tracker);
309 }
310 
311 static const struct nla_policy vxcan_policy[VXCAN_INFO_MAX + 1] = {
312 	[VXCAN_INFO_PEER] = { .len = sizeof(struct ifinfomsg) },
313 };
314 
315 static struct net *vxcan_get_link_net(const struct net_device *dev)
316 {
317 	struct vxcan_priv *priv = netdev_priv(dev);
318 	struct net_device *peer = rtnl_dereference(priv->peer);
319 
320 	return peer ? dev_net(peer) : dev_net(dev);
321 }
322 
323 static struct rtnl_link_ops vxcan_link_ops = {
324 	.kind		= DRV_NAME,
325 	.priv_size	= ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN) + sizeof(struct can_ml_priv),
326 	.setup		= vxcan_setup,
327 	.newlink	= vxcan_newlink,
328 	.dellink	= vxcan_dellink,
329 	.policy		= vxcan_policy,
330 	.peer_type	= VXCAN_INFO_PEER,
331 	.maxtype	= VXCAN_INFO_MAX,
332 	.get_link_net	= vxcan_get_link_net,
333 };
334 
335 static __init int vxcan_init(void)
336 {
337 	pr_info("vxcan: Virtual CAN Tunnel driver\n");
338 
339 	return rtnl_link_register(&vxcan_link_ops);
340 }
341 
342 static __exit void vxcan_exit(void)
343 {
344 	rtnl_link_unregister(&vxcan_link_ops);
345 }
346 
347 module_init(vxcan_init);
348 module_exit(vxcan_exit);
349