xref: /linux/drivers/net/can/vxcan.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
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 
vxcan_xmit(struct sk_buff * oskb,struct net_device * dev)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 	skb->pkt_type   = PACKET_BROADCAST;
83 	skb->dev        = peer;
84 	skb->ip_summed  = CHECKSUM_UNNECESSARY;
85 
86 	len = can_skb_get_data_len(skb);
87 	if (netif_rx(skb) == NET_RX_SUCCESS) {
88 		srcstats->tx_packets++;
89 		srcstats->tx_bytes += len;
90 		peerstats = &peer->stats;
91 		peerstats->rx_packets++;
92 		peerstats->rx_bytes += len;
93 	}
94 
95 out_unlock:
96 	rcu_read_unlock();
97 	return NETDEV_TX_OK;
98 }
99 
100 
vxcan_open(struct net_device * dev)101 static int vxcan_open(struct net_device *dev)
102 {
103 	struct vxcan_priv *priv = netdev_priv(dev);
104 	struct net_device *peer = rtnl_dereference(priv->peer);
105 
106 	if (!peer)
107 		return -ENOTCONN;
108 
109 	if (peer->flags & IFF_UP) {
110 		netif_carrier_on(dev);
111 		netif_carrier_on(peer);
112 	}
113 	return 0;
114 }
115 
vxcan_close(struct net_device * dev)116 static int vxcan_close(struct net_device *dev)
117 {
118 	struct vxcan_priv *priv = netdev_priv(dev);
119 	struct net_device *peer = rtnl_dereference(priv->peer);
120 
121 	netif_carrier_off(dev);
122 	if (peer)
123 		netif_carrier_off(peer);
124 
125 	return 0;
126 }
127 
vxcan_get_iflink(const struct net_device * dev)128 static int vxcan_get_iflink(const struct net_device *dev)
129 {
130 	struct vxcan_priv *priv = netdev_priv(dev);
131 	struct net_device *peer;
132 	int iflink;
133 
134 	rcu_read_lock();
135 	peer = rcu_dereference(priv->peer);
136 	iflink = peer ? READ_ONCE(peer->ifindex) : 0;
137 	rcu_read_unlock();
138 
139 	return iflink;
140 }
141 
vxcan_set_cap_info(struct net_device * dev)142 static void vxcan_set_cap_info(struct net_device *dev)
143 {
144 	u32 can_cap = CAN_CAP_CC;
145 
146 	if (dev->mtu > CAN_MTU)
147 		can_cap |= CAN_CAP_FD;
148 
149 	if (dev->mtu >= CANXL_MIN_MTU)
150 		can_cap |= CAN_CAP_XL;
151 
152 	can_set_cap(dev, can_cap);
153 }
154 
vxcan_change_mtu(struct net_device * dev,int new_mtu)155 static int vxcan_change_mtu(struct net_device *dev, int new_mtu)
156 {
157 	/* Do not allow changing the MTU while running */
158 	if (dev->flags & IFF_UP)
159 		return -EBUSY;
160 
161 	if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU &&
162 	    !can_is_canxl_dev_mtu(new_mtu))
163 		return -EINVAL;
164 
165 	WRITE_ONCE(dev->mtu, new_mtu);
166 	vxcan_set_cap_info(dev);
167 	return 0;
168 }
169 
170 static const struct net_device_ops vxcan_netdev_ops = {
171 	.ndo_open	= vxcan_open,
172 	.ndo_stop	= vxcan_close,
173 	.ndo_start_xmit	= vxcan_xmit,
174 	.ndo_get_iflink	= vxcan_get_iflink,
175 	.ndo_change_mtu = vxcan_change_mtu,
176 };
177 
178 static const struct ethtool_ops vxcan_ethtool_ops = {
179 	.get_ts_info = ethtool_op_get_ts_info,
180 };
181 
vxcan_setup(struct net_device * dev)182 static void vxcan_setup(struct net_device *dev)
183 {
184 	struct can_ml_priv *can_ml;
185 
186 	dev->type		= ARPHRD_CAN;
187 	dev->mtu		= CANXL_MTU;
188 	dev->hard_header_len	= 0;
189 	dev->addr_len		= 0;
190 	dev->tx_queue_len	= 0;
191 	dev->flags		= IFF_NOARP;
192 	dev->netdev_ops		= &vxcan_netdev_ops;
193 	dev->ethtool_ops	= &vxcan_ethtool_ops;
194 	dev->needs_free_netdev	= true;
195 
196 	can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN);
197 	can_set_ml_priv(dev, can_ml);
198 	vxcan_set_cap_info(dev);
199 }
200 
201 /* forward declaration for rtnl_create_link() */
202 static struct rtnl_link_ops vxcan_link_ops;
203 
vxcan_newlink(struct net_device * dev,struct rtnl_newlink_params * params,struct netlink_ext_ack * extack)204 static int vxcan_newlink(struct net_device *dev,
205 			 struct rtnl_newlink_params *params,
206 			 struct netlink_ext_ack *extack)
207 {
208 	struct net *peer_net = rtnl_newlink_peer_net(params);
209 	struct nlattr **data = params->data;
210 	struct nlattr **tb = params->tb;
211 	struct vxcan_priv *priv;
212 	struct net_device *peer;
213 
214 	struct nlattr *peer_tb[IFLA_MAX + 1], **tbp = tb;
215 	char ifname[IFNAMSIZ];
216 	unsigned char name_assign_type;
217 	struct ifinfomsg *ifmp = NULL;
218 	int err;
219 
220 	/* register peer device */
221 	if (data && data[VXCAN_INFO_PEER]) {
222 		struct nlattr *nla_peer = data[VXCAN_INFO_PEER];
223 
224 		ifmp = nla_data(nla_peer);
225 		rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack);
226 		tbp = peer_tb;
227 	}
228 
229 	if (ifmp && tbp[IFLA_IFNAME]) {
230 		nla_strscpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
231 		name_assign_type = NET_NAME_USER;
232 	} else {
233 		snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
234 		name_assign_type = NET_NAME_ENUM;
235 	}
236 
237 	peer = rtnl_create_link(peer_net, ifname, name_assign_type,
238 				&vxcan_link_ops, tbp, extack);
239 	if (IS_ERR(peer))
240 		return PTR_ERR(peer);
241 
242 	if (ifmp && dev->ifindex)
243 		peer->ifindex = ifmp->ifi_index;
244 
245 	err = register_netdevice(peer);
246 	if (err < 0) {
247 		free_netdev(peer);
248 		return err;
249 	}
250 
251 	netif_carrier_off(peer);
252 
253 	err = rtnl_configure_link(peer, ifmp, 0, NULL);
254 	if (err < 0)
255 		goto unregister_network_device;
256 
257 	/* register first device */
258 	if (tb[IFLA_IFNAME])
259 		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
260 	else
261 		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
262 
263 	err = register_netdevice(dev);
264 	if (err < 0)
265 		goto unregister_network_device;
266 
267 	netif_carrier_off(dev);
268 
269 	/* cross link the device pair */
270 	priv = netdev_priv(dev);
271 	rcu_assign_pointer(priv->peer, peer);
272 	netdev_hold(peer, &priv->peer_tracker, GFP_KERNEL);
273 
274 	priv = netdev_priv(peer);
275 	rcu_assign_pointer(priv->peer, dev);
276 	netdev_hold(dev, &priv->peer_tracker, GFP_KERNEL);
277 
278 	return 0;
279 
280 unregister_network_device:
281 	unregister_netdevice(peer);
282 	return err;
283 }
284 
vxcan_dellink(struct net_device * dev,struct list_head * head)285 static void vxcan_dellink(struct net_device *dev, struct list_head *head)
286 {
287 	netdevice_tracker *peer_tracker;
288 	struct vxcan_priv *priv;
289 	struct net_device *peer;
290 
291 	priv = netdev_priv(dev);
292 	peer_tracker = &priv->peer_tracker;
293 	peer = unrcu_pointer(xchg(&priv->peer, NULL));
294 	if (!peer)
295 		return;
296 
297 	unregister_netdevice_queue(dev, head);
298 
299 	priv = netdev_priv(peer);
300 	dev = unrcu_pointer(xchg(&priv->peer, NULL));
301 	if (dev)
302 		unregister_netdevice_queue_net(dev_net(dev), peer, head);
303 
304 	netdev_put(peer, peer_tracker);
305 	netdev_put(dev, &priv->peer_tracker);
306 }
307 
308 static const struct nla_policy vxcan_policy[VXCAN_INFO_MAX + 1] = {
309 	[VXCAN_INFO_PEER] = { .len = sizeof(struct ifinfomsg) },
310 };
311 
vxcan_get_link_net(const struct net_device * dev)312 static struct net *vxcan_get_link_net(const struct net_device *dev)
313 {
314 	struct vxcan_priv *priv = netdev_priv(dev);
315 	struct net_device *peer = rtnl_dereference(priv->peer);
316 
317 	return peer ? dev_net(peer) : dev_net(dev);
318 }
319 
320 static struct rtnl_link_ops vxcan_link_ops = {
321 	.kind		= DRV_NAME,
322 	.priv_size	= ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN) + sizeof(struct can_ml_priv),
323 	.setup		= vxcan_setup,
324 	.newlink	= vxcan_newlink,
325 	.dellink	= vxcan_dellink,
326 	.policy		= vxcan_policy,
327 	.peer_type	= VXCAN_INFO_PEER,
328 	.maxtype	= VXCAN_INFO_MAX,
329 	.get_link_net	= vxcan_get_link_net,
330 };
331 
vxcan_init(void)332 static __init int vxcan_init(void)
333 {
334 	pr_info("vxcan: Virtual CAN Tunnel driver\n");
335 
336 	return rtnl_link_register(&vxcan_link_ops);
337 }
338 
vxcan_exit(void)339 static __exit void vxcan_exit(void)
340 {
341 	rtnl_link_unregister(&vxcan_link_ops);
342 }
343 
344 module_init(vxcan_init);
345 module_exit(vxcan_exit);
346