diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-05-08 13:36:44 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-05-08 13:36:47 -0400 |
commit | 4981682cc19733f3ca43d3abd81dd4adbc9005d5 (patch) | |
tree | 6c4583e26b8f12559defc11d0c141011a71e3de1 | |
parent | ac3a546ac89fdf3c4b50e40039a5a7f6df4dda72 (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>
-rw-r--r-- | Documentation/networking/ip-sysctl.txt | 13 | ||||
-rw-r--r-- | net/bridge/br_netfilter.c | 26 |
2 files changed, 35 insertions, 4 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 90b0c4fd275b..6f896b94abdc 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -1301,13 +1301,22 @@ bridge-nf-call-ip6tables - BOOLEAN | |||
1301 | bridge-nf-filter-vlan-tagged - BOOLEAN | 1301 | bridge-nf-filter-vlan-tagged - BOOLEAN |
1302 | 1 : pass bridged vlan-tagged ARP/IP/IPv6 traffic to {arp,ip,ip6}tables. | 1302 | 1 : pass bridged vlan-tagged ARP/IP/IPv6 traffic to {arp,ip,ip6}tables. |
1303 | 0 : disable this. | 1303 | 0 : disable this. |
1304 | Default: 1 | 1304 | Default: 0 |
1305 | 1305 | ||
1306 | bridge-nf-filter-pppoe-tagged - BOOLEAN | 1306 | bridge-nf-filter-pppoe-tagged - BOOLEAN |
1307 | 1 : pass bridged pppoe-tagged IP/IPv6 traffic to {ip,ip6}tables. | 1307 | 1 : pass bridged pppoe-tagged IP/IPv6 traffic to {ip,ip6}tables. |
1308 | 0 : disable this. | 1308 | 0 : disable this. |
1309 | Default: 1 | 1309 | Default: 0 |
1310 | 1310 | ||
1311 | bridge-nf-pass-vlan-input-dev - BOOLEAN | ||
1312 | 1: if bridge-nf-filter-vlan-tagged is enabled, try to find a vlan | ||
1313 | interface on the bridge and set the netfilter input device to the vlan. | ||
1314 | This allows use of e.g. "iptables -i br0.1" and makes the REDIRECT | ||
1315 | target work with vlan-on-top-of-bridge interfaces. When no matching | ||
1316 | vlan interface is found, or this switch is off, the input device is | ||
1317 | set to the bridge interface. | ||
1318 | 0: disable bridge netfilter vlan interface lookup. | ||
1319 | Default: 0 | ||
1311 | 1320 | ||
1312 | proc/sys/net/sctp/* Variables: | 1321 | proc/sys/net/sctp/* Variables: |
1313 | 1322 | ||
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; | |||
54 | static int brnf_call_arptables __read_mostly = 1; | 54 | static int brnf_call_arptables __read_mostly = 1; |
55 | static int brnf_filter_vlan_tagged __read_mostly = 0; | 55 | static int brnf_filter_vlan_tagged __read_mostly = 0; |
56 | static int brnf_filter_pppoe_tagged __read_mostly = 0; | 56 | static int brnf_filter_pppoe_tagged __read_mostly = 0; |
57 | static 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 | ||
508 | static 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 */ |
507 | static struct net_device *setup_pre_routing(struct sk_buff *skb) | 522 | static 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 |