|
@@ -54,12 +54,14 @@ static int brnf_call_ip6tables __read_mostly = 1;
|
|
|
static int brnf_call_arptables __read_mostly = 1;
|
|
|
static int brnf_filter_vlan_tagged __read_mostly = 0;
|
|
|
static int brnf_filter_pppoe_tagged __read_mostly = 0;
|
|
|
+static int brnf_pass_vlan_indev __read_mostly = 0;
|
|
|
#else
|
|
|
#define brnf_call_iptables 1
|
|
|
#define brnf_call_ip6tables 1
|
|
|
#define brnf_call_arptables 1
|
|
|
#define brnf_filter_vlan_tagged 0
|
|
|
#define brnf_filter_pppoe_tagged 0
|
|
|
+#define brnf_pass_vlan_indev 0
|
|
|
#endif
|
|
|
|
|
|
#define IS_IP(skb) \
|
|
@@ -503,6 +505,19 @@ bridged_dnat:
|
|
|
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 */
|
|
|
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->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))
|
|
|
nf_bridge->mask |= BRNF_8021Q;
|
|
|
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
|
|
|
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);
|
|
|
|
|
|
return NF_STOLEN;
|
|
@@ -1002,6 +1017,13 @@ static ctl_table brnf_table[] = {
|
|
|
.mode = 0644,
|
|
|
.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
|