* [PATCH] Add sysctl entries for bridge-nf
@ 2003-12-22 22:01 Bart De Schuymer
2003-12-25 3:32 ` David S. Miller
0 siblings, 1 reply; 2+ messages in thread
From: Bart De Schuymer @ 2003-12-22 22:01 UTC (permalink / raw)
To: David S.Miller; +Cc: netdev
Hi Dave,
The following patch adds these sysctl entries in /proc/sys/net/bridge/:
bridge-nf-call-arptables - pass or don't pass bridged ARP traffic to
arptables' FORWARD chain.
bridge-nf-call-iptables - pass or don't pass bridged IPv4 traffic to
iptables' chains.
bridge-nf-filter-vlan-tagged - pass or don't pass bridged vlan-tagged
ARP/IP traffic to arptables/iptables.
It adds the necessary constants to sysctl.h, changes br_netfilter.c and
adds some info to the ip-sysctl documentation.
The default values are so that the old behavior is kept by default.
cheers,
Bart
--- linux-2.6.0/include/linux/sysctl.h.old 2003-12-21 16:46:05.000000000 +0100
+++ linux-2.6.0/include/linux/sysctl.h 2003-12-21 16:53:09.000000000 +0100
@@ -579,6 +579,14 @@
NET_SCTP_MAX_BURST = 12,
};
+/* /proc/sys/net/bridge */
+enum {
+ NET_BRIDGE_NF_CALL_ARPTABLES = 1,
+ NET_BRIDGE_NF_CALL_IPTABLES = 2,
+ NET_BRIDGE_NF_CALL_IP6TABLES = 3,
+ NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4,
+};
+
/* CTL_PROC names: */
/* CTL_FS names: */
--- linux-2.6.0/net/bridge/br_netfilter.c.earlier 2003-12-21 13:29:59.000000000 +0100
+++ linux-2.6.0/net/bridge/br_netfilter.c 2003-12-22 22:16:45.000000000 +0100
@@ -35,6 +35,9 @@
#include <asm/uaccess.h>
#include <asm/checksum.h>
#include "br_private.h"
+#ifdef CONFIG_SYSCTL
+#include <linux/sysctl.h>
+#endif
#define skb_origaddr(skb) (((struct bridge_skb_cb *) \
@@ -45,10 +48,21 @@
#define has_bridge_parent(device) ((device)->br_port != NULL)
#define bridge_parent(device) ((device)->br_port->br->dev)
-#define IS_VLAN_IP (skb->protocol == __constant_htons(ETH_P_8021Q) && \
- hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP))
-#define IS_VLAN_ARP (skb->protocol == __constant_htons(ETH_P_8021Q) && \
- hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_ARP))
+#ifdef CONFIG_SYSCTL
+static struct ctl_table_header *brnf_sysctl_header;
+static int brnf_call_iptables = 1;
+static int brnf_call_arptables = 1;
+static int brnf_filter_vlan_tagged = 1;
+#else
+#define brnf_filter_vlan_tagged 1
+#endif
+
+#define IS_VLAN_IP (skb->protocol == __constant_htons(ETH_P_8021Q) && \
+ hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP) && \
+ brnf_filter_vlan_tagged)
+#define IS_VLAN_ARP (skb->protocol == __constant_htons(ETH_P_8021Q) && \
+ hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_ARP) && \
+ brnf_filter_vlan_tagged)
/* We need these fake structures to make netfilter happy --
* lots of places assume that skb->dst != NULL, which isn't
@@ -72,8 +86,7 @@ static struct rtable __fake_rtable = {
.metrics = {[RTAX_MTU - 1] = 1500},
}
},
-
- .rt_flags = 0
+ .rt_flags = 0,
};
@@ -247,6 +260,11 @@ static unsigned int br_nf_pre_routing(un
struct sk_buff *skb = *pskb;
struct nf_bridge_info *nf_bridge;
+#ifdef CONFIG_SYSCTL
+ if (!brnf_call_iptables)
+ return NF_ACCEPT;
+#endif
+
if (skb->protocol != __constant_htons(ETH_P_IP)) {
struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)
((*pskb)->mac.ethernet);
@@ -369,7 +387,7 @@ static int br_nf_forward_finish(struct s
* because of the ipt_physdev.c module. For ARP, indev and outdev are the
* bridge ports.
*/
-static unsigned int br_nf_forward(unsigned int hook, struct sk_buff **pskb,
+static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
@@ -377,9 +395,13 @@ static unsigned int br_nf_forward(unsign
struct nf_bridge_info *nf_bridge;
struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet);
- if (skb->protocol != __constant_htons(ETH_P_IP) &&
- skb->protocol != __constant_htons(ETH_P_ARP)) {
- if (!IS_VLAN_IP && !IS_VLAN_ARP)
+#ifdef CONFIG_SYSCTL
+ if (!skb->nf_bridge)
+ return NF_ACCEPT;
+#endif
+
+ if (skb->protocol != __constant_htons(ETH_P_IP)) {
+ if (!IS_VLAN_IP)
return NF_ACCEPT;
skb_pull(*pskb, VLAN_HLEN);
(*pskb)->nh.raw += VLAN_HLEN;
@@ -388,39 +410,58 @@ static unsigned int br_nf_forward(unsign
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug ^= (1 << NF_BR_FORWARD);
#endif
- if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP) {
- nf_bridge = skb->nf_bridge;
- if (skb->pkt_type == PACKET_OTHERHOST) {
- skb->pkt_type = PACKET_HOST;
- nf_bridge->mask |= BRNF_PKT_TYPE;
- }
+ nf_bridge = skb->nf_bridge;
+ if (skb->pkt_type == PACKET_OTHERHOST) {
+ skb->pkt_type = PACKET_HOST;
+ nf_bridge->mask |= BRNF_PKT_TYPE;
+ }
- /* The physdev module checks on this */
- nf_bridge->mask |= BRNF_BRIDGED;
- nf_bridge->physoutdev = skb->dev;
+ /* The physdev module checks on this */
+ nf_bridge->mask |= BRNF_BRIDGED;
+ nf_bridge->physoutdev = skb->dev;
- NF_HOOK(PF_INET, NF_IP_FORWARD, skb, bridge_parent(in),
- bridge_parent(out), br_nf_forward_finish);
- } else {
- struct net_device **d = (struct net_device **)(skb->cb);
- struct arphdr *arp = skb->nh.arph;
+ NF_HOOK(PF_INET, NF_IP_FORWARD, skb, bridge_parent(in),
+ bridge_parent(out), br_nf_forward_finish);
- if (arp->ar_pln != 4) {
- if (IS_VLAN_ARP) {
- skb_push(*pskb, VLAN_HLEN);
- (*pskb)->nh.raw -= VLAN_HLEN;
- }
+ return NF_STOLEN;
+}
+
+static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
+ const struct net_device *in, const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct sk_buff *skb = *pskb;
+ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet);
+ struct net_device **d = (struct net_device **)(skb->cb);
+
+ if (!brnf_call_arptables)
+ return NF_ACCEPT;
+
+ if (skb->protocol != __constant_htons(ETH_P_ARP)) {
+ if (!IS_VLAN_ARP)
return NF_ACCEPT;
+ skb_pull(*pskb, VLAN_HLEN);
+ (*pskb)->nh.raw += VLAN_HLEN;
+ }
+
+#ifdef CONFIG_NETFILTER_DEBUG
+ skb->nf_debug ^= (1 << NF_BR_FORWARD);
+#endif
+
+ if (skb->nh.arph->ar_pln != 4) {
+ if (IS_VLAN_ARP) {
+ skb_push(*pskb, VLAN_HLEN);
+ (*pskb)->nh.raw -= VLAN_HLEN;
}
- *d = (struct net_device *)in;
- NF_HOOK(NF_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in,
- (struct net_device *)out, br_nf_forward_finish);
+ return NF_ACCEPT;
}
+ *d = (struct net_device *)in;
+ NF_HOOK(NF_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in,
+ (struct net_device *)out, br_nf_forward_finish);
return NF_STOLEN;
}
-
/* PF_BRIDGE/LOCAL_OUT ***********************************************/
static int br_nf_local_out_finish(struct sk_buff *skb)
{
@@ -471,6 +512,11 @@ static unsigned int br_nf_local_out(unsi
struct nf_bridge_info *nf_bridge;
struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet);
+#ifdef CONFIG_SYSCTL
+ if (!skb->nf_bridge)
+ return NF_ACCEPT;
+#endif
+
if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP)
return NF_ACCEPT;
@@ -481,6 +527,7 @@ static unsigned int br_nf_local_out(unsi
return NF_ACCEPT;
nf_bridge = skb->nf_bridge;
+
nf_bridge->physoutdev = skb->dev;
realindev = nf_bridge->physindev;
@@ -563,6 +610,11 @@ static unsigned int br_nf_post_routing(u
return NF_ACCEPT;
}
+#ifdef CONFIG_SYSCTL
+ if (!nf_bridge)
+ return NF_ACCEPT;
+#endif
+
if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP)
return NF_ACCEPT;
@@ -628,6 +680,13 @@ static unsigned int ipv4_sabotage_out(un
const struct net_device *in, const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
+ struct sk_buff *skb = *pskb;
+
+#ifdef CONFIG_SYSCTL
+ if (!brnf_call_iptables && !skb->nf_bridge)
+ return NF_ACCEPT;
+#endif
+
if ((out->hard_start_xmit == br_dev_xmit &&
okfn != br_nf_forward_finish &&
okfn != br_nf_local_out_finish &&
@@ -637,7 +696,6 @@ static unsigned int ipv4_sabotage_out(un
VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit)
#endif
) {
- struct sk_buff *skb = *pskb;
struct nf_bridge_info *nf_bridge;
if (!skb->nf_bridge && !nf_bridge_alloc(skb))
@@ -683,7 +741,12 @@ static struct nf_hook_ops br_nf_ops[] =
.pf = PF_BRIDGE,
.hooknum = NF_BR_LOCAL_IN,
.priority = NF_BR_PRI_BRNF, },
- { .hook = br_nf_forward,
+ { .hook = br_nf_forward_ip,
+ .owner = THIS_MODULE,
+ .pf = PF_BRIDGE,
+ .hooknum = NF_BR_FORWARD,
+ .priority = NF_BR_PRI_BRNF - 1, },
+ { .hook = br_nf_forward_arp,
.owner = THIS_MODULE,
.pf = PF_BRIDGE,
.hooknum = NF_BR_FORWARD,
@@ -720,6 +783,69 @@ static struct nf_hook_ops br_nf_ops[] =
.priority = NF_IP_PRI_FIRST, },
};
+#ifdef CONFIG_SYSCTL
+static
+int brnf_sysctl_call_tables(ctl_table *ctl, int write, struct file * filp,
+ void *buffer, size_t *lenp)
+{
+ int ret;
+
+ ret = proc_dointvec(ctl, write, filp, buffer, lenp);
+
+ if (write && *(int *)(ctl->data))
+ *(int *)(ctl->data) = 1;
+ return ret;
+}
+
+static ctl_table brnf_table[] = {
+ {
+ .ctl_name = NET_BRIDGE_NF_CALL_ARPTABLES,
+ .procname = "bridge-nf-call-arptables",
+ .data = &brnf_call_arptables,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &brnf_sysctl_call_tables,
+ },
+ {
+ .ctl_name = NET_BRIDGE_NF_CALL_IPTABLES,
+ .procname = "bridge-nf-call-iptables",
+ .data = &brnf_call_iptables,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &brnf_sysctl_call_tables,
+ },
+ {
+ .ctl_name = NET_BRIDGE_NF_FILTER_VLAN_TAGGED,
+ .procname = "bridge-nf-filter-vlan-tagged",
+ .data = &brnf_filter_vlan_tagged,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &brnf_sysctl_call_tables,
+ },
+ { .ctl_name = 0 }
+};
+
+static ctl_table brnf_bridge_table[] = {
+ {
+ .ctl_name = NET_BRIDGE,
+ .procname = "bridge",
+ .mode = 0555,
+ .child = brnf_table,
+ },
+ { .ctl_name = 0 }
+};
+
+static ctl_table brnf_net_table[] = {
+ {
+ .ctl_name = CTL_NET,
+ .procname = "net",
+ .mode = 0555,
+ .child = brnf_bridge_table,
+ },
+ { .ctl_name = 0 }
+};
+#endif
+
int br_netfilter_init(void)
{
int i;
@@ -736,6 +862,16 @@ int br_netfilter_init(void)
return ret;
}
+#ifdef CONFIG_SYSCTL
+ brnf_sysctl_header = register_sysctl_table(brnf_net_table, 0);
+ if (brnf_sysctl_header == NULL) {
+ printk(KERN_WARNING "br_netfilter: can't register to sysctl.\n");
+ for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++)
+ nf_unregister_hook(&br_nf_ops[i]);
+ return -EFAULT;
+ }
+#endif
+
printk(KERN_NOTICE "Bridge firewalling registered\n");
return 0;
@@ -747,4 +883,7 @@ void br_netfilter_fini(void)
for (i = ARRAY_SIZE(br_nf_ops) - 1; i >= 0; i--)
nf_unregister_hook(&br_nf_ops[i]);
+#ifdef CONFIG_SYSCTL
+ unregister_sysctl_table(brnf_sysctl_header);
+#endif
}
--- linux-2.6.0/Documentation/networking/ip-sysctl.txt.old 2003-12-21 22:12:28.000000000 +0100
+++ linux-2.6.0/Documentation/networking/ip-sysctl.txt 2003-12-21 22:22:00.000000000 +0100
@@ -678,4 +678,23 @@
Pekka Savola <pekkas@netcore.fi>
YOSHIFUJI Hideaki / USAGI Project <yoshfuji@linux-ipv6.org>
+
+/proc/sys/net/bridge/* Variables:
+
+bridge-nf-call-arptables - BOOLEAN
+ 1 : pass bridged ARP traffic to arptables' FORWARD chain.
+ 0 : disable this.
+ Default: 1
+
+bridge-nf-call-iptables - BOOLEAN
+ 1 : pass bridged IPv4 traffic to iptables' chains.
+ 0 : disable this.
+ Default: 1
+
+bridge-nf-filter-vlan-tagged - BOOLEAN
+ 1 : pass bridged vlan-tagged ARP/IP traffic to arptables/iptables.
+ 0 : disable this.
+ Default: 1
+
+
$Id: ip-sysctl.txt,v 1.20 2001/12/13 09:00:18 davem Exp $
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH] Add sysctl entries for bridge-nf
2003-12-22 22:01 [PATCH] Add sysctl entries for bridge-nf Bart De Schuymer
@ 2003-12-25 3:32 ` David S. Miller
0 siblings, 0 replies; 2+ messages in thread
From: David S. Miller @ 2003-12-25 3:32 UTC (permalink / raw)
To: Bart De Schuymer; +Cc: netdev
On Mon, 22 Dec 2003 23:01:47 +0100
Bart De Schuymer <bdschuym@pandora.be> wrote:
> The following patch adds these sysctl entries in /proc/sys/net/bridge/:
> bridge-nf-call-arptables - pass or don't pass bridged ARP traffic to
> arptables' FORWARD chain.
> bridge-nf-call-iptables - pass or don't pass bridged IPv4 traffic to
> iptables' chains.
> bridge-nf-filter-vlan-tagged - pass or don't pass bridged vlan-tagged
> ARP/IP traffic to arptables/iptables.
>
> It adds the necessary constants to sysctl.h, changes br_netfilter.c and
> adds some info to the ip-sysctl documentation.
> The default values are so that the old behavior is kept by default.
Applied, thanks Bart.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2003-12-25 3:32 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-12-22 22:01 [PATCH] Add sysctl entries for bridge-nf Bart De Schuymer
2003-12-25 3:32 ` David S. Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).