All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrea Mayer <andrea.mayer@uniroma2.it>
To: David Ahern <dsahern@kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	Shrijeet Mukherjee <shrijeet@gmail.com>,
	Jakub Kicinski <kuba@kernel.org>, Shuah Khan <shuah@kernel.org>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-kselftest@vger.kernel.org
Cc: Donald Sharp <sharpd@cumulusnetworks.com>,
	Roopa Prabhu <roopa@cumulusnetworks.com>,
	Dinesh Dutt <didutt@gmail.com>,
	Stefano Salsano <stefano.salsano@uniroma2.it>,
	Paolo Lungaroni <paolo.lungaroni@cnit.it>,
	Ahmed Abdelsalam <ahabdels@gmail.com>,
	Andrea Mayer <andrea.mayer@uniroma2.it>
Subject: [RFC,net-next, 3/5] vrf: add sysctl parameter for strict mode
Date: Fri, 12 Jun 2020 18:49:35 +0200	[thread overview]
Message-ID: <20200612164937.5468-4-andrea.mayer@uniroma2.it> (raw)
In-Reply-To: <20200612164937.5468-1-andrea.mayer@uniroma2.it>

Add net.vrf.strict_mode sysctl parameter.

When net.vrf.strict_mode=0 (default) it is possible to associate multiple
VRF devices to the same table. Conversely, when net.vrf.strict_mode=1 a
table can be associated to a single VRF device.

When switching from net.vrf.strict_mode=0 to net.vrf.strict_mode=1, a check
is performed to verify that all tables have at most one VRF associated,
otherwise the switch is not allowed.

The net.vrf.strict_mode parameter is per network namespace.

Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it>
---
 drivers/net/vrf.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index f772aac6a04c..bac118b615bc 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -102,6 +102,7 @@ struct netns_vrf {
 	bool add_fib_rules;
 
 	struct vrf_map vmap;
+	struct ctl_table_header	*ctl_hdr;
 };
 
 struct net_vrf {
@@ -245,6 +246,52 @@ static void vrf_map_unlock(struct vrf_map *vmap) __releases(&vmap->vmap_lock)
 	spin_unlock(&vmap->vmap_lock);
 }
 
+static bool vrf_strict_mode(struct vrf_map *vmap)
+{
+	bool strict_mode;
+
+	vrf_map_lock(vmap);
+	strict_mode = vmap->strict_mode;
+	vrf_map_unlock(vmap);
+
+	return strict_mode;
+}
+
+static int vrf_strict_mode_change(struct vrf_map *vmap, bool new_mode)
+{
+	bool *cur_mode;
+	int res = 0;
+
+	vrf_map_lock(vmap);
+
+	cur_mode = &vmap->strict_mode;
+	if (*cur_mode == new_mode)
+		goto unlock;
+
+	if (*cur_mode) {
+		/* disable strict mode */
+		*cur_mode = false;
+	} else {
+		if (vmap->shared_tables) {
+			/* we cannot allow strict_mode because there are some
+			 * vrfs that share one or more tables.
+			 */
+			res = -EBUSY;
+			goto unlock;
+		}
+
+		/* no tables are shared among vrfs, so we can go back
+		 * to 1:1 association between a vrf with its table.
+		 */
+		*cur_mode = true;
+	}
+
+unlock:
+	vrf_map_unlock(vmap);
+
+	return res;
+}
+
 /* called with rtnl lock held */
 static int
 vrf_map_register_dev(struct net_device *dev, struct netlink_ext_ack *extack)
@@ -1701,19 +1748,91 @@ static int vrf_map_init(struct vrf_map *vmap)
 	return 0;
 }
 
+static int vrf_shared_table_handler(struct ctl_table *table, int write,
+				    void __user *buffer, size_t *lenp,
+				    loff_t *ppos)
+{
+	struct net *net = (struct net *)table->extra1;
+	struct vrf_map *vmap = netns_vrf_map(net);
+	int proc_strict_mode = 0;
+	struct ctl_table tmp = {
+		.procname	= table->procname,
+		.data		= &proc_strict_mode,
+		.maxlen		= sizeof(int),
+		.mode		= table->mode,
+		.extra1		= SYSCTL_ZERO,
+		.extra2		= SYSCTL_ONE,
+	};
+	int ret;
+
+	if (!write)
+		proc_strict_mode = vrf_strict_mode(vmap);
+
+	ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
+
+	if (write && ret == 0)
+		ret = vrf_strict_mode_change(vmap, (bool)proc_strict_mode);
+
+	return ret;
+}
+
+static const struct ctl_table vrf_table[] = {
+	{
+		.procname	= "strict_mode",
+		.data		= NULL,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= vrf_shared_table_handler,
+		/* set by the vrf_netns_init */
+		.extra1		= NULL,
+	},
+	{ },
+};
+
 /* Initialize per network namespace state */
 static int __net_init vrf_netns_init(struct net *net)
 {
 	struct netns_vrf *nn_vrf = net_generic(net, vrf_net_id);
+	struct ctl_table *table;
+	int res;
 
 	nn_vrf->add_fib_rules = true;
 	vrf_map_init(&nn_vrf->vmap);
 
+	table = kmemdup(vrf_table, sizeof(vrf_table), GFP_KERNEL);
+	if (!table)
+		return -ENOMEM;
+
+	/* init the extra1 parameter with the reference to current netns */
+	table[0].extra1 = net;
+
+	nn_vrf->ctl_hdr = register_net_sysctl(net, "net/vrf", table);
+	if (!nn_vrf->ctl_hdr) {
+		res = -ENOMEM;
+		goto free_table;
+	}
+
 	return 0;
+
+free_table:
+	kfree(table);
+
+	return res;
+}
+
+static void __net_exit vrf_netns_exit(struct net *net)
+{
+	struct netns_vrf *nn_vrf = net_generic(net, vrf_net_id);
+	struct ctl_table *table;
+
+	table = nn_vrf->ctl_hdr->ctl_table_arg;
+	unregister_net_sysctl_table(nn_vrf->ctl_hdr);
+	kfree(table);
 }
 
 static struct pernet_operations vrf_net_ops __net_initdata = {
 	.init = vrf_netns_init,
+	.exit = vrf_netns_exit,
 	.id   = &vrf_net_id,
 	.size = sizeof(struct netns_vrf),
 };
-- 
2.20.1


  parent reply	other threads:[~2020-06-12 17:03 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-12 16:49 [RFC,net-next, 0/5] Strict mode for VRF Andrea Mayer
2020-06-12 16:49 ` [RFC,net-next, 1/5] l3mdev: add infrastructure for table to VRF mapping Andrea Mayer
2020-06-12 17:51   ` Jakub Kicinski
2020-06-13 22:35     ` Andrea Mayer
2020-06-12 20:59   ` [RFC PATCH] l3mdev: l3mdev_lock can be static kernel test robot
2020-06-14  0:37   ` [RFC,net-next, 1/5] l3mdev: add infrastructure for table to VRF mapping David Ahern
2020-06-14 21:56     ` Andrea Mayer
2020-06-12 16:49 ` [RFC,net-next, 2/5] vrf: track associations between VRF devices and tables Andrea Mayer
2020-06-13 19:28   ` Stephen Hemminger
2020-06-13 22:53     ` Andrea Mayer
2020-06-14  0:34       ` David Ahern
2020-06-14 21:23         ` Andrea Mayer
2020-06-12 16:49 ` Andrea Mayer [this message]
2020-06-12 17:52   ` [RFC,net-next, 3/5] vrf: add sysctl parameter for strict mode Jakub Kicinski
2020-06-13 22:40     ` Andrea Mayer
2020-06-12 16:49 ` [RFC,net-next, 4/5] vrf: add l3mdev registration for table to VRF device lookup Andrea Mayer
2020-06-12 16:49 ` [RFC,net-next, 5/5] selftests: add selftest for the VRF strict mode Andrea Mayer
2020-06-12 17:05 ` [RFC,net-next, 0/5] Strict mode for VRF Dinesh G Dutt
2020-06-13 22:29   ` Andrea Mayer
     [not found]     ` <3099cf72-d54c-494c-b11a-0131138f6d41@Spark>
2020-06-14  0:33       ` David Ahern

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200612164937.5468-4-andrea.mayer@uniroma2.it \
    --to=andrea.mayer@uniroma2.it \
    --cc=ahabdels@gmail.com \
    --cc=davem@davemloft.net \
    --cc=didutt@gmail.com \
    --cc=dsahern@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=paolo.lungaroni@cnit.it \
    --cc=roopa@cumulusnetworks.com \
    --cc=sharpd@cumulusnetworks.com \
    --cc=shrijeet@gmail.com \
    --cc=shuah@kernel.org \
    --cc=stefano.salsano@uniroma2.it \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.