Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
37923ed
Documentation
LICENSES
arch
block
certs
crypto
drivers
accessibility
acpi
amba
android
ata
atm
auxdisplay
base
bcma
block
bluetooth
bus
cdrom
char
clk
clocksource
connector
cpufreq
cpuidle
crypto
dax
dca
devfreq
dio
dma-buf
dma
edac
eisa
extcon
firewire
firmware
fmc
fpga
fsi
gpio
gpu
hid
hsi
hv
hwmon
hwspinlock
hwtracing
i2c
ide
idle
iio
infiniband
input
iommu
ipack
irqchip
isdn
leds
lightnvm
macintosh
mailbox
mcb
md
media
memory
memstick
message
mfd
misc
mmc
mtd
mux
net
appletalk
arcnet
bonding
caif
can
cris
dsa
ethernet
fddi
fjes
hamradio
hippi
hyperv
ieee802154
ipvlan
netdevsim
Makefile
bpf.c
devlink.c
fib.c
netdev.c
netdevsim.h
phy
plip
ppp
slip
team
usb
vmxnet3
wan
wimax
wireless
xen-netback
Kconfig
LICENSE.SRC
Makefile
Space.c
dummy.c
eql.c
geneve.c
gtp.c
ifb.c
loopback.c
macsec.c
macvlan.c
macvtap.c
mdio.c
mii.c
netconsole.c
nlmon.c
ntb_netdev.c
rionet.c
sb1000.c
sungem_phy.c
tap.c
thunderbolt.c
tun.c
veth.c
virtio_net.c
vrf.c
vsockmon.c
vxlan.c
xen-netfront.c
nfc
ntb
nubus
nvdimm
nvme
nvmem
of
opp
oprofile
parisc
parport
pci
pcmcia
perf
phy
pinctrl
platform
pnp
power
powercap
pps
ps3
ptp
pwm
rapidio
ras
regulator
remoteproc
reset
rpmsg
rtc
s390
sbus
scsi
sfi
sh
siox
slimbus
sn
soc
soundwire
spi
spmi
ssb
staging
target
tc
tee
thermal
thunderbolt
tty
uio
usb
uwb
vfio
vhost
video
virt
virtio
visorbus
vlynq
vme
w1
watchdog
xen
zorro
Kconfig
Makefile
firmware
fs
include
init
ipc
kernel
lib
mm
net
samples
scripts
security
sound
tools
usr
virt
.cocciconfig
.get_maintainer.ignore
.gitattributes
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
Breadcrumbs
linux
/
drivers
/
net
/
netdevsim
/
devlink.c
Blame
Blame
Latest commit
David Ahern
and
David S. Miller
netdevsim: Add simple FIB resource controller via devlink
Mar 29, 2018
37923ed
·
Mar 29, 2018
History
History
294 lines (242 loc) · 6.95 KB
Breadcrumbs
linux
/
drivers
/
net
/
netdevsim
/
devlink.c
Top
File metadata and controls
Code
Blame
294 lines (242 loc) · 6.95 KB
Raw
/* * Copyright (c) 2018 Cumulus Networks. All rights reserved. * Copyright (c) 2018 David Ahern <dsa@cumulusnetworks.com> * * This software is licensed under the GNU General License Version 2, * June 1991 as shown in the file COPYING in the top-level directory of this * source tree. * * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. */ #include <linux/device.h> #include <net/devlink.h> #include <net/netns/generic.h> #include "netdevsim.h" static unsigned int nsim_devlink_id; /* place holder until devlink and namespaces is sorted out */ static struct net *nsim_devlink_net(struct devlink *devlink) { return &init_net; } /* IPv4 */ static u64 nsim_ipv4_fib_resource_occ_get(struct devlink *devlink) { struct net *net = nsim_devlink_net(devlink); return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, false); } static struct devlink_resource_ops nsim_ipv4_fib_res_ops = { .occ_get = nsim_ipv4_fib_resource_occ_get, }; static u64 nsim_ipv4_fib_rules_res_occ_get(struct devlink *devlink) { struct net *net = nsim_devlink_net(devlink); return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, false); } static struct devlink_resource_ops nsim_ipv4_fib_rules_res_ops = { .occ_get = nsim_ipv4_fib_rules_res_occ_get, }; /* IPv6 */ static u64 nsim_ipv6_fib_resource_occ_get(struct devlink *devlink) { struct net *net = nsim_devlink_net(devlink); return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, false); } static struct devlink_resource_ops nsim_ipv6_fib_res_ops = { .occ_get = nsim_ipv6_fib_resource_occ_get, }; static u64 nsim_ipv6_fib_rules_res_occ_get(struct devlink *devlink) { struct net *net = nsim_devlink_net(devlink); return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, false); } static struct devlink_resource_ops nsim_ipv6_fib_rules_res_ops = { .occ_get = nsim_ipv6_fib_rules_res_occ_get, }; static int devlink_resources_register(struct devlink *devlink) { struct devlink_resource_size_params params = { .size_max = (u64)-1, .size_granularity = 1, .unit = DEVLINK_RESOURCE_UNIT_ENTRY }; struct net *net = nsim_devlink_net(devlink); int err; u64 n; /* Resources for IPv4 */ err = devlink_resource_register(devlink, "IPv4", (u64)-1, NSIM_RESOURCE_IPV4, DEVLINK_RESOURCE_ID_PARENT_TOP, ¶ms, NULL); if (err) { pr_err("Failed to register IPv4 top resource\n"); goto out; } n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, true); err = devlink_resource_register(devlink, "fib", n, NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4, ¶ms, &nsim_ipv4_fib_res_ops); if (err) { pr_err("Failed to register IPv4 FIB resource\n"); return err; } n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, true); err = devlink_resource_register(devlink, "fib-rules", n, NSIM_RESOURCE_IPV4_FIB_RULES, NSIM_RESOURCE_IPV4, ¶ms, &nsim_ipv4_fib_rules_res_ops); if (err) { pr_err("Failed to register IPv4 FIB rules resource\n"); return err; } /* Resources for IPv6 */ err = devlink_resource_register(devlink, "IPv6", (u64)-1, NSIM_RESOURCE_IPV6, DEVLINK_RESOURCE_ID_PARENT_TOP, ¶ms, NULL); if (err) { pr_err("Failed to register IPv6 top resource\n"); goto out; } n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, true); err = devlink_resource_register(devlink, "fib", n, NSIM_RESOURCE_IPV6_FIB, NSIM_RESOURCE_IPV6, ¶ms, &nsim_ipv6_fib_res_ops); if (err) { pr_err("Failed to register IPv6 FIB resource\n"); return err; } n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, true); err = devlink_resource_register(devlink, "fib-rules", n, NSIM_RESOURCE_IPV6_FIB_RULES, NSIM_RESOURCE_IPV6, ¶ms, &nsim_ipv6_fib_rules_res_ops); if (err) { pr_err("Failed to register IPv6 FIB rules resource\n"); return err; } out: return err; } static int nsim_devlink_reload(struct devlink *devlink) { enum nsim_resource_id res_ids[] = { NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES, NSIM_RESOURCE_IPV6_FIB, NSIM_RESOURCE_IPV6_FIB_RULES }; struct net *net = nsim_devlink_net(devlink); int i; for (i = 0; i < ARRAY_SIZE(res_ids); ++i) { int err; u64 val; err = devlink_resource_size_get(devlink, res_ids[i], &val); if (!err) { err = nsim_fib_set_max(net, res_ids[i], val); if (err) return err; } } return 0; } static void nsim_devlink_net_reset(struct net *net) { enum nsim_resource_id res_ids[] = { NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES, NSIM_RESOURCE_IPV6_FIB, NSIM_RESOURCE_IPV6_FIB_RULES }; int i; for (i = 0; i < ARRAY_SIZE(res_ids); ++i) { if (nsim_fib_set_max(net, res_ids[i], (u64)-1)) { pr_err("Failed to reset limit for resource %u\n", res_ids[i]); } } } static const struct devlink_ops nsim_devlink_ops = { .reload = nsim_devlink_reload, }; /* once devlink / namespace issues are sorted out * this needs to be net in which a devlink instance * is to be created. e.g., dev_net(ns->netdev) */ static struct net *nsim_to_net(struct netdevsim *ns) { return &init_net; } void nsim_devlink_teardown(struct netdevsim *ns) { if (ns->devlink) { struct net *net = nsim_to_net(ns); bool *reg_devlink = net_generic(net, nsim_devlink_id); devlink_unregister(ns->devlink); devlink_free(ns->devlink); ns->devlink = NULL; nsim_devlink_net_reset(net); *reg_devlink = true; } } void nsim_devlink_setup(struct netdevsim *ns) { struct net *net = nsim_to_net(ns); bool *reg_devlink = net_generic(net, nsim_devlink_id); struct devlink *devlink; int err = -ENOMEM; /* only one device per namespace controls devlink */ if (!*reg_devlink) { ns->devlink = NULL; return; } devlink = devlink_alloc(&nsim_devlink_ops, 0); if (!devlink) return; err = devlink_register(devlink, &ns->dev); if (err) goto err_devlink_free; err = devlink_resources_register(devlink); if (err) goto err_dl_unregister; ns->devlink = devlink; *reg_devlink = false; return; err_dl_unregister: devlink_unregister(devlink); err_devlink_free: devlink_free(devlink); } /* Initialize per network namespace state */ static int __net_init nsim_devlink_netns_init(struct net *net) { bool *reg_devlink = net_generic(net, nsim_devlink_id); *reg_devlink = true; return 0; } static struct pernet_operations nsim_devlink_net_ops __net_initdata = { .init = nsim_devlink_netns_init, .id = &nsim_devlink_id, .size = sizeof(bool), }; void nsim_devlink_exit(void) { unregister_pernet_subsys(&nsim_devlink_net_ops); nsim_fib_exit(); } int nsim_devlink_init(void) { int err; err = nsim_fib_init(); if (err) goto err_out; err = register_pernet_subsys(&nsim_devlink_net_ops); if (err) nsim_fib_exit(); err_out: return err; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
You can’t perform that action at this time.