Re: [PATCH net-next v2 2/2] net: vrf: Add l3mdev rules on first device create
From: Nikolay Aleksandrov <hidden>
Date: 2016-06-03 11:05:48
quoted hunk ↗ jump to hunk
On Jun 3, 2016, at 4:22 AM, David Ahern [off-list ref] wrote: Add l3mdev rule per address family when the first VRF device is created. Remove them when the last is deleted. Signed-off-by: David Ahern <redacted> --- v2 - added EXCL flag and EEXISTS check. Appropriate once the exclude fib rule patch is accepted - changed 3rd arg to vrf_fib_rule from 0/1 to false/true per Dave's comment drivers/net/vrf.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-)diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index d356f5d0f7b0..1d13c95cab97 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c@@ -35,6 +35,7 @@#include <net/route.h> #include <net/addrconf.h> #include <net/l3mdev.h> +#include <net/fib_rules.h> #define RT_FL_TOS(oldflp4) \ ((oldflp4)->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))@@ -42,6 +43,11 @@#define DRV_NAME "vrf" #define DRV_VERSION "1.0" +static atomic_t num_vrfs;
num_vrfs seems to be used only with rtnl held, so it seems you can avoid the atomic ops altogether.
quoted hunk ↗ jump to hunk
+ +static u32 rule_pref = 1000; +module_param(rule_pref, uint, S_IRUGO); + struct net_vrf { struct rtable __rcu *rth; struct rt6_info __rcu *rt6;@@ -729,6 +735,98 @@ static const struct ethtool_ops vrf_ethtool_ops = {.get_drvinfo = vrf_get_drvinfo, };
[snip]
quoted hunk ↗ jump to hunk
static void vrf_setup(struct net_device *dev) { ether_setup(dev);@@ -763,12 +861,17 @@ static int vrf_validate(struct nlattr *tb[], struct nlattr *data[])static void vrf_dellink(struct net_device *dev, struct list_head *head) { unregister_netdevice_queue(dev, head); + + atomic_dec(&num_vrfs); + if (!atomic_read(&num_vrfs))
If you’re sticking with atomics, this looks like atomic_dec_and_test().
+ vrf_del_fib_rules(dev);
}
static int vrf_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
{
struct net_vrf *vrf = netdev_priv(dev);
+ int err;
if (!data || !data[IFLA_VRF_TABLE])
return -EINVAL;Cheers, Nik