aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_netfilter.c31
-rw-r--r--net/bridge/br_private.h3
-rw-r--r--net/bridge/br_sysfs_br.c72
3 files changed, 97 insertions, 9 deletions
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 84060bc48f11..9fdf1b116bd7 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -55,6 +55,9 @@ static 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;
57#else 57#else
58#define brnf_call_iptables 1
59#define brnf_call_ip6tables 1
60#define brnf_call_arptables 1
58#define brnf_filter_vlan_tagged 0 61#define brnf_filter_vlan_tagged 0
59#define brnf_filter_pppoe_tagged 0 62#define brnf_filter_pppoe_tagged 0
60#endif 63#endif
@@ -544,25 +547,30 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
544 const struct net_device *out, 547 const struct net_device *out,
545 int (*okfn)(struct sk_buff *)) 548 int (*okfn)(struct sk_buff *))
546{ 549{
550 struct net_bridge_port *p;
551 struct net_bridge *br;
547 struct iphdr *iph; 552 struct iphdr *iph;
548 __u32 len = nf_bridge_encap_header_len(skb); 553 __u32 len = nf_bridge_encap_header_len(skb);
549 554
550 if (unlikely(!pskb_may_pull(skb, len))) 555 if (unlikely(!pskb_may_pull(skb, len)))
551 goto out; 556 goto out;
552 557
558 p = br_port_get_rcu(in);
559 if (p == NULL)
560 goto out;
561 br = p->br;
562
553 if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) || 563 if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) ||
554 IS_PPPOE_IPV6(skb)) { 564 IS_PPPOE_IPV6(skb)) {
555#ifdef CONFIG_SYSCTL 565 if (!brnf_call_ip6tables && !br->nf_call_ip6tables)
556 if (!brnf_call_ip6tables)
557 return NF_ACCEPT; 566 return NF_ACCEPT;
558#endif 567
559 nf_bridge_pull_encap_header_rcsum(skb); 568 nf_bridge_pull_encap_header_rcsum(skb);
560 return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn); 569 return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
561 } 570 }
562#ifdef CONFIG_SYSCTL 571
563 if (!brnf_call_iptables) 572 if (!brnf_call_iptables && !br->nf_call_iptables)
564 return NF_ACCEPT; 573 return NF_ACCEPT;
565#endif
566 574
567 if (skb->protocol != htons(ETH_P_IP) && !IS_VLAN_IP(skb) && 575 if (skb->protocol != htons(ETH_P_IP) && !IS_VLAN_IP(skb) &&
568 !IS_PPPOE_IP(skb)) 576 !IS_PPPOE_IP(skb))
@@ -715,12 +723,17 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb,
715 const struct net_device *out, 723 const struct net_device *out,
716 int (*okfn)(struct sk_buff *)) 724 int (*okfn)(struct sk_buff *))
717{ 725{
726 struct net_bridge_port *p;
727 struct net_bridge *br;
718 struct net_device **d = (struct net_device **)(skb->cb); 728 struct net_device **d = (struct net_device **)(skb->cb);
719 729
720#ifdef CONFIG_SYSCTL 730 p = br_port_get_rcu(out);
721 if (!brnf_call_arptables) 731 if (p == NULL)
732 return NF_ACCEPT;
733 br = p->br;
734
735 if (!brnf_call_arptables && !br->nf_call_arptables)
722 return NF_ACCEPT; 736 return NF_ACCEPT;
723#endif
724 737
725 if (skb->protocol != htons(ETH_P_ARP)) { 738 if (skb->protocol != htons(ETH_P_ARP)) {
726 if (!IS_VLAN_ARP(skb)) 739 if (!IS_VLAN_ARP(skb))
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 3f0678fd1fd0..75c90edaf7db 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -176,6 +176,9 @@ struct net_bridge
176 unsigned long feature_mask; 176 unsigned long feature_mask;
177#ifdef CONFIG_BRIDGE_NETFILTER 177#ifdef CONFIG_BRIDGE_NETFILTER
178 struct rtable fake_rtable; 178 struct rtable fake_rtable;
179 bool nf_call_iptables;
180 bool nf_call_ip6tables;
181 bool nf_call_arptables;
179#endif 182#endif
180 unsigned long flags; 183 unsigned long flags;
181#define BR_SET_MAC_ADDR 0x00000001 184#define BR_SET_MAC_ADDR 0x00000001
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 486b8f3861d2..5c1e5559ebba 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -611,6 +611,73 @@ static DEVICE_ATTR(multicast_startup_query_interval, S_IRUGO | S_IWUSR,
611 show_multicast_startup_query_interval, 611 show_multicast_startup_query_interval,
612 store_multicast_startup_query_interval); 612 store_multicast_startup_query_interval);
613#endif 613#endif
614#ifdef CONFIG_BRIDGE_NETFILTER
615static ssize_t show_nf_call_iptables(
616 struct device *d, struct device_attribute *attr, char *buf)
617{
618 struct net_bridge *br = to_bridge(d);
619 return sprintf(buf, "%u\n", br->nf_call_iptables);
620}
621
622static int set_nf_call_iptables(struct net_bridge *br, unsigned long val)
623{
624 br->nf_call_iptables = val ? true : false;
625 return 0;
626}
627
628static ssize_t store_nf_call_iptables(
629 struct device *d, struct device_attribute *attr, const char *buf,
630 size_t len)
631{
632 return store_bridge_parm(d, buf, len, set_nf_call_iptables);
633}
634static DEVICE_ATTR(nf_call_iptables, S_IRUGO | S_IWUSR,
635 show_nf_call_iptables, store_nf_call_iptables);
636
637static ssize_t show_nf_call_ip6tables(
638 struct device *d, struct device_attribute *attr, char *buf)
639{
640 struct net_bridge *br = to_bridge(d);
641 return sprintf(buf, "%u\n", br->nf_call_ip6tables);
642}
643
644static int set_nf_call_ip6tables(struct net_bridge *br, unsigned long val)
645{
646 br->nf_call_ip6tables = val ? true : false;
647 return 0;
648}
649
650static ssize_t store_nf_call_ip6tables(
651 struct device *d, struct device_attribute *attr, const char *buf,
652 size_t len)
653{
654 return store_bridge_parm(d, buf, len, set_nf_call_ip6tables);
655}
656static DEVICE_ATTR(nf_call_ip6tables, S_IRUGO | S_IWUSR,
657 show_nf_call_ip6tables, store_nf_call_ip6tables);
658
659static ssize_t show_nf_call_arptables(
660 struct device *d, struct device_attribute *attr, char *buf)
661{
662 struct net_bridge *br = to_bridge(d);
663 return sprintf(buf, "%u\n", br->nf_call_arptables);
664}
665
666static int set_nf_call_arptables(struct net_bridge *br, unsigned long val)
667{
668 br->nf_call_arptables = val ? true : false;
669 return 0;
670}
671
672static ssize_t store_nf_call_arptables(
673 struct device *d, struct device_attribute *attr, const char *buf,
674 size_t len)
675{
676 return store_bridge_parm(d, buf, len, set_nf_call_arptables);
677}
678static DEVICE_ATTR(nf_call_arptables, S_IRUGO | S_IWUSR,
679 show_nf_call_arptables, store_nf_call_arptables);
680#endif
614 681
615static struct attribute *bridge_attrs[] = { 682static struct attribute *bridge_attrs[] = {
616 &dev_attr_forward_delay.attr, 683 &dev_attr_forward_delay.attr,
@@ -645,6 +712,11 @@ static struct attribute *bridge_attrs[] = {
645 &dev_attr_multicast_query_response_interval.attr, 712 &dev_attr_multicast_query_response_interval.attr,
646 &dev_attr_multicast_startup_query_interval.attr, 713 &dev_attr_multicast_startup_query_interval.attr,
647#endif 714#endif
715#ifdef CONFIG_BRIDGE_NETFILTER
716 &dev_attr_nf_call_iptables.attr,
717 &dev_attr_nf_call_ip6tables.attr,
718 &dev_attr_nf_call_arptables.attr,
719#endif
648 NULL 720 NULL
649}; 721};
650 722