Skip to content

Commit 1b6687e

Browse files
dsaherndavem330
authored andcommitted
vrf: Handle CONFIG_SYSCTL not set
Randy reported compile failure when CONFIG_SYSCTL is not set/enabled: ERROR: modpost: "sysctl_vals" [drivers/net/vrf.ko] undefined! Fix by splitting out the sysctl init and cleanup into helpers that can be set to do nothing when CONFIG_SYSCTL is disabled. In addition, move vrf_strict_mode and vrf_strict_mode_change to above vrf_shared_table_handler (code move only) and wrap all of it in the ifdef CONFIG_SYSCTL. Update the strict mode tests to check for the existence of the /proc/sys entry. Fixes: 33306f1 ("vrf: add sysctl parameter for strict mode") Cc: Andrea Mayer <andrea.mayer@uniroma2.it> Reported-by: Randy Dunlap <rdunlap@infradead.org> Signed-off-by: David Ahern <dsahern@kernel.org> Acked-by: Randy Dunlap <rdunlap@infradead.org> # build-tested Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 5df5661 commit 1b6687e

File tree

2 files changed

+83
-61
lines changed

2 files changed

+83
-61
lines changed

drivers/net/vrf.c

Lines changed: 77 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -260,52 +260,6 @@ static void vrf_map_unlock(struct vrf_map *vmap) __releases(&vmap->vmap_lock)
260260
spin_unlock(&vmap->vmap_lock);
261261
}
262262

263-
static bool vrf_strict_mode(struct vrf_map *vmap)
264-
{
265-
bool strict_mode;
266-
267-
vrf_map_lock(vmap);
268-
strict_mode = vmap->strict_mode;
269-
vrf_map_unlock(vmap);
270-
271-
return strict_mode;
272-
}
273-
274-
static int vrf_strict_mode_change(struct vrf_map *vmap, bool new_mode)
275-
{
276-
bool *cur_mode;
277-
int res = 0;
278-
279-
vrf_map_lock(vmap);
280-
281-
cur_mode = &vmap->strict_mode;
282-
if (*cur_mode == new_mode)
283-
goto unlock;
284-
285-
if (*cur_mode) {
286-
/* disable strict mode */
287-
*cur_mode = false;
288-
} else {
289-
if (vmap->shared_tables) {
290-
/* we cannot allow strict_mode because there are some
291-
* vrfs that share one or more tables.
292-
*/
293-
res = -EBUSY;
294-
goto unlock;
295-
}
296-
297-
/* no tables are shared among vrfs, so we can go back
298-
* to 1:1 association between a vrf with its table.
299-
*/
300-
*cur_mode = true;
301-
}
302-
303-
unlock:
304-
vrf_map_unlock(vmap);
305-
306-
return res;
307-
}
308-
309263
/* called with rtnl lock held */
310264
static int
311265
vrf_map_register_dev(struct net_device *dev, struct netlink_ext_ack *extack)
@@ -1790,6 +1744,53 @@ static int vrf_map_init(struct vrf_map *vmap)
17901744
return 0;
17911745
}
17921746

