aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/ip-sysctl.txt7
-rw-r--r--include/linux/if_pppox.h3
-rw-r--r--include/linux/netfilter_bridge.h11
-rw-r--r--include/linux/sysctl.h1
-rw-r--r--net/bridge/br_netfilter.c77
5 files changed, 92 insertions, 7 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 054c515bd726..af6a63ab9026 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1015,7 +1015,12 @@ bridge-nf-call-ip6tables - BOOLEAN
1015 Default: 1 1015 Default: 1
1016 1016
1017bridge-nf-filter-vlan-tagged - BOOLEAN 1017bridge-nf-filter-vlan-tagged - BOOLEAN
1018 1 : pass bridged vlan-tagged ARP/IP traffic to arptables/iptables. 1018 1 : pass bridged vlan-tagged ARP/IP/IPv6 traffic to {arp,ip,ip6}tables.
1019 0 : disable this.
1020 Default: 1
1021
1022bridge-nf-filter-pppoe-tagged - BOOLEAN
1023 1 : pass bridged pppoe-tagged IP/IPv6 traffic to {ip,ip6}tables.
1019 0 : disable this. 1024 0 : disable this.
1020 Default: 1 1025 Default: 1
1021 1026
diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h
index 29d6579ff1a0..6f987be60fe2 100644
--- a/include/linux/if_pppox.h
+++ b/include/linux/if_pppox.h
@@ -111,6 +111,9 @@ struct pppoe_hdr {
111 struct pppoe_tag tag[0]; 111 struct pppoe_tag tag[0];
112} __attribute__ ((packed)); 112} __attribute__ ((packed));
113 113
114/* Length of entire PPPoE + PPP header */
115#define PPPOE_SES_HLEN 8
116
114#ifdef __KERNEL__ 117#ifdef __KERNEL__
115#include <linux/skbuff.h> 118#include <linux/skbuff.h>
116 119
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
index 55689f39f77a..19060030bac9 100644
--- a/include/linux/netfilter_bridge.h
+++ b/include/linux/netfilter_bridge.h
@@ -7,6 +7,7 @@
7#include <linux/netfilter.h> 7#include <linux/netfilter.h>
8#include <linux/if_ether.h> 8#include <linux/if_ether.h>
9#include <linux/if_vlan.h> 9#include <linux/if_vlan.h>
10#include <linux/if_pppox.h>
10 11
11/* Bridge Hooks */ 12/* Bridge Hooks */
12/* After promisc drops, checksum checks. */ 13/* After promisc drops, checksum checks. */
@@ -58,8 +59,14 @@ static inline int nf_bridge_maybe_copy_header(struct sk_buff *skb)
58 * enough room for the encapsulating header (if there is one). */ 59 * enough room for the encapsulating header (if there is one). */
59static inline int nf_bridge_pad(const struct sk_buff *skb) 60static inline int nf_bridge_pad(const struct sk_buff *skb)
60{ 61{
61 return (skb->nf_bridge && skb->protocol == htons(ETH_P_8021Q)) 62 int padding = 0;
62 ? VLAN_HLEN : 0; 63
64 if (skb->nf_bridge && skb->protocol == htons(ETH_P_8021Q))
65 padding = VLAN_HLEN;
66 else if (skb->nf_bridge && skb->protocol == htons(ETH_P_PPP_SES))
67 padding = PPPOE_SES_HLEN;
68
69 return padding;
63} 70}
64 71
65struct bridge_skb_cb { 72struct bridge_skb_cb {
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index df2d9ed20a4e..47f1c53332ce 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -792,6 +792,7 @@ enum {
792 NET_BRIDGE_NF_CALL_IPTABLES = 2, 792 NET_BRIDGE_NF_CALL_IPTABLES = 2,
793 NET_BRIDGE_NF_CALL_IP6TABLES = 3, 793 NET_BRIDGE_NF_CALL_IP6TABLES = 3,
794 NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4, 794 NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4,
795 NET_BRIDGE_NF_FILTER_PPPOE_TAGGED = 5,
795}; 796};
796 797
797/* CTL_FS names: */ 798/* CTL_FS names: */
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index fd70d041e51f..9b2986b182ba 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -29,6 +29,8 @@
29#include <linux/if_arp.h> 29#include <linux/if_arp.h>
30#include <linux/if_ether.h> 30#include <linux/if_ether.h>
31#include <linux/if_vlan.h> 31#include <linux/if_vlan.h>
32#include <linux/if_pppox.h>
33#include <linux/ppp_defs.h>
32#include <linux/netfilter_bridge.h> 34#include <linux/netfilter_bridge.h>
33#include <linux/netfilter_ipv4.h> 35#include <linux/netfilter_ipv4.h>
34#include <linux/netfilter_ipv6.h> 36#include <linux/netfilter_ipv6.h>
@@ -57,8 +59,10 @@ static int brnf_call_iptables __read_mostly = 1;
57static int brnf_call_ip6tables __read_mostly = 1; 59static int brnf_call_ip6tables __read_mostly = 1;
58static int brnf_call_arptables __read_mostly = 1; 60static int brnf_call_arptables __read_mostly = 1;
59static int brnf_filter_vlan_tagged __read_mostly = 1; 61static int brnf_filter_vlan_tagged __read_mostly = 1;
62static int brnf_filter_pppoe_tagged __read_mostly = 1;
60#else 63#else
61#define brnf_filter_vlan_tagged 1 64#define brnf_filter_vlan_tagged 1
65#define brnf_filter_pppoe_tagged 1
62#endif 66#endif
63 67
64static inline __be16 vlan_proto(const struct sk_buff *skb) 68static inline __be16 vlan_proto(const struct sk_buff *skb)
@@ -81,6 +85,22 @@ static inline __be16 vlan_proto(const struct sk_buff *skb)
81 vlan_proto(skb) == htons(ETH_P_ARP) && \ 85 vlan_proto(skb) == htons(ETH_P_ARP) && \
82 brnf_filter_vlan_tagged) 86 brnf_filter_vlan_tagged)
83 87
88static inline __be16 pppoe_proto(const struct sk_buff *skb)
89{
90 return *((__be16 *)(skb_mac_header(skb) + ETH_HLEN +
91 sizeof(struct pppoe_hdr)));
92}
93
94#define IS_PPPOE_IP(skb) \
95 (skb->protocol == htons(ETH_P_PPP_SES) && \
96 pppoe_proto(skb) == htons(PPP_IP) && \
97 brnf_filter_pppoe_tagged)
98
99#define IS_PPPOE_IPV6(skb) \
100 (skb->protocol == htons(ETH_P_PPP_SES) && \
101 pppoe_proto(skb) == htons(PPP_IPV6) && \
102 brnf_filter_pppoe_tagged)
103
84/* We need these fake structures to make netfilter happy -- 104/* We need these fake structures to make netfilter happy --
85 * lots of places assume that skb->dst != NULL, which isn't 105 * lots of places assume that skb->dst != NULL, which isn't
86 * all that unreasonable. 106 * all that unreasonable.
@@ -128,6 +148,8 @@ static inline void nf_bridge_save_header(struct sk_buff *skb)
128 148
129 if (skb->protocol == htons(ETH_P_8021Q)) 149 if (skb->protocol == htons(ETH_P_8021Q))
130 header_size += VLAN_HLEN; 150 header_size += VLAN_HLEN;
151 else if (skb->protocol == htons(ETH_P_PPP_SES))
152 header_size += PPPOE_SES_HLEN;
131 153
132 skb_copy_from_linear_data_offset(skb, -header_size, 154 skb_copy_from_linear_data_offset(skb, -header_size,
133 skb->nf_bridge->data, header_size); 155 skb->nf_bridge->data, header_size);
@@ -144,6 +166,8 @@ int nf_bridge_copy_header(struct sk_buff *skb)
144 166
145 if (skb->protocol == htons(ETH_P_8021Q)) 167 if (skb->protocol == htons(ETH_P_8021Q))
146 header_size += VLAN_HLEN; 168 header_size += VLAN_HLEN;
169 else if (skb->protocol == htons(ETH_P_PPP_SES))
170 header_size += PPPOE_SES_HLEN;
147 171
148 err = skb_cow(skb, header_size); 172 err = skb_cow(skb, header_size);
149 if (err) 173 if (err)
@@ -154,6 +178,8 @@ int nf_bridge_copy_header(struct sk_buff *skb)
154 178
155 if (skb->protocol == htons(ETH_P_8021Q)) 179 if (skb->protocol == htons(ETH_P_8021Q))
156 __skb_push(skb, VLAN_HLEN); 180 __skb_push(skb, VLAN_HLEN);
181 else if (skb->protocol == htons(ETH_P_PPP_SES))
182 __skb_push(skb, PPPOE_SES_HLEN);
157 return 0; 183 return 0;
158} 184}
159 185
@@ -177,6 +203,9 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
177 if (skb->protocol == htons(ETH_P_8021Q)) { 203 if (skb->protocol == htons(ETH_P_8021Q)) {
178 skb_push(skb, VLAN_HLEN); 204 skb_push(skb, VLAN_HLEN);
179 skb->network_header -= VLAN_HLEN; 205 skb->network_header -= VLAN_HLEN;
206 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
207 skb_push(skb, PPPOE_SES_HLEN);
208 skb->network_header -= PPPOE_SES_HLEN;
180 } 209 }
181 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, 210 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
182 br_handle_frame_finish, 1); 211 br_handle_frame_finish, 1);
@@ -258,6 +287,9 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
258 if (skb->protocol == htons(ETH_P_8021Q)) { 287 if (skb->protocol == htons(ETH_P_8021Q)) {
259 skb_pull(skb, VLAN_HLEN); 288 skb_pull(skb, VLAN_HLEN);
260 skb->network_header += VLAN_HLEN; 289 skb->network_header += VLAN_HLEN;
290 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
291 skb_pull(skb, PPPOE_SES_HLEN);
292 skb->network_header += PPPOE_SES_HLEN;
261 } 293 }
262 skb->dst->output(skb); 294 skb->dst->output(skb);
263 } 295 }
@@ -328,6 +360,10 @@ bridged_dnat:
328 htons(ETH_P_8021Q)) { 360 htons(ETH_P_8021Q)) {
329 skb_push(skb, VLAN_HLEN); 361 skb_push(skb, VLAN_HLEN);
330 skb->network_header -= VLAN_HLEN; 362 skb->network_header -= VLAN_HLEN;
363 } else if(skb->protocol ==
364 htons(ETH_P_PPP_SES)) {
365 skb_push(skb, PPPOE_SES_HLEN);
366 skb->network_header -= PPPOE_SES_HLEN;
331 } 367 }
332 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, 368 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING,
333 skb, skb->dev, NULL, 369 skb, skb->dev, NULL,
@@ -347,6 +383,9 @@ bridged_dnat:
347 if (skb->protocol == htons(ETH_P_8021Q)) { 383 if (skb->protocol == htons(ETH_P_8021Q)) {
348 skb_push(skb, VLAN_HLEN); 384 skb_push(skb, VLAN_HLEN);
349 skb->network_header -= VLAN_HLEN; 385 skb->network_header -= VLAN_HLEN;
386 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
387 skb_push(skb, PPPOE_SES_HLEN);
388 skb->network_header -= PPPOE_SES_HLEN;
350 } 389 }
351 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, 390 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
352 br_handle_frame_finish, 1); 391 br_handle_frame_finish, 1);
@@ -489,7 +528,8 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
489 __u32 len; 528 __u32 len;
490 struct sk_buff *skb = *pskb; 529 struct sk_buff *skb = *pskb;
491 530
492 if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb)) { 531 if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb) ||
532 IS_PPPOE_IPV6(skb)) {
493#ifdef CONFIG_SYSCTL 533#ifdef CONFIG_SYSCTL
494 if (!brnf_call_ip6tables) 534 if (!brnf_call_ip6tables)
495 return NF_ACCEPT; 535 return NF_ACCEPT;
@@ -500,6 +540,9 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
500 if (skb->protocol == htons(ETH_P_8021Q)) { 540 if (skb->protocol == htons(ETH_P_8021Q)) {
501 skb_pull_rcsum(skb, VLAN_HLEN); 541 skb_pull_rcsum(skb, VLAN_HLEN);
502 skb->network_header += VLAN_HLEN; 542 skb->network_header += VLAN_HLEN;
543 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
544 skb_pull_rcsum(skb, PPPOE_SES_HLEN);
545 skb->network_header += PPPOE_SES_HLEN;
503 } 546 }
504 return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn); 547 return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
505 } 548 }
@@ -508,7 +551,8 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
508 return NF_ACCEPT; 551 return NF_ACCEPT;
509#endif 552#endif
510 553
511 if (skb->protocol != htons(ETH_P_IP) && !IS_VLAN_IP(skb)) 554 if (skb->protocol != htons(ETH_P_IP) && !IS_VLAN_IP(skb) &&
555 !IS_PPPOE_IP(skb))
512 return NF_ACCEPT; 556 return NF_ACCEPT;
513 557
514 if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL) 558 if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL)
@@ -517,6 +561,9 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
517 if (skb->protocol == htons(ETH_P_8021Q)) { 561 if (skb->protocol == htons(ETH_P_8021Q)) {
518 skb_pull_rcsum(skb, VLAN_HLEN); 562 skb_pull_rcsum(skb, VLAN_HLEN);
519 skb->network_header += VLAN_HLEN; 563 skb->network_header += VLAN_HLEN;
564 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
565 skb_pull_rcsum(skb, PPPOE_SES_HLEN);
566 skb->network_header += PPPOE_SES_HLEN;
520 } 567 }
521 568
522 if (!pskb_may_pull(skb, sizeof(struct iphdr))) 569 if (!pskb_may_pull(skb, sizeof(struct iphdr)))
@@ -598,6 +645,9 @@ static int br_nf_forward_finish(struct sk_buff *skb)
598 if (skb->protocol == htons(ETH_P_8021Q)) { 645 if (skb->protocol == htons(ETH_P_8021Q)) {
599 skb_push(skb, VLAN_HLEN); 646 skb_push(skb, VLAN_HLEN);
600 skb->network_header -= VLAN_HLEN; 647 skb->network_header -= VLAN_HLEN;
648 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
649 skb_push(skb, PPPOE_SES_HLEN);
650 skb->network_header -= PPPOE_SES_HLEN;
601 } 651 }
602 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in, 652 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in,
603 skb->dev, br_forward_finish, 1); 653 skb->dev, br_forward_finish, 1);
@@ -626,7 +676,8 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
626 if (!parent) 676 if (!parent)
627 return NF_DROP; 677 return NF_DROP;
628 678
629 if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb)) 679 if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb) ||
680 IS_PPPOE_IP(skb))
630 pf = PF_INET; 681 pf = PF_INET;
631 else 682 else
632 pf = PF_INET6; 683 pf = PF_INET6;
@@ -634,6 +685,9 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
634 if (skb->protocol == htons(ETH_P_8021Q)) { 685 if (skb->protocol == htons(ETH_P_8021Q)) {
635 skb_pull(*pskb, VLAN_HLEN); 686 skb_pull(*pskb, VLAN_HLEN);
636 (*pskb)->network_header += VLAN_HLEN; 687 (*pskb)->network_header += VLAN_HLEN;
688 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
689 skb_pull(*pskb, PPPOE_SES_HLEN);
690 (*pskb)->network_header += PPPOE_SES_HLEN;
637 } 691 }
638 692
639 nf_bridge = skb->nf_bridge; 693 nf_bridge = skb->nf_bridge;
@@ -726,6 +780,9 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
726 if (skb->protocol == htons(ETH_P_8021Q)) { 780 if (skb->protocol == htons(ETH_P_8021Q)) {
727 skb_push(skb, VLAN_HLEN); 781 skb_push(skb, VLAN_HLEN);
728 skb->network_header -= VLAN_HLEN; 782 skb->network_header -= VLAN_HLEN;
783 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
784 skb_push(skb, PPPOE_SES_HLEN);
785 skb->network_header -= PPPOE_SES_HLEN;
729 } 786 }
730 787
731 NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev, 788 NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev,
@@ -771,7 +828,8 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
771 if (!realoutdev) 828 if (!realoutdev)
772 return NF_DROP; 829 return NF_DROP;
773 830
774 if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb)) 831 if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb) ||
832 IS_PPPOE_IP(skb))
775 pf = PF_INET; 833 pf = PF_INET;
776 else 834 else
777 pf = PF_INET6; 835 pf = PF_INET6;
@@ -793,6 +851,9 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
793 if (skb->protocol == htons(ETH_P_8021Q)) { 851 if (skb->protocol == htons(ETH_P_8021Q)) {
794 skb_pull(skb, VLAN_HLEN); 852 skb_pull(skb, VLAN_HLEN);
795 skb->network_header += VLAN_HLEN; 853 skb->network_header += VLAN_HLEN;
854 } else if (skb->protocol == htons(ETH_P_PPP_SES)) {
855 skb_pull(skb, PPPOE_SES_HLEN);
856 skb->network_header += PPPOE_SES_HLEN;
796 } 857 }
797 858
798 nf_bridge_save_header(skb); 859 nf_bridge_save_header(skb);
@@ -930,6 +991,14 @@ static ctl_table brnf_table[] = {
930 .mode = 0644, 991 .mode = 0644,
931 .proc_handler = &brnf_sysctl_call_tables, 992 .proc_handler = &brnf_sysctl_call_tables,
932 }, 993 },
994 {
995 .ctl_name = NET_BRIDGE_NF_FILTER_PPPOE_TAGGED,
996 .procname = "bridge-nf-filter-pppoe-tagged",
997 .data = &brnf_filter_pppoe_tagged,
998 .maxlen = sizeof(int),
999 .mode = 0644,
1000 .proc_handler = &brnf_sysctl_call_tables,
1001 },
933 { .ctl_name = 0 } 1002 { .ctl_name = 0 }
934}; 1003};
935 1004