diff options
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br_netfilter.c | 31 | ||||
-rw-r--r-- | net/bridge/br_private.h | 3 | ||||
-rw-r--r-- | net/bridge/br_sysfs_br.c | 72 |
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; | |||
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 | #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 | ||
615 | static 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 | |||
622 | static 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 | |||
628 | static 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 | } | ||
634 | static DEVICE_ATTR(nf_call_iptables, S_IRUGO | S_IWUSR, | ||
635 | show_nf_call_iptables, store_nf_call_iptables); | ||
636 | |||
637 | static 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 | |||
644 | static 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 | |||
650 | static 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 | } | ||
656 | static DEVICE_ATTR(nf_call_ip6tables, S_IRUGO | S_IWUSR, | ||
657 | show_nf_call_ip6tables, store_nf_call_ip6tables); | ||
658 | |||
659 | static 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 | |||
666 | static 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 | |||
672 | static 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 | } | ||
678 | static DEVICE_ATTR(nf_call_arptables, S_IRUGO | S_IWUSR, | ||
679 | show_nf_call_arptables, store_nf_call_arptables); | ||
680 | #endif | ||
614 | 681 | ||
615 | static struct attribute *bridge_attrs[] = { | 682 | static 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 | ||