Commit 2230f5e2 authored by Florian Westphal's avatar Florian Westphal Committed by Greg Kroah-Hartman

netfilter: physdev: relax br_netfilter dependency

[ Upstream commit 8e2f311a ]

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: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 0999f638
...@@ -49,7 +49,6 @@ static inline struct rtable *bridge_parent_rtable(const struct net_device *dev) ...@@ -49,7 +49,6 @@ static inline struct rtable *bridge_parent_rtable(const struct net_device *dev)
} }
struct net_device *setup_pre_routing(struct sk_buff *skb); struct net_device *setup_pre_routing(struct sk_buff *skb);
void br_netfilter_enable(void);
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
int br_validate_ipv6(struct net *net, struct sk_buff *skb); int br_validate_ipv6(struct net *net, struct sk_buff *skb);
......
...@@ -881,11 +881,6 @@ static const struct nf_br_ops br_ops = { ...@@ -881,11 +881,6 @@ static const struct nf_br_ops br_ops = {
.br_dev_xmit_hook = br_nf_dev_xmit, .br_dev_xmit_hook = br_nf_dev_xmit,
}; };
void br_netfilter_enable(void)
{
}
EXPORT_SYMBOL_GPL(br_netfilter_enable);
/* For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because /* For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because
* br_dev_queue_push_xmit is called afterwards */ * br_dev_queue_push_xmit is called afterwards */
static const struct nf_hook_ops br_nf_ops[] = { static const struct nf_hook_ops br_nf_ops[] = {
......
...@@ -96,8 +96,7 @@ physdev_mt(const struct sk_buff *skb, struct xt_action_param *par) ...@@ -96,8 +96,7 @@ physdev_mt(const struct sk_buff *skb, struct xt_action_param *par)
static int physdev_mt_check(const struct xt_mtchk_param *par) static int physdev_mt_check(const struct xt_mtchk_param *par)
{ {
const struct xt_physdev_info *info = par->matchinfo; const struct xt_physdev_info *info = par->matchinfo;
static bool brnf_probed __read_mostly;
br_netfilter_enable();
if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
info->bitmask & ~XT_PHYSDEV_OP_MASK) info->bitmask & ~XT_PHYSDEV_OP_MASK)
...@@ -113,6 +112,12 @@ static int physdev_mt_check(const struct xt_mtchk_param *par) ...@@ -113,6 +112,12 @@ static int physdev_mt_check(const struct xt_mtchk_param *par)
if (par->hook_mask & (1 << NF_INET_LOCAL_OUT)) if (par->hook_mask & (1 << NF_INET_LOCAL_OUT))
return -EINVAL; return -EINVAL;
} }
if (!brnf_probed) {
brnf_probed = true;
request_module("br_netfilter");
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment