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 /* 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
vxcan_open(struct net_device * dev)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
vxcan_close(struct net_device * dev)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
vxcan_get_iflink(const struct net_device * dev)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
vxcan_set_cap_info(struct net_device * dev)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
vxcan_change_mtu(struct net_device * dev,int new_mtu)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
vxcan_setup(struct net_device * dev)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
vxcan_newlink(struct net_device * dev,struct rtnl_newlink_params * params,struct netlink_ext_ack * extack)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
vxcan_dellink(struct net_device * dev,struct list_head * head)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
vxcan_get_link_net(const struct net_device * dev)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
vxcan_init(void)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
vxcan_exit(void)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