Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/*
2 * Copyright (C) 2017 Netronome Systems, Inc.
3 *
4 * This software is licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this
6 * source tree.
7 *
8 * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
9 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
10 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11 * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
12 * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
13 * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
14 */
15
16#include <linux/debugfs.h>
17#include <linux/etherdevice.h>
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/netdevice.h>
21#include <linux/slab.h>
22#include <net/netlink.h>
23#include <net/pkt_cls.h>
24#include <net/rtnetlink.h>
25
26#include "netdevsim.h"
27
28static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
29{
30 struct netdevsim *ns = netdev_priv(dev);
31
32 if (!nsim_ipsec_tx(ns, skb))
33 goto out;
34
35 u64_stats_update_begin(&ns->syncp);
36 ns->tx_packets++;
37 ns->tx_bytes += skb->len;
38 u64_stats_update_end(&ns->syncp);
39
40out:
41 dev_kfree_skb(skb);
42
43 return NETDEV_TX_OK;
44}
45
46static void nsim_set_rx_mode(struct net_device *dev)
47{
48}
49
50static int nsim_change_mtu(struct net_device *dev, int new_mtu)
51{
52 struct netdevsim *ns = netdev_priv(dev);
53
54 if (ns->xdp.prog && new_mtu > NSIM_XDP_MAX_MTU)
55 return -EBUSY;
56
57 dev->mtu = new_mtu;
58
59 return 0;
60}
61
62static void
63nsim_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
64{
65 struct netdevsim *ns = netdev_priv(dev);
66 unsigned int start;
67
68 do {
69 start = u64_stats_fetch_begin(&ns->syncp);
70 stats->tx_bytes = ns->tx_bytes;
71 stats->tx_packets = ns->tx_packets;
72 } while (u64_stats_fetch_retry(&ns->syncp, start));
73}
74
75static int
76nsim_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
77{
78 return nsim_bpf_setup_tc_block_cb(type, type_data, cb_priv);
79}
80
81static int
82nsim_setup_tc_block(struct net_device *dev, struct tc_block_offload *f)
83{
84 struct netdevsim *ns = netdev_priv(dev);
85
86 if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
87 return -EOPNOTSUPP;
88
89 switch (f->command) {
90 case TC_BLOCK_BIND:
91 return tcf_block_cb_register(f->block, nsim_setup_tc_block_cb,
92 ns, ns, f->extack);
93 case TC_BLOCK_UNBIND:
94 tcf_block_cb_unregister(f->block, nsim_setup_tc_block_cb, ns);
95 return 0;
96 default:
97 return -EOPNOTSUPP;
98 }
99}
100
101static int nsim_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
102{
103 struct netdevsim *ns = netdev_priv(dev);
104 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
105
106 /* Only refuse multicast addresses, zero address can mean unset/any. */
107 if (vf >= nsim_bus_dev->num_vfs || is_multicast_ether_addr(mac))
108 return -EINVAL;
109 memcpy(nsim_bus_dev->vfconfigs[vf].vf_mac, mac, ETH_ALEN);
110
111 return 0;
112}
113
114static int nsim_set_vf_vlan(struct net_device *dev, int vf,
115 u16 vlan, u8 qos, __be16 vlan_proto)
116{
117 struct netdevsim *ns = netdev_priv(dev);
118 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
119
120 if (vf >= nsim_bus_dev->num_vfs || vlan > 4095 || qos > 7)
121 return -EINVAL;
122
123 nsim_bus_dev->vfconfigs[vf].vlan = vlan;
124 nsim_bus_dev->vfconfigs[vf].qos = qos;
125 nsim_bus_dev->vfconfigs[vf].vlan_proto = vlan_proto;
126
127 return 0;
128}
129
130static int nsim_set_vf_rate(struct net_device *dev, int vf, int min, int max)
131{
132 struct netdevsim *ns = netdev_priv(dev);
133 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
134
135 if (vf >= nsim_bus_dev->num_vfs)
136 return -EINVAL;
137
138 nsim_bus_dev->vfconfigs[vf].min_tx_rate = min;
139 nsim_bus_dev->vfconfigs[vf].max_tx_rate = max;
140
141 return 0;
142}
143
144static int nsim_set_vf_spoofchk(struct net_device *dev, int vf, bool val)
145{
146 struct netdevsim *ns = netdev_priv(dev);
147 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
148
149 if (vf >= nsim_bus_dev->num_vfs)
150 return -EINVAL;
151 nsim_bus_dev->vfconfigs[vf].spoofchk_enabled = val;
152
153 return 0;
154}
155
156static int nsim_set_vf_rss_query_en(struct net_device *dev, int vf, bool val)
157{
158 struct netdevsim *ns = netdev_priv(dev);
159 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
160
161 if (vf >= nsim_bus_dev->num_vfs)
162 return -EINVAL;
163 nsim_bus_dev->vfconfigs[vf].rss_query_enabled = val;
164
165 return 0;
166}
167
168static int nsim_set_vf_trust(struct net_device *dev, int vf, bool val)
169{
170 struct netdevsim *ns = netdev_priv(dev);
171 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
172
173 if (vf >= nsim_bus_dev->num_vfs)
174 return -EINVAL;
175 nsim_bus_dev->vfconfigs[vf].trusted = val;
176
177 return 0;
178}
179
180static int
181nsim_get_vf_config(struct net_device *dev, int vf, struct ifla_vf_info *ivi)
182{
183 struct netdevsim *ns = netdev_priv(dev);
184 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
185
186 if (vf >= nsim_bus_dev->num_vfs)
187 return -EINVAL;
188
189 ivi->vf = vf;
190 ivi->linkstate = nsim_bus_dev->vfconfigs[vf].link_state;
191 ivi->min_tx_rate = nsim_bus_dev->vfconfigs[vf].min_tx_rate;
192 ivi->max_tx_rate = nsim_bus_dev->vfconfigs[vf].max_tx_rate;
193 ivi->vlan = nsim_bus_dev->vfconfigs[vf].vlan;
194 ivi->vlan_proto = nsim_bus_dev->vfconfigs[vf].vlan_proto;
195 ivi->qos = nsim_bus_dev->vfconfigs[vf].qos;
196 memcpy(&ivi->mac, nsim_bus_dev->vfconfigs[vf].vf_mac, ETH_ALEN);
197 ivi->spoofchk = nsim_bus_dev->vfconfigs[vf].spoofchk_enabled;
198 ivi->trusted = nsim_bus_dev->vfconfigs[vf].trusted;
199 ivi->rss_query_en = nsim_bus_dev->vfconfigs[vf].rss_query_enabled;
200
201 return 0;
202}
203
204static int nsim_set_vf_link_state(struct net_device *dev, int vf, int state)
205{
206 struct netdevsim *ns = netdev_priv(dev);
207 struct nsim_bus_dev *nsim_bus_dev = ns->nsim_bus_dev;
208
209 if (vf >= nsim_bus_dev->num_vfs)
210 return -EINVAL;
211
212 switch (state) {
213 case IFLA_VF_LINK_STATE_AUTO:
214 case IFLA_VF_LINK_STATE_ENABLE:
215 case IFLA_VF_LINK_STATE_DISABLE:
216 break;
217 default:
218 return -EINVAL;
219 }
220
221 nsim_bus_dev->vfconfigs[vf].link_state = state;
222
223 return 0;
224}
225
226static int
227nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
228{
229 switch (type) {
230 case TC_SETUP_BLOCK:
231 return nsim_setup_tc_block(dev, type_data);
232 default:
233 return -EOPNOTSUPP;
234 }
235}
236
237static int
238nsim_set_features(struct net_device *dev, netdev_features_t features)
239{
240 struct netdevsim *ns = netdev_priv(dev);
241
242 if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC))
243 return nsim_bpf_disable_tc(ns);
244
245 return 0;
246}
247
248static struct devlink_port *nsim_get_devlink_port(struct net_device *dev)
249{
250 struct netdevsim *ns = netdev_priv(dev);
251
252 return &ns->nsim_dev_port->devlink_port;
253}
254
255static const struct net_device_ops nsim_netdev_ops = {
256 .ndo_start_xmit = nsim_start_xmit,
257 .ndo_set_rx_mode = nsim_set_rx_mode,
258 .ndo_set_mac_address = eth_mac_addr,
259 .ndo_validate_addr = eth_validate_addr,
260 .ndo_change_mtu = nsim_change_mtu,
261 .ndo_get_stats64 = nsim_get_stats64,
262 .ndo_set_vf_mac = nsim_set_vf_mac,
263 .ndo_set_vf_vlan = nsim_set_vf_vlan,
264 .ndo_set_vf_rate = nsim_set_vf_rate,
265 .ndo_set_vf_spoofchk = nsim_set_vf_spoofchk,
266 .ndo_set_vf_trust = nsim_set_vf_trust,
267 .ndo_get_vf_config = nsim_get_vf_config,
268 .ndo_set_vf_link_state = nsim_set_vf_link_state,
269 .ndo_set_vf_rss_query_en = nsim_set_vf_rss_query_en,
270 .ndo_setup_tc = nsim_setup_tc,
271 .ndo_set_features = nsim_set_features,
272 .ndo_bpf = nsim_bpf,
273 .ndo_get_devlink_port = nsim_get_devlink_port,
274};
275
276static void nsim_setup(struct net_device *dev)
277{
278 ether_setup(dev);
279 eth_hw_addr_random(dev);
280
281 dev->tx_queue_len = 0;
282 dev->flags |= IFF_NOARP;
283 dev->flags &= ~IFF_MULTICAST;
284 dev->priv_flags |= IFF_LIVE_ADDR_CHANGE |
285 IFF_NO_QUEUE;
286 dev->features |= NETIF_F_HIGHDMA |
287 NETIF_F_SG |
288 NETIF_F_FRAGLIST |
289 NETIF_F_HW_CSUM |
290 NETIF_F_TSO;
291 dev->hw_features |= NETIF_F_HW_TC;
292 dev->max_mtu = ETH_MAX_MTU;
293}
294
295struct netdevsim *
296nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
297{
298 struct net_device *dev;
299 struct netdevsim *ns;
300 int err;
301
302 dev = alloc_netdev(sizeof(*ns), "eth%d", NET_NAME_UNKNOWN, nsim_setup);
303 if (!dev)
304 return ERR_PTR(-ENOMEM);
305
306 ns = netdev_priv(dev);
307 ns->netdev = dev;
308 ns->nsim_dev = nsim_dev;
309 ns->nsim_dev_port = nsim_dev_port;
310 ns->nsim_bus_dev = nsim_dev->nsim_bus_dev;
311 SET_NETDEV_DEV(dev, &ns->nsim_bus_dev->dev);
312 dev->netdev_ops = &nsim_netdev_ops;
313
314 rtnl_lock();
315 err = nsim_bpf_init(ns);
316 if (err)
317 goto err_free_netdev;
318
319 nsim_ipsec_init(ns);
320
321 err = register_netdevice(dev);
322 if (err)
323 goto err_ipsec_teardown;
324 rtnl_unlock();
325
326 return ns;
327
328err_ipsec_teardown:
329 nsim_ipsec_teardown(ns);
330 nsim_bpf_uninit(ns);
331 rtnl_unlock();
332err_free_netdev:
333 free_netdev(dev);
334 return ERR_PTR(err);
335}
336
337void nsim_destroy(struct netdevsim *ns)
338{
339 struct net_device *dev = ns->netdev;
340
341 rtnl_lock();
342 unregister_netdevice(dev);
343 nsim_ipsec_teardown(ns);
344 nsim_bpf_uninit(ns);
345 rtnl_unlock();
346 free_netdev(dev);
347}
348
349static int nsim_validate(struct nlattr *tb[], struct nlattr *data[],
350 struct netlink_ext_ack *extack)
351{
352 NL_SET_ERR_MSG_MOD(extack, "Please use: echo \"[ID] [PORT_COUNT]\" > /sys/bus/netdevsim/new_device");
353 return -EOPNOTSUPP;
354}
355
356static struct rtnl_link_ops nsim_link_ops __read_mostly = {
357 .kind = DRV_NAME,
358 .validate = nsim_validate,
359};
360
361static int __init nsim_module_init(void)
362{
363 int err;
364
365 err = nsim_dev_init();
366 if (err)
367 return err;
368
369 err = nsim_bus_init();
370 if (err)
371 goto err_dev_exit;
372
373 err = rtnl_link_register(&nsim_link_ops);
374 if (err)
375 goto err_bus_exit;
376
377 return 0;
378
379err_bus_exit:
380 nsim_bus_exit();
381err_dev_exit:
382 nsim_dev_exit();
383 return err;
384}
385
386static void __exit nsim_module_exit(void)
387{
388 rtnl_link_unregister(&nsim_link_ops);
389 nsim_bus_exit();
390 nsim_dev_exit();
391}
392
393module_init(nsim_module_init);
394module_exit(nsim_module_exit);
395MODULE_LICENSE("GPL");
396MODULE_ALIAS_RTNL_LINK(DRV_NAME);