aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/Kconfig1
-rw-r--r--net/bridge/br.c18
-rw-r--r--net/bridge/br_device.c14
-rw-r--r--net/bridge/br_fdb.c2
-rw-r--r--net/bridge/br_forward.c6
-rw-r--r--net/bridge/br_if.c12
-rw-r--r--net/bridge/br_input.c25
-rw-r--r--net/bridge/br_ioctl.c2
-rw-r--r--net/bridge/br_notify.c4
-rw-r--r--net/bridge/br_private.h10
-rw-r--r--net/bridge/br_private_stp.h2
-rw-r--r--net/bridge/br_stp.c2
-rw-r--r--net/bridge/br_stp_bpdu.c16
-rw-r--r--net/bridge/br_stp_if.c6
-rw-r--r--net/bridge/br_stp_timer.c2
-rw-r--r--net/bridge/netfilter/Kconfig11
-rw-r--r--net/bridge/netfilter/Makefile1
-rw-r--r--net/bridge/netfilter/ebt_ip6.c144
-rw-r--r--net/bridge/netfilter/ebt_log.c66
19 files changed, 251 insertions, 93 deletions
diff --git a/net/bridge/Kconfig b/net/bridge/Kconfig
index 12265aff7099..e143ca678881 100644
--- a/net/bridge/Kconfig
+++ b/net/bridge/Kconfig
@@ -5,6 +5,7 @@
5config BRIDGE 5config BRIDGE
6 tristate "802.1d Ethernet Bridging" 6 tristate "802.1d Ethernet Bridging"
7 select LLC 7 select LLC
8 select STP
8 ---help--- 9 ---help---
9 If you say Y here, then your Linux box will be able to act as an 10 If you say Y here, then your Linux box will be able to act as an
10 Ethernet bridge, which means that the different Ethernet segments it 11 Ethernet bridge, which means that the different Ethernet segments it
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 8f3c58e5f7a5..573acdf6f9ff 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br.c,v 1.47 2001/12/24 00:56:41 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
@@ -20,21 +18,24 @@
20#include <linux/init.h> 18#include <linux/init.h>
21#include <linux/llc.h> 19#include <linux/llc.h>
22#include <net/llc.h> 20#include <net/llc.h>
21#include <net/stp.h>
23 22
24#include "br_private.h" 23#include "br_private.h"
25 24
26int (*br_should_route_hook)(struct sk_buff *skb); 25int (*br_should_route_hook)(struct sk_buff *skb);
27 26
28static struct llc_sap *br_stp_sap; 27static const struct stp_proto br_stp_proto = {
28 .rcv = br_stp_rcv,
29};
29 30
30static int __init br_init(void) 31static int __init br_init(void)
31{ 32{
32 int err; 33 int err;
33 34
34 br_stp_sap = llc_sap_open(LLC_SAP_BSPAN, br_stp_rcv); 35 err = stp_proto_register(&br_stp_proto);
35 if (!br_stp_sap) { 36 if (err < 0) {
36 printk(KERN_ERR "bridge: can't register sap for STP\n"); 37 printk(KERN_ERR "bridge: can't register sap for STP\n");
37 return -EADDRINUSE; 38 return err;
38 } 39 }
39 40
40 err = br_fdb_init(); 41 err = br_fdb_init();
@@ -67,13 +68,13 @@ err_out2:
67err_out1: 68err_out1:
68 br_fdb_fini(); 69 br_fdb_fini();
69err_out: 70err_out:
70 llc_sap_put(br_stp_sap); 71 stp_proto_unregister(&br_stp_proto);
71 return err; 72 return err;
72} 73}
73 74
74static void __exit br_deinit(void) 75static void __exit br_deinit(void)
75{ 76{
76 rcu_assign_pointer(br_stp_sap->rcv_func, NULL); 77 stp_proto_unregister(&br_stp_proto);
77 78
78 br_netlink_fini(); 79 br_netlink_fini();
79 unregister_netdevice_notifier(&br_device_notifier); 80 unregister_netdevice_notifier(&br_device_notifier);
@@ -84,7 +85,6 @@ static void __exit br_deinit(void)
84 synchronize_net(); 85 synchronize_net();
85 86
86 br_netfilter_fini(); 87 br_netfilter_fini();
87 llc_sap_put(br_stp_sap);
88 br_fdb_get_hook = NULL; 88 br_fdb_get_hook = NULL;
89 br_fdb_put_hook = NULL; 89 br_fdb_put_hook = NULL;
90 90
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index bf7787395fe0..d9449df7cad5 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_device.c,v 1.6 2001/12/24 00:59:55 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
@@ -21,12 +19,6 @@
21#include <asm/uaccess.h> 19#include <asm/uaccess.h>
22#include "br_private.h" 20#include "br_private.h"
23 21
24static struct net_device_stats *br_dev_get_stats(struct net_device *dev)
25{
26 struct net_bridge *br = netdev_priv(dev);
27 return &br->statistics;
28}
29
30/* net device transmit always called with no BH (preempt_disabled) */ 22/* net device transmit always called with no BH (preempt_disabled) */
31int br_dev_xmit(struct sk_buff *skb, struct net_device *dev) 23int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
32{ 24{
@@ -34,8 +26,8 @@ int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
34 const unsigned char *dest = skb->data; 26 const unsigned char *dest = skb->data;
35 struct net_bridge_fdb_entry *dst; 27 struct net_bridge_fdb_entry *dst;
36 28
37 br->statistics.tx_packets++; 29 dev->stats.tx_packets++;
38 br->statistics.tx_bytes += skb->len; 30 dev->stats.tx_bytes += skb->len;
39 31
40 skb_reset_mac_header(skb); 32 skb_reset_mac_header(skb);
41 skb_pull(skb, ETH_HLEN); 33 skb_pull(skb, ETH_HLEN);
@@ -95,6 +87,7 @@ static int br_set_mac_address(struct net_device *dev, void *p)
95 spin_lock_bh(&br->lock); 87 spin_lock_bh(&br->lock);
96 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); 88 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
97 br_stp_change_bridge_id(br, addr->sa_data); 89 br_stp_change_bridge_id(br, addr->sa_data);
90 br->flags |= BR_SET_MAC_ADDR;
98 spin_unlock_bh(&br->lock); 91 spin_unlock_bh(&br->lock);
99 92
100 return 0; 93 return 0;
@@ -161,7 +154,6 @@ void br_dev_setup(struct net_device *dev)
161 ether_setup(dev); 154 ether_setup(dev);
162 155
163 dev->do_ioctl = br_dev_ioctl; 156 dev->do_ioctl = br_dev_ioctl;
164 dev->get_stats = br_dev_get_stats;
165 dev->hard_start_xmit = br_dev_xmit; 157 dev->hard_start_xmit = br_dev_xmit;
166 dev->open = br_dev_open; 158 dev->open = br_dev_open;
167 dev->set_multicast_list = br_dev_set_multicast_list; 159 dev->set_multicast_list = br_dev_set_multicast_list;
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 142060f02054..a48f5efdb6bf 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_fdb.c,v 1.6 2002/01/17 00:57:07 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index bdd7c35c3c7b..bdd9ccea17ce 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_forward.c,v 1.4 2001/08/14 22:05:57 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
@@ -91,7 +89,7 @@ void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
91/* called with rcu_read_lock */ 89/* called with rcu_read_lock */
92void br_forward(const struct net_bridge_port *to, struct sk_buff *skb) 90void br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
93{ 91{
94 if (should_deliver(to, skb)) { 92 if (!skb_warn_if_lro(skb) && should_deliver(to, skb)) {
95 __br_forward(to, skb); 93 __br_forward(to, skb);
96 return; 94 return;
97 } 95 }
@@ -115,7 +113,7 @@ static void br_flood(struct net_bridge *br, struct sk_buff *skb,
115 struct sk_buff *skb2; 113 struct sk_buff *skb2;
116 114
117 if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) { 115 if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) {
118 br->statistics.tx_dropped++; 116 br->dev->stats.tx_dropped++;
119 kfree_skb(skb); 117 kfree_skb(skb);
120 return; 118 return;
121 } 119 }
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index f38cc5317b88..a072ea5ca6f5 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_if.c,v 1.7 2001/12/24 00:59:55 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
@@ -375,6 +373,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
375 if (IS_ERR(p)) 373 if (IS_ERR(p))
376 return PTR_ERR(p); 374 return PTR_ERR(p);
377 375
376 err = dev_set_promiscuity(dev, 1);
377 if (err)
378 goto put_back;
379
378 err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj), 380 err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj),
379 SYSFS_BRIDGE_PORT_ATTR); 381 SYSFS_BRIDGE_PORT_ATTR);
380 if (err) 382 if (err)
@@ -389,7 +391,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
389 goto err2; 391 goto err2;
390 392
391 rcu_assign_pointer(dev->br_port, p); 393 rcu_assign_pointer(dev->br_port, p);
392 dev_set_promiscuity(dev, 1); 394 dev_disable_lro(dev);
393 395
394 list_add_rcu(&p->list, &br->port_list); 396 list_add_rcu(&p->list, &br->port_list);
395 397
@@ -413,12 +415,12 @@ err2:
413 br_fdb_delete_by_port(br, p, 1); 415 br_fdb_delete_by_port(br, p, 1);
414err1: 416err1:
415 kobject_del(&p->kobj); 417 kobject_del(&p->kobj);
416 goto put_back;
417err0: 418err0:
418 kobject_put(&p->kobj); 419 kobject_put(&p->kobj);
419 420 dev_set_promiscuity(dev, -1);
420put_back: 421put_back:
421 dev_put(dev); 422 dev_put(dev);
423 kfree(p);
422 return err; 424 return err;
423} 425}
424 426
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 255c00f60ce7..30b88777c3df 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_input.c,v 1.10 2001/12/24 04:50:20 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
@@ -24,13 +22,13 @@ const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
24 22
25static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb) 23static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb)
26{ 24{
27 struct net_device *indev; 25 struct net_device *indev, *brdev = br->dev;
28 26
29 br->statistics.rx_packets++; 27 brdev->stats.rx_packets++;
30 br->statistics.rx_bytes += skb->len; 28 brdev->stats.rx_bytes += skb->len;
31 29
32 indev = skb->dev; 30 indev = skb->dev;
33 skb->dev = br->dev; 31 skb->dev = brdev;
34 32
35 NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, 33 NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,
36 netif_receive_skb); 34 netif_receive_skb);
@@ -64,7 +62,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
64 dst = NULL; 62 dst = NULL;
65 63
66 if (is_multicast_ether_addr(dest)) { 64 if (is_multicast_ether_addr(dest)) {
67 br->statistics.multicast++; 65 br->dev->stats.multicast++;
68 skb2 = skb; 66 skb2 = skb;
69 } else if ((dst = __br_fdb_get(br, dest)) && dst->is_local) { 67 } else if ((dst = __br_fdb_get(br, dest)) && dst->is_local) {
70 skb2 = skb; 68 skb2 = skb;
@@ -136,14 +134,11 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
136 if (skb->protocol == htons(ETH_P_PAUSE)) 134 if (skb->protocol == htons(ETH_P_PAUSE))
137 goto drop; 135 goto drop;
138 136
139 /* Process STP BPDU's through normal netif_receive_skb() path */ 137 if (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
140 if (p->br->stp_enabled != BR_NO_STP) { 138 NULL, br_handle_local_finish))
141 if (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, 139 return NULL; /* frame consumed by filter */
142 NULL, br_handle_local_finish)) 140 else
143 return NULL; 141 return skb; /* continue processing */
144 else
145 return skb;
146 }
147 } 142 }
148 143
149 switch (p->state) { 144 switch (p->state) {
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c
index 0655a5f07f58..eeee218eed80 100644
--- a/net/bridge/br_ioctl.c
+++ b/net/bridge/br_ioctl.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_ioctl.c,v 1.4 2000/11/08 05:16:40 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 00644a544e3c..76340bdd052e 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_notify.c,v 1.2 2000/02/21 15:51:34 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
@@ -37,7 +35,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
37 struct net_bridge_port *p = dev->br_port; 35 struct net_bridge_port *p = dev->br_port;
38 struct net_bridge *br; 36 struct net_bridge *br;
39 37
40 if (dev_net(dev) != &init_net) 38 if (!net_eq(dev_net(dev), &init_net))
41 return NOTIFY_DONE; 39 return NOTIFY_DONE;
42 40
43 /* not a port of a bridge */ 41 /* not a port of a bridge */
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index c11b554fd109..815ed38925b2 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -4,8 +4,6 @@
4 * Authors: 4 * Authors:
5 * Lennert Buytenhek <buytenh@gnu.org> 5 * Lennert Buytenhek <buytenh@gnu.org>
6 * 6 *
7 * $Id: br_private.h,v 1.7 2001/12/24 00:59:55 davem Exp $
8 *
9 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
@@ -90,11 +88,12 @@ struct net_bridge
90 spinlock_t lock; 88 spinlock_t lock;
91 struct list_head port_list; 89 struct list_head port_list;
92 struct net_device *dev; 90 struct net_device *dev;
93 struct net_device_stats statistics;
94 spinlock_t hash_lock; 91 spinlock_t hash_lock;
95 struct hlist_head hash[BR_HASH_SIZE]; 92 struct hlist_head hash[BR_HASH_SIZE];
96 struct list_head age_list; 93 struct list_head age_list;
97 unsigned long feature_mask; 94 unsigned long feature_mask;
95 unsigned long flags;
96#define BR_SET_MAC_ADDR 0x00000001
98 97
99 /* STP */ 98 /* STP */
100 bridge_id designated_root; 99 bridge_id designated_root;
@@ -227,8 +226,9 @@ extern void br_stp_set_path_cost(struct net_bridge_port *p,
227extern ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id); 226extern ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id);
228 227
229/* br_stp_bpdu.c */ 228/* br_stp_bpdu.c */
230extern int br_stp_rcv(struct sk_buff *skb, struct net_device *dev, 229struct stp_proto;
231 struct packet_type *pt, struct net_device *orig_dev); 230extern void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
231 struct net_device *dev);
232 232
233/* br_stp_timer.c */ 233/* br_stp_timer.c */
234extern void br_stp_timer_init(struct net_bridge *br); 234extern void br_stp_timer_init(struct net_bridge *br);
diff --git a/net/bridge/br_private_stp.h b/net/bridge/br_private_stp.h
index e29f01ac1adf..8b650f7fbfa0 100644
--- a/net/bridge/br_private_stp.h
+++ b/net/bridge/br_private_stp.h
@@ -4,8 +4,6 @@
4 * Authors: 4 * Authors:
5 * Lennert Buytenhek <buytenh@gnu.org> 5 * Lennert Buytenhek <buytenh@gnu.org>
6 * 6 *
7 * $Id: br_private_stp.h,v 1.3 2001/02/05 06:03:47 davem Exp $
8 *
9 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index 9e96ffcd29a3..921bbe5cb94a 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_stp.c,v 1.4 2000/06/19 10:13:35 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index ddeb6e5d45d6..8b200f96f722 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_stp_bpdu.c,v 1.3 2001/11/10 02:35:25 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
@@ -20,6 +18,7 @@
20#include <net/net_namespace.h> 18#include <net/net_namespace.h>
21#include <net/llc.h> 19#include <net/llc.h>
22#include <net/llc_pdu.h> 20#include <net/llc_pdu.h>
21#include <net/stp.h>
23#include <asm/unaligned.h> 22#include <asm/unaligned.h>
24 23
25#include "br_private.h" 24#include "br_private.h"
@@ -133,26 +132,20 @@ void br_send_tcn_bpdu(struct net_bridge_port *p)
133 * 132 *
134 * NO locks, but rcu_read_lock (preempt_disabled) 133 * NO locks, but rcu_read_lock (preempt_disabled)
135 */ 134 */
136int br_stp_rcv(struct sk_buff *skb, struct net_device *dev, 135void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
137 struct packet_type *pt, struct net_device *orig_dev) 136 struct net_device *dev)
138{ 137{
139 const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
140 const unsigned char *dest = eth_hdr(skb)->h_dest; 138 const unsigned char *dest = eth_hdr(skb)->h_dest;
141 struct net_bridge_port *p = rcu_dereference(dev->br_port); 139 struct net_bridge_port *p = rcu_dereference(dev->br_port);
142 struct net_bridge *br; 140 struct net_bridge *br;
143 const unsigned char *buf; 141 const unsigned char *buf;
144 142
145 if (dev_net(dev) != &init_net) 143 if (!net_eq(dev_net(dev), &init_net))
146 goto err; 144 goto err;
147 145
148 if (!p) 146 if (!p)
149 goto err; 147 goto err;
150 148
151 if (pdu->ssap != LLC_SAP_BSPAN
152 || pdu->dsap != LLC_SAP_BSPAN
153 || pdu->ctrl_1 != LLC_PDU_TYPE_U)
154 goto err;
155
156 if (!pskb_may_pull(skb, 4)) 149 if (!pskb_may_pull(skb, 4))
157 goto err; 150 goto err;
158 151
@@ -226,5 +219,4 @@ int br_stp_rcv(struct sk_buff *skb, struct net_device *dev,
226 spin_unlock(&br->lock); 219 spin_unlock(&br->lock);
227 err: 220 err:
228 kfree_skb(skb); 221 kfree_skb(skb);
229 return 0;
230} 222}
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 1a430eccec9b..9a52ac5b4525 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_stp_if.c,v 1.4 2001/04/14 21:14:39 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
@@ -216,6 +214,10 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br)
216 const unsigned char *addr = br_mac_zero; 214 const unsigned char *addr = br_mac_zero;
217 struct net_bridge_port *p; 215 struct net_bridge_port *p;
218 216
217 /* user has chosen a value so keep it */
218 if (br->flags & BR_SET_MAC_ADDR)
219 return;
220
219 list_for_each_entry(p, &br->port_list, list) { 221 list_for_each_entry(p, &br->port_list, list) {
220 if (addr == br_mac_zero || 222 if (addr == br_mac_zero ||
221 memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0) 223 memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c
index 77f5255e6915..772a140bfdf0 100644
--- a/net/bridge/br_stp_timer.c
+++ b/net/bridge/br_stp_timer.c
@@ -5,8 +5,6 @@
5 * Authors: 5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org> 6 * Lennert Buytenhek <buytenh@gnu.org>
7 * 7 *
8 * $Id: br_stp_timer.c,v 1.3 2000/05/05 02:17:17 davem Exp $
9 *
10 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index 7beeefa0f9c0..909479794999 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -83,6 +83,15 @@ config BRIDGE_EBT_IP
83 83
84 To compile it as a module, choose M here. If unsure, say N. 84 To compile it as a module, choose M here. If unsure, say N.
85 85
86config BRIDGE_EBT_IP6
87 tristate "ebt: IP6 filter support"
88 depends on BRIDGE_NF_EBTABLES && IPV6
89 help
90 This option adds the IP6 match, which allows basic IPV6 header field
91 filtering.
92
93 To compile it as a module, choose M here. If unsure, say N.
94
86config BRIDGE_EBT_LIMIT 95config BRIDGE_EBT_LIMIT
87 tristate "ebt: limit match support" 96 tristate "ebt: limit match support"
88 depends on BRIDGE_NF_EBTABLES 97 depends on BRIDGE_NF_EBTABLES
@@ -221,7 +230,7 @@ config BRIDGE_EBT_NFLOG
221 either the old LOG target, the old ULOG target or nfnetlink_log 230 either the old LOG target, the old ULOG target or nfnetlink_log
222 as backend. 231 as backend.
223 232
224 This option adds the ulog watcher, that you can use in any rule 233 This option adds the nflog watcher, that you can use in any rule
225 in any ebtables table. 234 in any ebtables table.
226 235
227 To compile it as a module, choose M here. If unsure, say N. 236 To compile it as a module, choose M here. If unsure, say N.
diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile
index 83715d73a503..0718699540b0 100644
--- a/net/bridge/netfilter/Makefile
+++ b/net/bridge/netfilter/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_BRIDGE_EBT_802_3) += ebt_802_3.o
14obj-$(CONFIG_BRIDGE_EBT_AMONG) += ebt_among.o 14obj-$(CONFIG_BRIDGE_EBT_AMONG) += ebt_among.o
15obj-$(CONFIG_BRIDGE_EBT_ARP) += ebt_arp.o 15obj-$(CONFIG_BRIDGE_EBT_ARP) += ebt_arp.o
16obj-$(CONFIG_BRIDGE_EBT_IP) += ebt_ip.o 16obj-$(CONFIG_BRIDGE_EBT_IP) += ebt_ip.o
17obj-$(CONFIG_BRIDGE_EBT_IP6) += ebt_ip6.o
17obj-$(CONFIG_BRIDGE_EBT_LIMIT) += ebt_limit.o 18obj-$(CONFIG_BRIDGE_EBT_LIMIT) += ebt_limit.o
18obj-$(CONFIG_BRIDGE_EBT_MARK) += ebt_mark_m.o 19obj-$(CONFIG_BRIDGE_EBT_MARK) += ebt_mark_m.o
19obj-$(CONFIG_BRIDGE_EBT_PKTTYPE) += ebt_pkttype.o 20obj-$(CONFIG_BRIDGE_EBT_PKTTYPE) += ebt_pkttype.o
diff --git a/net/bridge/netfilter/ebt_ip6.c b/net/bridge/netfilter/ebt_ip6.c
new file mode 100644
index 000000000000..36efb3a75249
--- /dev/null
+++ b/net/bridge/netfilter/ebt_ip6.c
@@ -0,0 +1,144 @@
1/*
2 * ebt_ip6
3 *
4 * Authors:
5 * Manohar Castelino <manohar.r.castelino@intel.com>
6 * Kuo-Lang Tseng <kuo-lang.tseng@intel.com>
7 * Jan Engelhardt <jengelh@computergmbh.de>
8 *
9 * Summary:
10 * This is just a modification of the IPv4 code written by
11 * Bart De Schuymer <bdschuym@pandora.be>
12 * with the changes required to support IPv6
13 *
14 * Jan, 2008
15 */
16
17#include <linux/netfilter_bridge/ebtables.h>
18#include <linux/netfilter_bridge/ebt_ip6.h>
19#include <linux/ipv6.h>
20#include <net/ipv6.h>
21#include <linux/in.h>
22#include <linux/module.h>
23#include <net/dsfield.h>
24
25struct tcpudphdr {
26 __be16 src;
27 __be16 dst;
28};
29
30static int ebt_filter_ip6(const struct sk_buff *skb,
31 const struct net_device *in,
32 const struct net_device *out, const void *data,
33 unsigned int datalen)
34{
35 const struct ebt_ip6_info *info = (struct ebt_ip6_info *)data;
36 const struct ipv6hdr *ih6;
37 struct ipv6hdr _ip6h;
38 const struct tcpudphdr *pptr;
39 struct tcpudphdr _ports;
40 struct in6_addr tmp_addr;
41 int i;
42
43 ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h);
44 if (ih6 == NULL)
45 return EBT_NOMATCH;
46 if (info->bitmask & EBT_IP6_TCLASS &&
47 FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS))
48 return EBT_NOMATCH;
49 for (i = 0; i < 4; i++)
50 tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] &
51 info->smsk.in6_u.u6_addr32[i];
52 if (info->bitmask & EBT_IP6_SOURCE &&
53 FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0),
54 EBT_IP6_SOURCE))
55 return EBT_NOMATCH;
56 for (i = 0; i < 4; i++)
57 tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] &
58 info->dmsk.in6_u.u6_addr32[i];
59 if (info->bitmask & EBT_IP6_DEST &&
60 FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), EBT_IP6_DEST))
61 return EBT_NOMATCH;
62 if (info->bitmask & EBT_IP6_PROTO) {
63 uint8_t nexthdr = ih6->nexthdr;
64 int offset_ph;
65
66 offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr);
67 if (offset_ph == -1)
68 return EBT_NOMATCH;
69 if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO))
70 return EBT_NOMATCH;
71 if (!(info->bitmask & EBT_IP6_DPORT) &&
72 !(info->bitmask & EBT_IP6_SPORT))
73 return EBT_MATCH;
74 pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports),
75 &_ports);
76 if (pptr == NULL)
77 return EBT_NOMATCH;
78 if (info->bitmask & EBT_IP6_DPORT) {
79 u32 dst = ntohs(pptr->dst);
80 if (FWINV(dst < info->dport[0] ||
81 dst > info->dport[1], EBT_IP6_DPORT))
82 return EBT_NOMATCH;
83 }
84 if (info->bitmask & EBT_IP6_SPORT) {
85 u32 src = ntohs(pptr->src);
86 if (FWINV(src < info->sport[0] ||
87 src > info->sport[1], EBT_IP6_SPORT))
88 return EBT_NOMATCH;
89 }
90 return EBT_MATCH;
91 }
92 return EBT_MATCH;
93}
94
95static int ebt_ip6_check(const char *tablename, unsigned int hookmask,
96 const struct ebt_entry *e, void *data, unsigned int datalen)
97{
98 struct ebt_ip6_info *info = (struct ebt_ip6_info *)data;
99
100 if (datalen != EBT_ALIGN(sizeof(struct ebt_ip6_info)))
101 return -EINVAL;
102 if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO)
103 return -EINVAL;
104 if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK)
105 return -EINVAL;
106 if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) {
107 if (info->invflags & EBT_IP6_PROTO)
108 return -EINVAL;
109 if (info->protocol != IPPROTO_TCP &&
110 info->protocol != IPPROTO_UDP &&
111 info->protocol != IPPROTO_UDPLITE &&
112 info->protocol != IPPROTO_SCTP &&
113 info->protocol != IPPROTO_DCCP)
114 return -EINVAL;
115 }
116 if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1])
117 return -EINVAL;
118 if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1])
119 return -EINVAL;
120 return 0;
121}
122
123static struct ebt_match filter_ip6 =
124{
125 .name = EBT_IP6_MATCH,
126 .match = ebt_filter_ip6,
127 .check = ebt_ip6_check,
128 .me = THIS_MODULE,
129};
130
131static int __init ebt_ip6_init(void)
132{
133 return ebt_register_match(&filter_ip6);
134}
135
136static void __exit ebt_ip6_fini(void)
137{
138 ebt_unregister_match(&filter_ip6);
139}
140
141module_init(ebt_ip6_init);
142module_exit(ebt_ip6_fini);
143MODULE_DESCRIPTION("Ebtables: IPv6 protocol packet match");
144MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 0b209e4aad0a..2f430d4ae911 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -18,6 +18,9 @@
18#include <linux/if_arp.h> 18#include <linux/if_arp.h>
19#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <net/netfilter/nf_log.h> 20#include <net/netfilter/nf_log.h>
21#include <linux/ipv6.h>
22#include <net/ipv6.h>
23#include <linux/in6.h>
21 24
22static DEFINE_SPINLOCK(ebt_log_lock); 25static DEFINE_SPINLOCK(ebt_log_lock);
23 26
@@ -58,6 +61,27 @@ static void print_MAC(const unsigned char *p)
58 printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':'); 61 printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':');
59} 62}
60 63
64static void
65print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
66{
67 if (protocol == IPPROTO_TCP ||
68 protocol == IPPROTO_UDP ||
69 protocol == IPPROTO_UDPLITE ||
70 protocol == IPPROTO_SCTP ||
71 protocol == IPPROTO_DCCP) {
72 const struct tcpudphdr *pptr;
73 struct tcpudphdr _ports;
74
75 pptr = skb_header_pointer(skb, offset,
76 sizeof(_ports), &_ports);
77 if (pptr == NULL) {
78 printk(" INCOMPLETE TCP/UDP header");
79 return;
80 }
81 printk(" SPT=%u DPT=%u", ntohs(pptr->src), ntohs(pptr->dst));
82 }
83}
84
61#define myNIPQUAD(a) a[0], a[1], a[2], a[3] 85#define myNIPQUAD(a) a[0], a[1], a[2], a[3]
62static void 86static void
63ebt_log_packet(unsigned int pf, unsigned int hooknum, 87ebt_log_packet(unsigned int pf, unsigned int hooknum,
@@ -95,25 +119,35 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
95 printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP " 119 printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP "
96 "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr), 120 "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr),
97 NIPQUAD(ih->daddr), ih->tos, ih->protocol); 121 NIPQUAD(ih->daddr), ih->tos, ih->protocol);
98 if (ih->protocol == IPPROTO_TCP || 122 print_ports(skb, ih->protocol, ih->ihl*4);
99 ih->protocol == IPPROTO_UDP || 123 goto out;
100 ih->protocol == IPPROTO_UDPLITE || 124 }
101 ih->protocol == IPPROTO_SCTP || 125
102 ih->protocol == IPPROTO_DCCP) { 126#if defined(CONFIG_BRIDGE_EBT_IP6) || defined(CONFIG_BRIDGE_EBT_IP6_MODULE)
103 const struct tcpudphdr *pptr; 127 if ((bitmask & EBT_LOG_IP6) && eth_hdr(skb)->h_proto ==
104 struct tcpudphdr _ports; 128 htons(ETH_P_IPV6)) {
105 129 const struct ipv6hdr *ih;
106 pptr = skb_header_pointer(skb, ih->ihl*4, 130 struct ipv6hdr _iph;
107 sizeof(_ports), &_ports); 131 uint8_t nexthdr;
108 if (pptr == NULL) { 132 int offset_ph;
109 printk(" INCOMPLETE TCP/UDP header"); 133
110 goto out; 134 ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
111 } 135 if (ih == NULL) {
112 printk(" SPT=%u DPT=%u", ntohs(pptr->src), 136 printk(" INCOMPLETE IPv6 header");
113 ntohs(pptr->dst)); 137 goto out;
114 } 138 }
139 printk(" IPv6 SRC=%x:%x:%x:%x:%x:%x:%x:%x "
140 "IPv6 DST=%x:%x:%x:%x:%x:%x:%x:%x, IPv6 "
141 "priority=0x%01X, Next Header=%d", NIP6(ih->saddr),
142 NIP6(ih->daddr), ih->priority, ih->nexthdr);
143 nexthdr = ih->nexthdr;
144 offset_ph = ipv6_skip_exthdr(skb, sizeof(_iph), &nexthdr);
145 if (offset_ph == -1)
146 goto out;
147 print_ports(skb, nexthdr, offset_ph);
115 goto out; 148 goto out;
116 } 149 }
150#endif
117 151
118 if ((bitmask & EBT_LOG_ARP) && 152 if ((bitmask & EBT_LOG_ARP) &&
119 ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) || 153 ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) ||