diff options
author | Patrick McHardy <kaber@trash.net> | 2010-06-15 11:31:06 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-06-15 11:31:06 -0400 |
commit | f9181f4ffc71d7b7dd1906c9a11d51d6659220ae (patch) | |
tree | 194f22e8216a1b9ee2c0dd019142202d73a7dc87 /net/bridge | |
parent | 0902b469bd25065aa0688c3cee6f11744c817e7c (diff) | |
parent | 1ab6c163dee279559e3a62d774af7e4c4c9b4c67 (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.c | 2 | ||||
-rw-r--r-- | net/bridge/br_device.c | 2 | ||||
-rw-r--r-- | net/bridge/br_if.c | 8 | ||||
-rw-r--r-- | net/bridge/br_input.c | 12 | ||||
-rw-r--r-- | net/bridge/br_netfilter.c | 16 | ||||
-rw-r--r-- | net/bridge/br_private.h | 3 |
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; |
460 | err3: | ||
461 | rcu_assign_pointer(dev->br_port, NULL); | ||
454 | err2: | 462 | err2: |
455 | br_fdb_delete_by_port(br, p, 1); | 463 | br_fdb_delete_by_port(br, p, 1); |
456 | err1: | 464 | err1: |
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 | */ |
138 | struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb) | 138 | struct 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 | ||
128 | static inline struct rtable *bridge_parent_rtable(const struct net_device *dev) | 128 | static 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 */ |
333 | extern int br_handle_frame_finish(struct sk_buff *skb); | 333 | extern int br_handle_frame_finish(struct sk_buff *skb); |
334 | extern struct sk_buff *br_handle_frame(struct net_bridge_port *p, | 334 | extern 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 */ |
338 | extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 337 | extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |