* 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).