Commit af9573be authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso Committed by David S. Miller

netfilter: nf_conntrack_bridge: register inet conntrack for bridge

This patch enables IPv4 and IPv6 conntrack from the bridge to deal with
local traffic. Hence, packets that are passed up to the local input path
are confirmed later on from the {ipv4,ipv6}_confirm() hooks.

For packets leaving the IP stack (ie. output path), fragmentation occurs
after the inet postrouting hook. Therefore, the bridge local out and
postrouting bridge hooks see fragments with conntrack objects, which is
inconsistent. In this case, we could defragment again from the bridge
output hook, but this is expensive. The recommended filtering spot for
outgoing locally generated traffic leaving through the bridge interface
is to use the classic IPv4/IPv6 output hook, which comes earlier.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 764dd163
...@@ -560,38 +560,64 @@ static void nf_ct_netns_do_put(struct net *net, u8 nfproto) ...@@ -560,38 +560,64 @@ static void nf_ct_netns_do_put(struct net *net, u8 nfproto)
mutex_unlock(&nf_ct_proto_mutex); mutex_unlock(&nf_ct_proto_mutex);
} }
int nf_ct_netns_get(struct net *net, u8 nfproto) static int nf_ct_netns_inet_get(struct net *net)
{ {
int err; int err;
if (nfproto == NFPROTO_INET) { err = nf_ct_netns_do_get(net, NFPROTO_IPV4);
err = nf_ct_netns_do_get(net, NFPROTO_IPV4); if (err < 0)
if (err < 0) goto err1;
goto err1; err = nf_ct_netns_do_get(net, NFPROTO_IPV6);
err = nf_ct_netns_do_get(net, NFPROTO_IPV6); if (err < 0)
if (err < 0) goto err2;
goto err2;
} else {
err = nf_ct_netns_do_get(net, nfproto);
if (err < 0)
goto err1;
}
return 0;
return err;
err2: err2:
nf_ct_netns_put(net, NFPROTO_IPV4); nf_ct_netns_put(net, NFPROTO_IPV4);
err1: err1:
return err; return err;
} }
int nf_ct_netns_get(struct net *net, u8 nfproto)
{
int err;
switch (nfproto) {
case NFPROTO_INET:
err = nf_ct_netns_inet_get(net);
break;
case NFPROTO_BRIDGE:
err = nf_ct_netns_do_get(net, NFPROTO_BRIDGE);
if (err < 0)
return err;
err = nf_ct_netns_inet_get(net);
if (err < 0) {
nf_ct_netns_put(net, NFPROTO_BRIDGE);
return err;
}
break;
default:
err = nf_ct_netns_do_get(net, nfproto);
break;
}
return err;
}
EXPORT_SYMBOL_GPL(nf_ct_netns_get); EXPORT_SYMBOL_GPL(nf_ct_netns_get);
void nf_ct_netns_put(struct net *net, uint8_t nfproto) void nf_ct_netns_put(struct net *net, uint8_t nfproto)
{ {
if (nfproto == NFPROTO_INET) { switch (nfproto) {
case NFPROTO_BRIDGE:
nf_ct_netns_do_put(net, NFPROTO_BRIDGE);
/* fall through */
case NFPROTO_INET:
nf_ct_netns_do_put(net, NFPROTO_IPV4); nf_ct_netns_do_put(net, NFPROTO_IPV4);
nf_ct_netns_do_put(net, NFPROTO_IPV6); nf_ct_netns_do_put(net, NFPROTO_IPV6);
} else { break;
default:
nf_ct_netns_do_put(net, nfproto); nf_ct_netns_do_put(net, nfproto);
break;
} }
} }
EXPORT_SYMBOL_GPL(nf_ct_netns_put); EXPORT_SYMBOL_GPL(nf_ct_netns_put);
......
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