From 37923ed6b8cea94d7d76038e2f72c57a0b45daab Mon Sep 17 00:00:00 2001 From: David Ahern Date: Tue, 27 Mar 2018 18:22:00 -0700 Subject: netdevsim: Add simple FIB resource controller via devlink Add devlink support to netdevsim and use it to implement a simple, profile based resource controller. Only one controller is needed per namespace, so the first netdevsim netdevice in a namespace registers with devlink. If that device is deleted, the resource settings are deleted. The resource controller allows a user to limit the number of IPv4 and IPv6 FIB entries and FIB rules. The resource paths are: /IPv4 /IPv4/fib /IPv4/fib-rules /IPv6 /IPv6/fib /IPv6/fib-rules The IPv4 and IPv6 top level resources are unlimited in size and can not be changed. From there, the number of FIB entries and FIB rule entries are unlimited by default. A user can specify a limit for the fib and fib-rules resources: $ devlink resource set netdevsim/netdevsim0 path /IPv4/fib size 96 $ devlink resource set netdevsim/netdevsim0 path /IPv4/fib-rules size 16 $ devlink resource set netdevsim/netdevsim0 path /IPv6/fib size 64 $ devlink resource set netdevsim/netdevsim0 path /IPv6/fib-rules size 16 $ devlink dev reload netdevsim/netdevsim0 such that the number of rules or routes is limited (96 ipv4 routes in the example above): $ for n in $(seq 1 32); do ip ro add 10.99.$n.0/24 dev eth1; done Error: netdevsim: Exceeded number of supported fib entries. $ devlink resource show netdevsim/netdevsim0 netdevsim/netdevsim0: name IPv4 size unlimited unit entry size_min 0 size_max unlimited size_gran 1 dpipe_tables non resources: name fib size 96 occ 96 unit entry size_min 0 size_max unlimited size_gran 1 dpipe_tables ... With this template in place for resource management, it is fairly trivial to extend and shows one way to implement a simple counter based resource controller typical of network profiles. Currently, devlink only supports initial namespace. Code is in place to adapt netdevsim to a per namespace controller once the network namespace issues are resolved. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- drivers/net/netdevsim/netdev.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/net/netdevsim/netdev.c') diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index 3fd567928f3d..8b30ab3ea2c2 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -167,6 +167,8 @@ static int nsim_init(struct net_device *dev) SET_NETDEV_DEV(dev, &ns->dev); + nsim_devlink_setup(ns); + return 0; err_bpf_uninit: @@ -180,6 +182,7 @@ static void nsim_uninit(struct net_device *dev) { struct netdevsim *ns = netdev_priv(dev); + nsim_devlink_teardown(ns); debugfs_remove_recursive(ns->ddir); nsim_bpf_uninit(ns); } @@ -478,12 +481,18 @@ static int __init nsim_module_init(void) if (err) goto err_debugfs_destroy; - err = rtnl_link_register(&nsim_link_ops); + err = nsim_devlink_init(); if (err) goto err_unreg_bus; + err = rtnl_link_register(&nsim_link_ops); + if (err) + goto err_dl_fini; + return 0; +err_dl_fini: + nsim_devlink_exit(); err_unreg_bus: bus_unregister(&nsim_bus); err_debugfs_destroy: @@ -494,6 +503,7 @@ err_debugfs_destroy: static void __exit nsim_module_exit(void) { rtnl_link_unregister(&nsim_link_ops); + nsim_devlink_exit(); bus_unregister(&nsim_bus); debugfs_remove_recursive(nsim_ddir); } -- cgit v1.2.3 From ef817102586cca428d6fe0803cc232a3c929141f Mon Sep 17 00:00:00 2001 From: David Ahern Date: Fri, 30 Mar 2018 09:28:51 -0700 Subject: netdevsim: Change nsim_devlink_setup to return error to caller Change nsim_devlink_setup to return any error back to the caller and update nsim_init to handle it. Requested-by: Jakub Kicinski Signed-off-by: David Ahern Acked-by: Jakub Kicinski Signed-off-by: David S. Miller --- drivers/net/netdevsim/devlink.c | 12 +++++++----- drivers/net/netdevsim/netdev.c | 6 +++++- drivers/net/netdevsim/netdevsim.h | 5 +++-- 3 files changed, 15 insertions(+), 8 deletions(-) (limited to 'drivers/net/netdevsim/netdev.c') diff --git a/drivers/net/netdevsim/devlink.c b/drivers/net/netdevsim/devlink.c index bbdcf064ba10..27ae05c5fdaf 100644 --- a/drivers/net/netdevsim/devlink.c +++ b/drivers/net/netdevsim/devlink.c @@ -218,22 +218,22 @@ void nsim_devlink_teardown(struct netdevsim *ns) } } -void nsim_devlink_setup(struct netdevsim *ns) +int 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; + int err; /* only one device per namespace controls devlink */ if (!*reg_devlink) { ns->devlink = NULL; - return; + return 0; } devlink = devlink_alloc(&nsim_devlink_ops, 0); if (!devlink) - return; + return -ENOMEM; err = devlink_register(devlink, &ns->dev); if (err) @@ -247,12 +247,14 @@ void nsim_devlink_setup(struct netdevsim *ns) *reg_devlink = false; - return; + return 0; err_dl_unregister: devlink_unregister(devlink); err_devlink_free: devlink_free(devlink); + + return err; } /* Initialize per network namespace state */ diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index 8b30ab3ea2c2..ec68f38213d9 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -167,10 +167,14 @@ static int nsim_init(struct net_device *dev) SET_NETDEV_DEV(dev, &ns->dev); - nsim_devlink_setup(ns); + err = nsim_devlink_setup(ns); + if (err) + goto err_unreg_dev; return 0; +err_unreg_dev: + device_unregister(&ns->dev); err_bpf_uninit: nsim_bpf_uninit(ns); err_debugfs_destroy: diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h index afb8cf90c0fd..3a8581af3b85 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -117,7 +117,7 @@ enum nsim_resource_id { NSIM_RESOURCE_IPV6_FIB_RULES, }; -void nsim_devlink_setup(struct netdevsim *ns); +int nsim_devlink_setup(struct netdevsim *ns); void nsim_devlink_teardown(struct netdevsim *ns); int nsim_devlink_init(void); @@ -128,8 +128,9 @@ void nsim_fib_exit(void); u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max); int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val); #else -static inline void nsim_devlink_setup(struct netdevsim *ns) +static inline int nsim_devlink_setup(struct netdevsim *ns) { + return 0; } static inline void nsim_devlink_teardown(struct netdevsim *ns) -- cgit v1.2.3