* RFC: bridge netfilter vlan device name resolution
@ 2012-03-26 20:21 Florian Westphal
2012-03-26 20:23 ` [RFC PATCH] netfilter: bridge: change indev name to vlan if vlan tag present Florian Westphal
2012-03-27 17:34 ` RFC: bridge netfilter vlan device name resolution Bart De Schuymer
0 siblings, 2 replies; 8+ messages in thread
From: Florian Westphal @ 2012-03-26 20:21 UTC (permalink / raw)
To: netfilter-devel
When using a bridge with a management vlan on top (e.g. br0.1), you
cannot use iptables to match the input vlan device, because the vlan
device isn't resolved yet, i.e. "-i br0" matches, while "-i br0.1"
does not, unless "net.bridge.bridge-nf-filter-vlan-tagged" (or
"net.bridge.bridge-nf-call-iptables") is turned off.
This happens because bridge netfilter runs before
vlan device lookup, so skb->dev is set to the bridge; not
the vlan device on top of the bridge.
I'd like to use iptables -t nat ... -j REDIRECT only for one particular vlan.
Two possible solutions come to mind:
- #1, add the vlan tag to nf_bridge info for use with physdev match:
"... -m physdev --vlan-id 42 ..."
- #2, change bridge netfilter so that it passes in the vlan instead of
the bridge as input device.
Any other ideas on how to handle this?
RFC patch that implements #2 follows.
Thanks,
Florian
^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC PATCH] netfilter: bridge: change indev name to vlan if vlan tag present
2012-03-26 20:21 RFC: bridge netfilter vlan device name resolution Florian Westphal
@ 2012-03-26 20:23 ` Florian Westphal
2012-03-27 15:37 ` Pablo Neira Ayuso
2012-03-27 17:34 ` RFC: bridge netfilter vlan device name resolution Bart De Schuymer
1 sibling, 1 reply; 8+ messages in thread
From: Florian Westphal @ 2012-03-26 20:23 UTC (permalink / raw)
To: netfilter-devel
If net.bridge.bridge-nf-filter-vlan-tagged is on, bridge
netfilter will remove skbs vlan header, then feeds the packet
to ip(6)tables.
This changes the in/out interface to the vlan interface; if such
an interface has been configured, to allow iptables rules to
determine the original vlan the packet arrived on (e.g.
-i br0.1 will now work if a br0.1 vlan exists on top of br0 bridge
interface).
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/bridge/br_netfilter.c | 31 +++++++++++++++++++++++--------
1 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index dec4f38..087fbd1 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -503,6 +503,19 @@ bridged_dnat:
return 0;
}
+static struct net_device *brnf_find_logical_dev(struct sk_buff *skb, const struct net_device *dev)
+{
+ struct net_device *vlan, *br;
+
+ br = bridge_parent(dev);
+ if (!vlan_tx_tag_present(skb))
+ return br;
+
+ vlan = __vlan_find_dev_deep(br, vlan_tx_tag_get(skb) & VLAN_VID_MASK);
+
+ return vlan ? vlan : br;
+}
+
/* Some common code for IPv4/IPv6 */
static struct net_device *setup_pre_routing(struct sk_buff *skb)
{
@@ -515,7 +528,7 @@ static struct net_device *setup_pre_routing(struct sk_buff *skb)
nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
nf_bridge->physindev = skb->dev;
- skb->dev = bridge_parent(skb->dev);
+ skb->dev = brnf_find_logical_dev(skb, skb->dev);
if (skb->protocol == htons(ETH_P_8021Q))
nf_bridge->mask |= BRNF_8021Q;
else if (skb->protocol == htons(ETH_P_PPP_SES))
@@ -737,7 +750,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
int (*okfn)(struct sk_buff *))
{
struct nf_bridge_info *nf_bridge;
- struct net_device *parent;
+ struct net_device *parent, *indev;
u_int8_t pf;
if (!skb->nf_bridge)
@@ -748,10 +761,6 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
if (!nf_bridge_unshare(skb))
return NF_DROP;
- parent = bridge_parent(out);
- if (!parent)
- return NF_DROP;
-
if (IS_IP(skb) || IS_VLAN_IP(skb) || IS_PPPOE_IP(skb))
pf = PF_INET;
else if (IS_IPV6(skb) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb))
@@ -759,6 +768,10 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
else
return NF_ACCEPT;
+ parent = brnf_find_logical_dev(skb, out);
+ if (!parent)
+ return NF_DROP;
+
nf_bridge_pull_encap_header(skb);
nf_bridge = skb->nf_bridge;
@@ -778,7 +791,9 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
else
skb->protocol = htons(ETH_P_IPV6);
- NF_HOOK(pf, NF_INET_FORWARD, skb, bridge_parent(in), parent,
+ indev = brnf_find_logical_dev(skb, in);
+
+ NF_HOOK(pf, NF_INET_FORWARD, skb, indev, parent,
br_nf_forward_finish);
return NF_STOLEN;
@@ -850,7 +865,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
int (*okfn)(struct sk_buff *))
{
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
- struct net_device *realoutdev = bridge_parent(skb->dev);
+ struct net_device *realoutdev = brnf_find_logical_dev(skb, out);
u_int8_t pf;
if (!nf_bridge || !(nf_bridge->mask & BRNF_BRIDGED))
--
1.7.3.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [RFC PATCH] netfilter: bridge: change indev name to vlan if vlan tag present
2012-03-26 20:23 ` [RFC PATCH] netfilter: bridge: change indev name to vlan if vlan tag present Florian Westphal
@ 2012-03-27 15:37 ` Pablo Neira Ayuso
0 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2012-03-27 15:37 UTC (permalink / raw)
To: Florian Westphal; +Cc: netfilter-devel, Bart De Schuymer
On Mon, Mar 26, 2012 at 10:23:26PM +0200, Florian Westphal wrote:
> If net.bridge.bridge-nf-filter-vlan-tagged is on, bridge
> netfilter will remove skbs vlan header, then feeds the packet
> to ip(6)tables.
>
> This changes the in/out interface to the vlan interface; if such
> an interface has been configured, to allow iptables rules to
> determine the original vlan the packet arrived on (e.g.
> -i br0.1 will now work if a br0.1 vlan exists on top of br0 bridge
> interface).
Bart, can you see any problem with this approach?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFC: bridge netfilter vlan device name resolution
2012-03-26 20:21 RFC: bridge netfilter vlan device name resolution Florian Westphal
2012-03-26 20:23 ` [RFC PATCH] netfilter: bridge: change indev name to vlan if vlan tag present Florian Westphal
@ 2012-03-27 17:34 ` Bart De Schuymer
2012-03-27 20:19 ` Florian Westphal
2012-04-02 9:25 ` Florian Westphal
1 sibling, 2 replies; 8+ messages in thread
From: Bart De Schuymer @ 2012-03-27 17:34 UTC (permalink / raw)
To: Florian Westphal; +Cc: netfilter-devel
Op 26/03/2012 22:21, Florian Westphal schreef:
> When using a bridge with a management vlan on top (e.g. br0.1), you
> cannot use iptables to match the input vlan device, because the vlan
> device isn't resolved yet, i.e. "-i br0" matches, while "-i br0.1"
> does not, unless "net.bridge.bridge-nf-filter-vlan-tagged" (or
> "net.bridge.bridge-nf-call-iptables") is turned off.
>
> This happens because bridge netfilter runs before
> vlan device lookup, so skb->dev is set to the bridge; not
> the vlan device on top of the bridge.
>
> I'd like to use iptables -t nat ... -j REDIRECT only for one particular vlan.
>
> Two possible solutions come to mind:
>
> - #1, add the vlan tag to nf_bridge info for use with physdev match:
> "... -m physdev --vlan-id 42 ..."
> - #2, change bridge netfilter so that it passes in the vlan instead of
> the bridge as input device.
>
> Any other ideas on how to handle this?
I don't like approach #2: it will break existing firewall configurations
and I really don't see a reason why we would change the network device
to a non-bridge device (br0.1 isn't a bridge). Approach #1 can be
achieved without code changes with the nfmark field as shown below.
You can filter on the vlan id in iptables by using the nfmark field
intelligently, see e.g.
http://ebtables.sourceforge.net/examples/basic.html#ex_network_separation
cheers,
Bart
--
Bart De Schuymer
www.artinalgorithms.be
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFC: bridge netfilter vlan device name resolution
2012-03-27 17:34 ` RFC: bridge netfilter vlan device name resolution Bart De Schuymer
@ 2012-03-27 20:19 ` Florian Westphal
2012-04-02 9:25 ` Florian Westphal
1 sibling, 0 replies; 8+ messages in thread
From: Florian Westphal @ 2012-03-27 20:19 UTC (permalink / raw)
To: Bart De Schuymer; +Cc: Florian Westphal, netfilter-devel
Bart De Schuymer <bdschuym@pandora.be> wrote:
> > Two possible solutions come to mind:
> >
> > - #1, add the vlan tag to nf_bridge info for use with physdev match:
> > "... -m physdev --vlan-id 42 ..."
> > - #2, change bridge netfilter so that it passes in the vlan instead of
> > the bridge as input device.
> >
> > Any other ideas on how to handle this?
>
> I don't like approach #2: it will break existing firewall configurations
> and I really don't see a reason why we would change the network device
> to a non-bridge device (br0.1 isn't a bridge). Approach #1 can be
> achieved without code changes with the nfmark field as shown below.
>
> You can filter on the vlan id in iptables by using the nfmark field
> intelligently, see e.g.
> http://ebtables.sourceforge.net/examples/basic.html#ex_network_separation
I see, but this 'do it with nfmark' is really getting out of hand,
because thats what everyone says for everything (be it qos, tproxy/policy
routing, L7/DPI crap, ...). I only need the vlan identification in nat
PREROUTING so perhaps i can re-use some of that machines QoS nfmarks
here and re-set the nfmarks in the mangle table,
thanks for the hint.
Pablo, please toss the patch -- I'll come up with something else in case the
nfmark solution won't work for me.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFC: bridge netfilter vlan device name resolution
2012-03-27 17:34 ` RFC: bridge netfilter vlan device name resolution Bart De Schuymer
2012-03-27 20:19 ` Florian Westphal
@ 2012-04-02 9:25 ` Florian Westphal
2012-04-03 12:18 ` Bart De Schuymer
1 sibling, 1 reply; 8+ messages in thread
From: Florian Westphal @ 2012-04-02 9:25 UTC (permalink / raw)
To: Bart De Schuymer; +Cc: Florian Westphal, netfilter-devel
Bart De Schuymer <bdschuym@pandora.be> wrote:
> Op 26/03/2012 22:21, Florian Westphal schreef:
> > When using a bridge with a management vlan on top (e.g. br0.1), you
> > cannot use iptables to match the input vlan device, because the vlan
> > device isn't resolved yet, i.e. "-i br0" matches, while "-i br0.1"
> > does not, unless "net.bridge.bridge-nf-filter-vlan-tagged" (or
> > "net.bridge.bridge-nf-call-iptables") is turned off.
> >
> > This happens because bridge netfilter runs before
> > vlan device lookup, so skb->dev is set to the bridge; not
> > the vlan device on top of the bridge.
> >
> > I'd like to use iptables -t nat ... -j REDIRECT only for one particular vlan.
> >
> > Two possible solutions come to mind:
> >
> > - #1, add the vlan tag to nf_bridge info for use with physdev match:
> > "... -m physdev --vlan-id 42 ..."
> > - #2, change bridge netfilter so that it passes in the vlan instead of
> > the bridge as input device.
> >
> > Any other ideas on how to handle this?
>
> I don't like approach #2: it will break existing firewall configurations
> and I really don't see a reason why we would change the network device
> to a non-bridge device (br0.1 isn't a bridge). Approach #1 can be
> achieved without code changes with the nfmark field as shown below.
>
> You can filter on the vlan id in iptables by using the nfmark field
> intelligently, see e.g.
> http://ebtables.sourceforge.net/examples/basic.html#ex_network_separation
However, the REDIRECT target won't work with vlans on the bridge,
because skb->dev points to the bridge instead of the vlan, and thus
the REDIRECT target fails to get the ip address.
Would at least the PRE_ROUTING part of my patch be acceptable to make
REDIRECT work?
Thanks,
Florian
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFC: bridge netfilter vlan device name resolution
2012-04-02 9:25 ` Florian Westphal
@ 2012-04-03 12:18 ` Bart De Schuymer
2012-04-03 20:47 ` Florian Westphal
0 siblings, 1 reply; 8+ messages in thread
From: Bart De Schuymer @ 2012-04-03 12:18 UTC (permalink / raw)
To: Florian Westphal; +Cc: netfilter-devel
Op 2/04/2012 11:25, Florian Westphal schreef:
> Bart De Schuymer<bdschuym@pandora.be> wrote:
>> I don't like approach #2: it will break existing firewall
>> configurations and I really don't see a reason why we would change
>> the network device to a non-bridge device (br0.1 isn't a bridge).
>> Approach #1 can be achieved without code changes with the nfmark
>> field as shown below. You can filter on the vlan id in iptables by
>> using the nfmark field intelligently, see e.g.
>> http://ebtables.sourceforge.net/examples/basic.html#ex_network_separation
>
> However, the REDIRECT target won't work with vlans on the bridge,
> because skb->dev points to the bridge instead of the vlan, and thus
> the REDIRECT target fails to get the ip address.
Can't you use the DNAT target instead? If you have multiple vlan devices
on top with multiple IP addresses, you can use the nfmark value to
determine the destination IP address.
> Would at least the PRE_ROUTING part of my patch be acceptable to make
> REDIRECT work?
No, for the same reasons as stated before... What would be acceptable is
an extension that allows to specify which input device to give to
iptables. Perhaps for your use case, another flag in
|/proc/sys/net/bridge/ |that allows turning this feature on (off by
default) would be nice. The behaviour should then be like your original
idea and not restricted to only the PREROUTING case described above. A
name for the flag that comes to mind is |bridge-nf-pass-vlan-input-device.|
Best regards,
Bart
--
Bart De Schuymer
www.artinalgorithms.be
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: RFC: bridge netfilter vlan device name resolution
2012-04-03 12:18 ` Bart De Schuymer
@ 2012-04-03 20:47 ` Florian Westphal
0 siblings, 0 replies; 8+ messages in thread
From: Florian Westphal @ 2012-04-03 20:47 UTC (permalink / raw)
To: Bart De Schuymer; +Cc: Florian Westphal, netfilter-devel
Bart De Schuymer <bdschuym@pandora.be> wrote:
> >> I don't like approach #2: it will break existing firewall
> >> configurations and I really don't see a reason why we would change
> >> the network device to a non-bridge device (br0.1 isn't a bridge).
> >> Approach #1 can be achieved without code changes with the nfmark
> >> field as shown below. You can filter on the vlan id in iptables by
> >> using the nfmark field intelligently, see e.g.
> >> http://ebtables.sourceforge.net/examples/basic.html#ex_network_separation
> >
> > However, the REDIRECT target won't work with vlans on the bridge,
> > because skb->dev points to the bridge instead of the vlan, and thus
> > the REDIRECT target fails to get the ip address.
>
> Can't you use the DNAT target instead? If you have multiple vlan devices
> on top with multiple IP addresses, you can use the nfmark value to
> determine the destination IP address.
Right. But we're low on available nfmarks.
> > Would at least the PRE_ROUTING part of my patch be acceptable to make
> > REDIRECT work?
>
> No, for the same reasons as stated before... What would be acceptable is
> an extension that allows to specify which input device to give to
> iptables. Perhaps for your use case, another flag in
> |/proc/sys/net/bridge/ |that allows turning this feature on (off by
> default) would be nice. The behaviour should then be like your original
> idea and not restricted to only the PREROUTING case described above. A
> name for the flag that comes to mind is |bridge-nf-pass-vlan-input-device.|
Thanks, this seems to be a good solution.
I'll cook up a patch.
Thanks for your help,
Florian
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2012-04-03 20:47 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-26 20:21 RFC: bridge netfilter vlan device name resolution Florian Westphal
2012-03-26 20:23 ` [RFC PATCH] netfilter: bridge: change indev name to vlan if vlan tag present Florian Westphal
2012-03-27 15:37 ` Pablo Neira Ayuso
2012-03-27 17:34 ` RFC: bridge netfilter vlan device name resolution Bart De Schuymer
2012-03-27 20:19 ` Florian Westphal
2012-04-02 9:25 ` Florian Westphal
2012-04-03 12:18 ` Bart De Schuymer
2012-04-03 20:47 ` Florian Westphal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).