aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2012-05-08 13:36:44 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2012-05-08 13:36:47 -0400
commit4981682cc19733f3ca43d3abd81dd4adbc9005d5 (patch)
tree6c4583e26b8f12559defc11d0c141011a71e3de1 /net/bridge
parentac3a546ac89fdf3c4b50e40039a5a7f6df4dda72 (diff)
netfilter: bridge: optionally set indev to vlan
if net.bridge.bridge-nf-filter-vlan-tagged sysctl is enabled, bridge netfilter removes the vlan header temporarily and then feeds the packet to ip(6)tables. When the new "bridge-nf-pass-vlan-input-device" sysctl is on (default off), then bridge netfilter will also set the in-interface to the vlan interface; if such an interface exists. This is needed to make iptables REDIRECT target work with "vlan-on-top-of-bridge" setups and to allow use of "iptables -i" to match the vlan device name. Also update Documentation with current brnf default settings. Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Bart De Schuymer <bdschuym@pandora.be> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_netfilter.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 53f083686ae4..dce55d4ee83b 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -54,12 +54,14 @@ static int brnf_call_ip6tables __read_mostly = 1;
54static int brnf_call_arptables __read_mostly = 1; 54static int brnf_call_arptables __read_mostly = 1;
55static int brnf_filter_vlan_tagged __read_mostly = 0; 55static int brnf_filter_vlan_tagged __read_mostly = 0;
56static int brnf_filter_pppoe_tagged __read_mostly = 0; 56static int brnf_filter_pppoe_tagged __read_mostly = 0;
57static int brnf_pass_vlan_indev __read_mostly = 0;
57#else 58#else
58#define brnf_call_iptables 1 59#define brnf_call_iptables 1
59#define brnf_call_ip6tables 1 60#define brnf_call_ip6tables 1
60#define brnf_call_arptables 1 61#define brnf_call_arptables 1
61#define brnf_filter_vlan_tagged 0 62#define brnf_filter_vlan_tagged 0
62#define brnf_filter_pppoe_tagged 0 63#define brnf_filter_pppoe_tagged 0
64#define brnf_pass_vlan_indev 0
63#endif 65#endif
64 66
65#define IS_IP(skb) \ 67#define IS_IP(skb) \
@@ -503,6 +505,19 @@ bridged_dnat:
503 return 0; 505 return 0;
504} 506}
505 507
508static struct net_device *brnf_get_logical_dev(struct sk_buff *skb, const struct net_device *dev)
509{
510 struct net_device *vlan, *br;
511
512 br = bridge_parent(dev);
513 if (brnf_pass_vlan_indev == 0 || !vlan_tx_tag_present(skb))
514 return br;
515
516 vlan = __vlan_find_dev_deep(br, vlan_tx_tag_get(skb) & VLAN_VID_MASK);
517
518 return vlan ? vlan : br;
519}
520
506/* Some common code for IPv4/IPv6 */ 521/* Some common code for IPv4/IPv6 */
507static struct net_device *setup_pre_routing(struct sk_buff *skb) 522static struct net_device *setup_pre_routing(struct sk_buff *skb)
508{ 523{
@@ -515,7 +530,7 @@ static struct net_device *setup_pre_routing(struct sk_buff *skb)
515 530
516 nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING; 531 nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
517 nf_bridge->physindev = skb->dev; 532 nf_bridge->physindev = skb->dev;
518 skb->dev = bridge_parent(skb->dev); 533 skb->dev = brnf_get_logical_dev(skb, skb->dev);
519 if (skb->protocol == htons(ETH_P_8021Q)) 534 if (skb->protocol == htons(ETH_P_8021Q))
520 nf_bridge->mask |= BRNF_8021Q; 535 nf_bridge->mask |= BRNF_8021Q;
521 else if (skb->protocol == htons(ETH_P_PPP_SES)) 536 else if (skb->protocol == htons(ETH_P_PPP_SES))
@@ -774,7 +789,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
774 else 789 else
775 skb->protocol = htons(ETH_P_IPV6); 790 skb->protocol = htons(ETH_P_IPV6);
776 791
777 NF_HOOK(pf, NF_INET_FORWARD, skb, bridge_parent(in), parent, 792 NF_HOOK(pf, NF_INET_FORWARD, skb, brnf_get_logical_dev(skb, in), parent,
778 br_nf_forward_finish); 793 br_nf_forward_finish);
779 794
780 return NF_STOLEN; 795 return NF_STOLEN;
@@ -1002,6 +1017,13 @@ static ctl_table brnf_table[] = {
1002 .mode = 0644, 1017 .mode = 0644,
1003 .proc_handler = brnf_sysctl_call_tables, 1018 .proc_handler = brnf_sysctl_call_tables,
1004 }, 1019 },
1020 {
1021 .procname = "bridge-nf-pass-vlan-input-dev",
1022 .data = &brnf_pass_vlan_indev,
1023 .maxlen = sizeof(int),
1024 .mode = 0644,
1025 .proc_handler = brnf_sysctl_call_tables,
1026 },
1005 { } 1027 { }
1006}; 1028};
1007#endif 1029#endif