aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-06-15 11:31:06 -0400
committerPatrick McHardy <kaber@trash.net>2010-06-15 11:31:06 -0400
commitf9181f4ffc71d7b7dd1906c9a11d51d6659220ae (patch)
tree194f22e8216a1b9ee2c0dd019142202d73a7dc87 /net/bridge
parent0902b469bd25065aa0688c3cee6f11744c817e7c (diff)
parent1ab6c163dee279559e3a62d774af7e4c4c9b4c67 (diff)
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts: include/net/netfilter/xt_rateest.h net/bridge/br_netfilter.c net/netfilter/nf_conntrack_core.c Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br.c2
-rw-r--r--net/bridge/br_device.c2
-rw-r--r--net/bridge/br_if.c8
-rw-r--r--net/bridge/br_input.c12
-rw-r--r--net/bridge/br_netfilter.c16
-rw-r--r--net/bridge/br_private.h3
6 files changed, 27 insertions, 16 deletions
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 76357b547752..c8436fa31344 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -63,7 +63,6 @@ static int __init br_init(void)
63 goto err_out4; 63 goto err_out4;
64 64
65 brioctl_set(br_ioctl_deviceless_stub); 65 brioctl_set(br_ioctl_deviceless_stub);
66 br_handle_frame_hook = br_handle_frame;
67 66
68#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) 67#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
69 br_fdb_test_addr_hook = br_fdb_test_addr; 68 br_fdb_test_addr_hook = br_fdb_test_addr;
@@ -100,7 +99,6 @@ static void __exit br_deinit(void)
100 br_fdb_test_addr_hook = NULL; 99 br_fdb_test_addr_hook = NULL;
101#endif 100#endif
102 101
103 br_handle_frame_hook = NULL;
104 br_fdb_fini(); 102 br_fdb_fini();
105} 103}
106 104
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index eedf2c94820e..b898364beaf5 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -127,7 +127,7 @@ static int br_change_mtu(struct net_device *dev, int new_mtu)
127 127
128#ifdef CONFIG_BRIDGE_NETFILTER 128#ifdef CONFIG_BRIDGE_NETFILTER
129 /* remember the MTU in the rtable for PMTU */ 129 /* remember the MTU in the rtable for PMTU */
130 br->fake_rtable.u.dst.metrics[RTAX_MTU - 1] = new_mtu; 130 br->fake_rtable.dst.metrics[RTAX_MTU - 1] = new_mtu;
131#endif 131#endif
132 132
133 return 0; 133 return 0;
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 18b245e2c00e..d9242342837e 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -147,6 +147,7 @@ static void del_nbp(struct net_bridge_port *p)
147 147
148 list_del_rcu(&p->list); 148 list_del_rcu(&p->list);
149 149
150 netdev_rx_handler_unregister(dev);
150 rcu_assign_pointer(dev->br_port, NULL); 151 rcu_assign_pointer(dev->br_port, NULL);
151 152
152 br_multicast_del_port(p); 153 br_multicast_del_port(p);
@@ -429,6 +430,11 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
429 goto err2; 430 goto err2;
430 431
431 rcu_assign_pointer(dev->br_port, p); 432 rcu_assign_pointer(dev->br_port, p);
433
434 err = netdev_rx_handler_register(dev, br_handle_frame);
435 if (err)
436 goto err3;
437
432 dev_disable_lro(dev); 438 dev_disable_lro(dev);
433 439
434 list_add_rcu(&p->list, &br->port_list); 440 list_add_rcu(&p->list, &br->port_list);
@@ -451,6 +457,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
451 br_netpoll_enable(br, dev); 457 br_netpoll_enable(br, dev);
452 458
453 return 0; 459 return 0;
460err3:
461 rcu_assign_pointer(dev->br_port, NULL);
454err2: 462err2:
455 br_fdb_delete_by_port(br, p, 1); 463 br_fdb_delete_by_port(br, p, 1);
456err1: 464err1:
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index d36e700f7a26..99647d8f95c8 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -131,15 +131,19 @@ static inline int is_link_local(const unsigned char *dest)
131} 131}
132 132
133/* 133/*
134 * Called via br_handle_frame_hook.
135 * Return NULL if skb is handled 134 * Return NULL if skb is handled
136 * note: already called with rcu_read_lock (preempt_disabled) 135 * note: already called with rcu_read_lock (preempt_disabled) from
136 * netif_receive_skb
137 */ 137 */
138struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb) 138struct sk_buff *br_handle_frame(struct sk_buff *skb)
139{ 139{
140 struct net_bridge_port *p;
140 const unsigned char *dest = eth_hdr(skb)->h_dest; 141 const unsigned char *dest = eth_hdr(skb)->h_dest;
141 int (*rhook)(struct sk_buff *skb); 142 int (*rhook)(struct sk_buff *skb);
142 143
144 if (skb->pkt_type == PACKET_LOOPBACK)
145 return skb;
146
143 if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) 147 if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
144 goto drop; 148 goto drop;
145 149
@@ -147,6 +151,8 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
147 if (!skb) 151 if (!skb)
148 return NULL; 152 return NULL;
149 153
154 p = rcu_dereference(skb->dev->br_port);
155
150 if (unlikely(is_link_local(dest))) { 156 if (unlikely(is_link_local(dest))) {
151 /* Pause frames shouldn't be passed up by driver anyway */ 157 /* Pause frames shouldn't be passed up by driver anyway */
152 if (skb->protocol == htons(ETH_P_PAUSE)) 158 if (skb->protocol == htons(ETH_P_PAUSE))
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index cbea5af24ce6..6bb6f7c9e6e1 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -117,12 +117,12 @@ void br_netfilter_rtable_init(struct net_bridge *br)
117{ 117{
118 struct rtable *rt = &br->fake_rtable; 118 struct rtable *rt = &br->fake_rtable;
119 119
120 atomic_set(&rt->u.dst.__refcnt, 1); 120 atomic_set(&rt->dst.__refcnt, 1);
121 rt->u.dst.dev = br->dev; 121 rt->dst.dev = br->dev;
122 rt->u.dst.path = &rt->u.dst; 122 rt->dst.path = &rt->dst;
123 rt->u.dst.metrics[RTAX_MTU - 1] = 1500; 123 rt->dst.metrics[RTAX_MTU - 1] = 1500;
124 rt->u.dst.flags = DST_NOXFRM; 124 rt->dst.flags = DST_NOXFRM;
125 rt->u.dst.ops = &fake_dst_ops; 125 rt->dst.ops = &fake_dst_ops;
126} 126}
127 127
128static inline struct rtable *bridge_parent_rtable(const struct net_device *dev) 128static inline struct rtable *bridge_parent_rtable(const struct net_device *dev)
@@ -244,7 +244,7 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
244 kfree_skb(skb); 244 kfree_skb(skb);
245 return 0; 245 return 0;
246 } 246 }
247 skb_dst_set_noref(skb, &rt->u.dst); 247 skb_dst_set_noref(skb, &rt->dst);
248 248
249 skb->dev = nf_bridge->physindev; 249 skb->dev = nf_bridge->physindev;
250 nf_bridge_update_protocol(skb); 250 nf_bridge_update_protocol(skb);
@@ -395,7 +395,7 @@ bridged_dnat:
395 kfree_skb(skb); 395 kfree_skb(skb);
396 return 0; 396 return 0;
397 } 397 }
398 skb_dst_set_noref(skb, &rt->u.dst); 398 skb_dst_set_noref(skb, &rt->dst);
399 } 399 }
400 400
401 skb->dev = nf_bridge->physindev; 401 skb->dev = nf_bridge->physindev;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 0f4a74bc6a9b..c83519b555bb 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -331,8 +331,7 @@ extern void br_features_recompute(struct net_bridge *br);
331 331
332/* br_input.c */ 332/* br_input.c */
333extern int br_handle_frame_finish(struct sk_buff *skb); 333extern int br_handle_frame_finish(struct sk_buff *skb);
334extern struct sk_buff *br_handle_frame(struct net_bridge_port *p, 334extern struct sk_buff *br_handle_frame(struct sk_buff *skb);
335 struct sk_buff *skb);
336 335
337/* br_ioctl.c */ 336/* br_ioctl.c */
338extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 337extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);