1747+
#ifdef CONFIG_SYSCTL
1748+
static bool vrf_strict_mode(struct vrf_map *vmap)
1749+
{
1750+
bool strict_mode;
1751+
1752+
vrf_map_lock(vmap);
1753+
strict_mode = vmap->strict_mode;
1754+
vrf_map_unlock(vmap);
1755+
1756+
return strict_mode;
1757+
}
1758+
1759+
static int vrf_strict_mode_change(struct vrf_map *vmap, bool new_mode)
1760+
{
1761+
bool *cur_mode;
1762+
int res = 0;
1763+
1764+
vrf_map_lock(vmap);
1765+
1766+
cur_mode = &vmap->strict_mode;
1767+
if (*cur_mode == new_mode)
1768+
goto unlock;
1769+
1770+
if (*cur_mode) {
1771+
/* disable strict mode */
1772+
*cur_mode = false;
1773+
} else {
1774+
if (vmap->shared_tables) {
1775+
/* we cannot allow strict_mode because there are some
1776+
* vrfs that share one or more tables.
1777+
*/
1778+
res = -EBUSY;
1779+
goto unlock;
1780+
}
1781+
1782+
/* no tables are shared among vrfs, so we can go back
1783+
* to 1:1 association between a vrf with its table.
1784+
*/
1785+
*cur_mode = true;
1786+
}
1787+
1788+
unlock:
1789+
vrf_map_unlock(vmap);
1790+
1791+
return res;
1792+
}
1793+
17931794
static int vrf_shared_table_handler(struct ctl_table *table, int write,
17941795
void *buffer, size_t *lenp, loff_t *ppos)
17951796
{
@@ -1830,15 +1831,9 @@ static const struct ctl_table vrf_table[] = {
18301831
{ },
18311832
};
18321833

1833-
/* Initialize per network namespace state */
1834-
static int __net_init vrf_netns_init(struct net *net)
1834+
static int vrf_netns_init_sysctl(struct net *net, struct netns_vrf *nn_vrf)
18351835
{
1836-
struct netns_vrf *nn_vrf = net_generic(net, vrf_net_id);
18371836
struct ctl_table *table;
1838-
int res;
1839-
1840-
nn_vrf->add_fib_rules = true;
1841-
vrf_map_init(&nn_vrf->vmap);
18421837

18431838
table = kmemdup(vrf_table, sizeof(vrf_table), GFP_KERNEL);
18441839
if (!table)
@@ -1849,19 +1844,14 @@ static int __net_init vrf_netns_init(struct net *net)
18491844

18501845
nn_vrf->ctl_hdr = register_net_sysctl(net, "net/vrf", table);
18511846
if (!nn_vrf->ctl_hdr) {
1852-
res = -ENOMEM;
1853-
goto free_table;
1847+
kfree(table);
1848+
return -ENOMEM;
18541849
}
18551850

18561851
return 0;
1857-
1858-
free_table:
1859-
kfree(table);
1860-
1861-
return res;
18621852
}
18631853

1864-
static void __net_exit vrf_netns_exit(struct net *net)
1854+
static void vrf_netns_exit_sysctl(struct net *net)
18651855
{
18661856
struct netns_vrf *nn_vrf = net_generic(net, vrf_net_id);
18671857
struct ctl_table *table;
@@ -1870,6 +1860,32 @@ static void __net_exit vrf_netns_exit(struct net *net)
18701860
unregister_net_sysctl_table(nn_vrf->ctl_hdr);
18711861
kfree(table);
18721862
}
1863+
#else
1864+
static int vrf_netns_init_sysctl(struct net *net, struct netns_vrf *nn_vrf)
1865+
{
1866+
return 0;
1867+
}
1868+
1869+
static void vrf_netns_exit_sysctl(struct net *net)
1870+
{
1871+
}
1872+
#endif
1873+
1874+
/* Initialize per network namespace state */
1875+
static int __net_init vrf_netns_init(struct net *net)
1876+
{
1877+
struct netns_vrf *nn_vrf = net_generic(net, vrf_net_id);
1878+
1879+
nn_vrf->add_fib_rules = true;
1880+
vrf_map_init(&nn_vrf->vmap);
1881+
1882+
return vrf_netns_init_sysctl(net, nn_vrf);
1883+
}
1884+
1885+
static void __net_exit vrf_netns_exit(struct net *net)
1886+
{
1887+
vrf_netns_exit_sysctl(net);
1888+
}
18731889

18741890
static struct pernet_operations vrf_net_ops __net_initdata = {
18751891
.init = vrf_netns_init,

tools/testing/selftests/net/vrf_strict_mode_test.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,12 @@ if [ ! -x "$(command -v ip)" ]; then
379379
exit 0
380380
fi
381381

382+
modprobe vrf &>/dev/null
383+
if [ ! -e /proc/sys/net/vrf/strict_mode ]; then
384+
echo "SKIP: vrf sysctl does not exist"
385+
exit 0
386+
fi
387+
382388
cleanup &> /dev/null
383389

384390
setup

0 commit comments

Comments
 (0)