diff options
author | Florian Westphal <fw@strlen.de> | 2019-01-11 16:46:15 +0300 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-01-18 17:02:33 +0300 |
commit | 8e2f311a68494a6677c1724bdcb10bada21af37c (patch) | |
tree | fc30f35d66252e9177ad60c83157d6c4ae6c40ca /net/netfilter/xt_physdev.c | |
parent | 827318feb69cb07ed58bb9b9dd6c2eaa81a116ad (diff) | |
download | linux-8e2f311a68494a6677c1724bdcb10bada21af37c.tar.xz |
netfilter: physdev: relax br_netfilter dependency
Following command:
iptables -D FORWARD -m physdev ...
causes connectivity loss in some setups.
Reason is that iptables userspace will probe kernel for the module revision
of the physdev patch, and physdev has an artificial dependency on
br_netfilter (xt_physdev use makes no sense unless a br_netfilter module
is loaded).
This causes the "phydev" module to be loaded, which in turn enables the
"call-iptables" infrastructure.
bridged packets might then get dropped by the iptables ruleset.
The better fix would be to change the "call-iptables" defaults to 0 and
enforce explicit setting to 1, but that breaks backwards compatibility.
This does the next best thing: add a request_module call to checkentry.
This was a stray '-D ... -m physdev' won't activate br_netfilter
anymore.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/xt_physdev.c')
-rw-r--r-- | net/netfilter/xt_physdev.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c index 4034d70bff39..b2e39cb6a590 100644 --- a/net/netfilter/xt_physdev.c +++ b/net/netfilter/xt_physdev.c @@ -96,8 +96,7 @@ match_outdev: static int physdev_mt_check(const struct xt_mtchk_param *par) { const struct xt_physdev_info *info = par->matchinfo; - - br_netfilter_enable(); + static bool brnf_probed __read_mostly; if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || info->bitmask & ~XT_PHYSDEV_OP_MASK) @@ -111,6 +110,12 @@ static int physdev_mt_check(const struct xt_mtchk_param *par) if (par->hook_mask & (1 << NF_INET_LOCAL_OUT)) return -EINVAL; } + + if (!brnf_probed) { + brnf_probed = true; + request_module("br_netfilter"); + } + return 0; } |