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>
This commit is contained in:
parent
ac3a546ac8
commit
4981682cc1
|
@ -1301,13 +1301,22 @@ bridge-nf-call-ip6tables - BOOLEAN
|
||||||
bridge-nf-filter-vlan-tagged - BOOLEAN
|
bridge-nf-filter-vlan-tagged - BOOLEAN
|
||||||
1 : pass bridged vlan-tagged ARP/IP/IPv6 traffic to {arp,ip,ip6}tables.
|
1 : pass bridged vlan-tagged ARP/IP/IPv6 traffic to {arp,ip,ip6}tables.
|
||||||
0 : disable this.
|
0 : disable this.
|
||||||
Default: 1
|
Default: 0
|
||||||
|
|
||||||
bridge-nf-filter-pppoe-tagged - BOOLEAN
|
bridge-nf-filter-pppoe-tagged - BOOLEAN
|
||||||
1 : pass bridged pppoe-tagged IP/IPv6 traffic to {ip,ip6}tables.
|
1 : pass bridged pppoe-tagged IP/IPv6 traffic to {ip,ip6}tables.
|
||||||
0 : disable this.
|
0 : disable this.
|
||||||
Default: 1
|
Default: 0
|
||||||
|
|
||||||
|
bridge-nf-pass-vlan-input-dev - BOOLEAN
|
||||||
|
1: if bridge-nf-filter-vlan-tagged is enabled, try to find a vlan
|
||||||
|
interface on the bridge and set the netfilter input device to the vlan.
|
||||||
|
This allows use of e.g. "iptables -i br0.1" and makes the REDIRECT
|
||||||
|
target work with vlan-on-top-of-bridge interfaces. When no matching
|
||||||
|
vlan interface is found, or this switch is off, the input device is
|
||||||
|
set to the bridge interface.
|
||||||
|
0: disable bridge netfilter vlan interface lookup.
|
||||||
|
Default: 0
|
||||||
|
|
||||||
proc/sys/net/sctp/* Variables:
|
proc/sys/net/sctp/* Variables:
|
||||||
|
|
||||||
|
|
|
@ -54,12 +54,14 @@ static int brnf_call_ip6tables __read_mostly = 1;
|
||||||
static int brnf_call_arptables __read_mostly = 1;
|
static int brnf_call_arptables __read_mostly = 1;
|
||||||
static int brnf_filter_vlan_tagged __read_mostly = 0;
|
static int brnf_filter_vlan_tagged __read_mostly = 0;
|
||||||
static int brnf_filter_pppoe_tagged __read_mostly = 0;
|
static int brnf_filter_pppoe_tagged __read_mostly = 0;
|
||||||
|
static int brnf_pass_vlan_indev __read_mostly = 0;
|
||||||
#else
|
#else
|
||||||
#define brnf_call_iptables 1
|
#define brnf_call_iptables 1
|
||||||
#define brnf_call_ip6tables 1
|
#define brnf_call_ip6tables 1
|
||||||
#define brnf_call_arptables 1
|
#define brnf_call_arptables 1
|
||||||
#define brnf_filter_vlan_tagged 0
|
#define brnf_filter_vlan_tagged 0
|
||||||
#define brnf_filter_pppoe_tagged 0
|
#define brnf_filter_pppoe_tagged 0
|
||||||
|
#define brnf_pass_vlan_indev 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define IS_IP(skb) \
|
#define IS_IP(skb) \
|
||||||
|
@ -503,6 +505,19 @@ bridged_dnat:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct net_device *brnf_get_logical_dev(struct sk_buff *skb, const struct net_device *dev)
|
||||||
|
{
|
||||||
|
struct net_device *vlan, *br;
|
||||||
|
|
||||||
|
br = bridge_parent(dev);
|
||||||
|
if (brnf_pass_vlan_indev == 0 || !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 */
|
/* Some common code for IPv4/IPv6 */
|
||||||
static struct net_device *setup_pre_routing(struct sk_buff *skb)
|
static struct net_device *setup_pre_routing(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
@ -515,7 +530,7 @@ static struct net_device *setup_pre_routing(struct sk_buff *skb)
|
||||||
|
|
||||||
nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
|
nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
|
||||||
nf_bridge->physindev = skb->dev;
|
nf_bridge->physindev = skb->dev;
|
||||||
skb->dev = bridge_parent(skb->dev);
|
skb->dev = brnf_get_logical_dev(skb, skb->dev);
|
||||||
if (skb->protocol == htons(ETH_P_8021Q))
|
if (skb->protocol == htons(ETH_P_8021Q))
|
||||||
nf_bridge->mask |= BRNF_8021Q;
|
nf_bridge->mask |= BRNF_8021Q;
|
||||||
else if (skb->protocol == htons(ETH_P_PPP_SES))
|
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,
|
||||||
else
|
else
|
||||||
skb->protocol = htons(ETH_P_IPV6);
|
skb->protocol = htons(ETH_P_IPV6);
|
||||||
|
|
||||||
NF_HOOK(pf, NF_INET_FORWARD, skb, bridge_parent(in), parent,
|
NF_HOOK(pf, NF_INET_FORWARD, skb, brnf_get_logical_dev(skb, in), parent,
|
||||||
br_nf_forward_finish);
|
br_nf_forward_finish);
|
||||||
|
|
||||||
return NF_STOLEN;
|
return NF_STOLEN;
|
||||||
|
@ -1002,6 +1017,13 @@ static ctl_table brnf_table[] = {
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = brnf_sysctl_call_tables,
|
.proc_handler = brnf_sysctl_call_tables,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.procname = "bridge-nf-pass-vlan-input-dev",
|
||||||
|
.data = &brnf_pass_vlan_indev,
|
||||||
|
.maxlen = sizeof(int),
|
||||||
|
.mode = 0644,
|
||||||
|
.proc_handler = brnf_sysctl_call_tables,
|
||||||
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue