diff options
author | David Ahern <dsahern@gmail.com> | 2017-06-08 13:31:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-06-08 19:27:42 -0400 |
commit | 097d3c9508dc58286344e4a22b300098cf0c1566 (patch) | |
tree | 41113cd0f626f9aa313c269868da2131996b283c | |
parent | 78a5a93c1eeb4e6933d1f62b33e5496d53b46c5a (diff) |
net: vrf: Make add_fib_rules per network namespace flag
Commit 1aa6c4f6b8cd8 ("net: vrf: Add l3mdev rules on first device create")
adds the l3mdev FIB rule the first time a VRF device is created. However,
it only creates the rule once and only in the namespace the first device
is created - which may not be init_net. Fix by using the net_generic
capability to make the add_fib_rules flag per network namespace.
Fixes: 1aa6c4f6b8cd8 ("net: vrf: Add l3mdev rules on first device create")
Reported-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/vrf.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index d38f11d833fe..022c0b5f9844 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c | |||
@@ -36,12 +36,14 @@ | |||
36 | #include <net/addrconf.h> | 36 | #include <net/addrconf.h> |
37 | #include <net/l3mdev.h> | 37 | #include <net/l3mdev.h> |
38 | #include <net/fib_rules.h> | 38 | #include <net/fib_rules.h> |
39 | #include <net/netns/generic.h> | ||
39 | 40 | ||
40 | #define DRV_NAME "vrf" | 41 | #define DRV_NAME "vrf" |
41 | #define DRV_VERSION "1.0" | 42 | #define DRV_VERSION "1.0" |
42 | 43 | ||
43 | #define FIB_RULE_PREF 1000 /* default preference for FIB rules */ | 44 | #define FIB_RULE_PREF 1000 /* default preference for FIB rules */ |
44 | static bool add_fib_rules = true; | 45 | |
46 | static unsigned int vrf_net_id; | ||
45 | 47 | ||
46 | struct net_vrf { | 48 | struct net_vrf { |
47 | struct rtable __rcu *rth; | 49 | struct rtable __rcu *rth; |
@@ -1394,6 +1396,8 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev, | |||
1394 | struct nlattr *tb[], struct nlattr *data[]) | 1396 | struct nlattr *tb[], struct nlattr *data[]) |
1395 | { | 1397 | { |
1396 | struct net_vrf *vrf = netdev_priv(dev); | 1398 | struct net_vrf *vrf = netdev_priv(dev); |
1399 | bool *add_fib_rules; | ||
1400 | struct net *net; | ||
1397 | int err; | 1401 | int err; |
1398 | 1402 | ||
1399 | if (!data || !data[IFLA_VRF_TABLE]) | 1403 | if (!data || !data[IFLA_VRF_TABLE]) |
@@ -1409,13 +1413,15 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev, | |||
1409 | if (err) | 1413 | if (err) |
1410 | goto out; | 1414 | goto out; |
1411 | 1415 | ||
1412 | if (add_fib_rules) { | 1416 | net = dev_net(dev); |
1417 | add_fib_rules = net_generic(net, vrf_net_id); | ||
1418 | if (*add_fib_rules) { | ||
1413 | err = vrf_add_fib_rules(dev); | 1419 | err = vrf_add_fib_rules(dev); |
1414 | if (err) { | 1420 | if (err) { |
1415 | unregister_netdevice(dev); | 1421 | unregister_netdevice(dev); |
1416 | goto out; | 1422 | goto out; |
1417 | } | 1423 | } |
1418 | add_fib_rules = false; | 1424 | *add_fib_rules = false; |
1419 | } | 1425 | } |
1420 | 1426 | ||
1421 | out: | 1427 | out: |
@@ -1498,16 +1504,38 @@ static struct notifier_block vrf_notifier_block __read_mostly = { | |||
1498 | .notifier_call = vrf_device_event, | 1504 | .notifier_call = vrf_device_event, |
1499 | }; | 1505 | }; |
1500 | 1506 | ||
1507 | /* Initialize per network namespace state */ | ||
1508 | static int __net_init vrf_netns_init(struct net *net) | ||
1509 | { | ||
1510 | bool *add_fib_rules = net_generic(net, vrf_net_id); | ||
1511 | |||
1512 | *add_fib_rules = true; | ||
1513 | |||
1514 | return 0; | ||
1515 | } | ||
1516 | |||
1517 | static struct pernet_operations vrf_net_ops __net_initdata = { | ||
1518 | .init = vrf_netns_init, | ||
1519 | .id = &vrf_net_id, | ||
1520 | .size = sizeof(bool), | ||
1521 | }; | ||
1522 | |||
1501 | static int __init vrf_init_module(void) | 1523 | static int __init vrf_init_module(void) |
1502 | { | 1524 | { |
1503 | int rc; | 1525 | int rc; |
1504 | 1526 | ||
1505 | register_netdevice_notifier(&vrf_notifier_block); | 1527 | register_netdevice_notifier(&vrf_notifier_block); |
1506 | 1528 | ||
1507 | rc = rtnl_link_register(&vrf_link_ops); | 1529 | rc = register_pernet_subsys(&vrf_net_ops); |
1508 | if (rc < 0) | 1530 | if (rc < 0) |
1509 | goto error; | 1531 | goto error; |
1510 | 1532 | ||
1533 | rc = rtnl_link_register(&vrf_link_ops); | ||
1534 | if (rc < 0) { | ||
1535 | unregister_pernet_subsys(&vrf_net_ops); | ||
1536 | goto error; | ||
1537 | } | ||
1538 | |||
1511 | return 0; | 1539 | return 0; |
1512 | 1540 | ||
1513 | error: | 1541 | error: |