aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter_bridge.h5
-rw-r--r--include/net/neighbour.h14
-rw-r--r--net/bridge/br_netfilter.c90
3 files changed, 83 insertions, 26 deletions
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
index ffab6c423a57..ea0e44b90432 100644
--- a/include/linux/netfilter_bridge.h
+++ b/include/linux/netfilter_bridge.h
@@ -43,7 +43,8 @@ enum nf_br_hook_priorities {
43#define BRNF_BRIDGED_DNAT 0x02 43#define BRNF_BRIDGED_DNAT 0x02
44#define BRNF_BRIDGED 0x04 44#define BRNF_BRIDGED 0x04
45#define BRNF_NF_BRIDGE_PREROUTING 0x08 45#define BRNF_NF_BRIDGE_PREROUTING 0x08
46 46#define BRNF_8021Q 0x10
47#define BRNF_PPPoE 0x20
47 48
48/* Only used in br_forward.c */ 49/* Only used in br_forward.c */
49extern int nf_bridge_copy_header(struct sk_buff *skb); 50extern int nf_bridge_copy_header(struct sk_buff *skb);
@@ -75,6 +76,8 @@ static inline int br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
75 76
76 skb_pull(skb, ETH_HLEN); 77 skb_pull(skb, ETH_HLEN);
77 nf_bridge->mask ^= BRNF_BRIDGED_DNAT; 78 nf_bridge->mask ^= BRNF_BRIDGED_DNAT;
79 skb_copy_to_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN),
80 skb->nf_bridge->data, ETH_HLEN-ETH_ALEN);
78 skb->dev = nf_bridge->physindev; 81 skb->dev = nf_bridge->physindev;
79 return br_handle_frame_finish(skb); 82 return br_handle_frame_finish(skb);
80} 83}
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index da1d58be31b7..eb21340a573b 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -299,6 +299,20 @@ static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
299 return 0; 299 return 0;
300} 300}
301 301
302#ifdef CONFIG_BRIDGE_NETFILTER
303static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
304{
305 unsigned seq, hh_alen;
306
307 do {
308 seq = read_seqbegin(&hh->hh_lock);
309 hh_alen = HH_DATA_ALIGN(ETH_HLEN);
310 memcpy(skb->data - hh_alen, hh->hh_data, ETH_ALEN + hh_alen - ETH_HLEN);
311 } while (read_seqretry(&hh->hh_lock, seq));
312 return 0;
313}
314#endif
315
302static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb) 316static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb)
303{ 317{
304 unsigned seq; 318 unsigned seq;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 05dc6304992c..b7e405dc9d1c 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -196,15 +196,24 @@ static inline void nf_bridge_save_header(struct sk_buff *skb)
196 skb->nf_bridge->data, header_size); 196 skb->nf_bridge->data, header_size);
197} 197}
198 198
199/* 199static inline void nf_bridge_update_protocol(struct sk_buff *skb)
200 * When forwarding bridge frames, we save a copy of the original 200{
201 * header before processing. 201 if (skb->nf_bridge->mask & BRNF_8021Q)
202 skb->protocol = htons(ETH_P_8021Q);
203 else if (skb->nf_bridge->mask & BRNF_PPPoE)
204 skb->protocol = htons(ETH_P_PPP_SES);
205}
206
207/* Fill in the header for fragmented IP packets handled by
208 * the IPv4 connection tracking code.
202 */ 209 */
203int nf_bridge_copy_header(struct sk_buff *skb) 210int nf_bridge_copy_header(struct sk_buff *skb)
204{ 211{
205 int err; 212 int err;
206 int header_size = ETH_HLEN + nf_bridge_encap_header_len(skb); 213 unsigned int header_size;
207 214
215 nf_bridge_update_protocol(skb);
216 header_size = ETH_HLEN + nf_bridge_encap_header_len(skb);
208 err = skb_cow_head(skb, header_size); 217 err = skb_cow_head(skb, header_size);
209 if (err) 218 if (err)
210 return err; 219 return err;
@@ -238,6 +247,7 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
238 skb_dst_set(skb, &rt->u.dst); 247 skb_dst_set(skb, &rt->u.dst);
239 248
240 skb->dev = nf_bridge->physindev; 249 skb->dev = nf_bridge->physindev;
250 nf_bridge_update_protocol(skb);
241 nf_bridge_push_encap_header(skb); 251 nf_bridge_push_encap_header(skb);
242 NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, 252 NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
243 br_handle_frame_finish, 1); 253 br_handle_frame_finish, 1);
@@ -245,6 +255,38 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
245 return 0; 255 return 0;
246} 256}
247 257
258/* Obtain the correct destination MAC address, while preserving the original
259 * source MAC address. If we already know this address, we just copy it. If we
260 * don't, we use the neighbour framework to find out. In both cases, we make
261 * sure that br_handle_frame_finish() is called afterwards.
262 */
263static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
264{
265 struct nf_bridge_info *nf_bridge = skb->nf_bridge;
266 struct dst_entry *dst;
267
268 skb->dev = bridge_parent(skb->dev);
269 if (!skb->dev)
270 goto free_skb;
271 dst = skb_dst(skb);
272 if (dst->hh) {
273 neigh_hh_bridge(dst->hh, skb);
274 skb->dev = nf_bridge->physindev;
275 return br_handle_frame_finish(skb);
276 } else if (dst->neighbour) {
277 /* the neighbour function below overwrites the complete
278 * MAC header, so we save the Ethernet source address and
279 * protocol number. */
280 skb_copy_from_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN), skb->nf_bridge->data, ETH_HLEN-ETH_ALEN);
281 /* tell br_dev_xmit to continue with forwarding */
282 nf_bridge->mask |= BRNF_BRIDGED_DNAT;
283 return dst->neighbour->output(skb);
284 }
285free_skb:
286 kfree_skb(skb);
287 return 0;
288}
289
248/* This requires some explaining. If DNAT has taken place, 290/* This requires some explaining. If DNAT has taken place,
249 * we will need to fix up the destination Ethernet address. 291 * we will need to fix up the destination Ethernet address.
250 * 292 *
@@ -283,25 +325,6 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
283 * device, we proceed as if ip_route_input() succeeded. If it differs from the 325 * device, we proceed as if ip_route_input() succeeded. If it differs from the
284 * logical bridge port or if ip_route_output_key() fails we drop the packet. 326 * logical bridge port or if ip_route_output_key() fails we drop the packet.
285 */ 327 */
286
287static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
288{
289 skb->dev = bridge_parent(skb->dev);
290 if (skb->dev) {
291 struct dst_entry *dst = skb_dst(skb);
292
293 nf_bridge_pull_encap_header(skb);
294 skb->nf_bridge->mask |= BRNF_BRIDGED_DNAT;
295
296 if (dst->hh)
297 return neigh_hh_output(dst->hh, skb);
298 else if (dst->neighbour)
299 return dst->neighbour->output(skb);
300 }
301 kfree_skb(skb);
302 return 0;
303}
304
305static int br_nf_pre_routing_finish(struct sk_buff *skb) 328static int br_nf_pre_routing_finish(struct sk_buff *skb)
306{ 329{
307 struct net_device *dev = skb->dev; 330 struct net_device *dev = skb->dev;
@@ -354,6 +377,7 @@ free_skb:
354 if (skb_dst(skb)->dev == dev) { 377 if (skb_dst(skb)->dev == dev) {
355bridged_dnat: 378bridged_dnat:
356 skb->dev = nf_bridge->physindev; 379 skb->dev = nf_bridge->physindev;
380 nf_bridge_update_protocol(skb);
357 nf_bridge_push_encap_header(skb); 381 nf_bridge_push_encap_header(skb);
358 NF_HOOK_THRESH(NFPROTO_BRIDGE, 382 NF_HOOK_THRESH(NFPROTO_BRIDGE,
359 NF_BR_PRE_ROUTING, 383 NF_BR_PRE_ROUTING,
@@ -376,6 +400,7 @@ bridged_dnat:
376 } 400 }
377 401
378 skb->dev = nf_bridge->physindev; 402 skb->dev = nf_bridge->physindev;
403 nf_bridge_update_protocol(skb);
379 nf_bridge_push_encap_header(skb); 404 nf_bridge_push_encap_header(skb);
380 NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, 405 NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
381 br_handle_frame_finish, 1); 406 br_handle_frame_finish, 1);
@@ -396,6 +421,10 @@ static struct net_device *setup_pre_routing(struct sk_buff *skb)
396 nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING; 421 nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
397 nf_bridge->physindev = skb->dev; 422 nf_bridge->physindev = skb->dev;
398 skb->dev = bridge_parent(skb->dev); 423 skb->dev = bridge_parent(skb->dev);
424 if (skb->protocol == htons(ETH_P_8021Q))
425 nf_bridge->mask |= BRNF_8021Q;
426 else if (skb->protocol == htons(ETH_P_PPP_SES))
427 nf_bridge->mask |= BRNF_PPPoE;
399 428
400 return skb->dev; 429 return skb->dev;
401} 430}
@@ -494,6 +523,7 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
494 if (!setup_pre_routing(skb)) 523 if (!setup_pre_routing(skb))
495 return NF_DROP; 524 return NF_DROP;
496 525
526 skb->protocol = htons(ETH_P_IPV6);
497 NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, 527 NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
498 br_nf_pre_routing_finish_ipv6); 528 br_nf_pre_routing_finish_ipv6);
499 529
@@ -566,6 +596,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
566 if (!setup_pre_routing(skb)) 596 if (!setup_pre_routing(skb))
567 return NF_DROP; 597 return NF_DROP;
568 store_orig_dstaddr(skb); 598 store_orig_dstaddr(skb);
599 skb->protocol = htons(ETH_P_IP);
569 600
570 NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, 601 NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
571 br_nf_pre_routing_finish); 602 br_nf_pre_routing_finish);
@@ -614,7 +645,9 @@ static int br_nf_forward_finish(struct sk_buff *skb)
614 } else { 645 } else {
615 in = *((struct net_device **)(skb->cb)); 646 in = *((struct net_device **)(skb->cb));
616 } 647 }
648 nf_bridge_update_protocol(skb);
617 nf_bridge_push_encap_header(skb); 649 nf_bridge_push_encap_header(skb);
650
618 NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, in, 651 NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, in,
619 skb->dev, br_forward_finish, 1); 652 skb->dev, br_forward_finish, 1);
620 return 0; 653 return 0;
@@ -666,6 +699,10 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
666 /* The physdev module checks on this */ 699 /* The physdev module checks on this */
667 nf_bridge->mask |= BRNF_BRIDGED; 700 nf_bridge->mask |= BRNF_BRIDGED;
668 nf_bridge->physoutdev = skb->dev; 701 nf_bridge->physoutdev = skb->dev;
702 if (pf == PF_INET)
703 skb->protocol = htons(ETH_P_IP);
704 else
705 skb->protocol = htons(ETH_P_IPV6);
669 706
670 NF_HOOK(pf, NF_INET_FORWARD, skb, bridge_parent(in), parent, 707 NF_HOOK(pf, NF_INET_FORWARD, skb, bridge_parent(in), parent,
671 br_nf_forward_finish); 708 br_nf_forward_finish);
@@ -706,8 +743,7 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb,
706#if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE) 743#if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE)
707static int br_nf_dev_queue_xmit(struct sk_buff *skb) 744static int br_nf_dev_queue_xmit(struct sk_buff *skb)
708{ 745{
709 if (skb->nfct != NULL && 746 if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) &&
710 (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb)) &&
711 skb->len > skb->dev->mtu && 747 skb->len > skb->dev->mtu &&
712 !skb_is_gso(skb)) 748 !skb_is_gso(skb))
713 return ip_fragment(skb, br_dev_queue_push_xmit); 749 return ip_fragment(skb, br_dev_queue_push_xmit);
@@ -755,6 +791,10 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
755 791
756 nf_bridge_pull_encap_header(skb); 792 nf_bridge_pull_encap_header(skb);
757 nf_bridge_save_header(skb); 793 nf_bridge_save_header(skb);
794 if (pf == PF_INET)
795 skb->protocol = htons(ETH_P_IP);
796 else
797 skb->protocol = htons(ETH_P_IPV6);
758 798
759 NF_HOOK(pf, NF_INET_POST_ROUTING, skb, NULL, realoutdev, 799 NF_HOOK(pf, NF_INET_POST_ROUTING, skb, NULL, realoutdev,
760 br_nf_dev_queue_xmit); 800 br_nf_dev_queue_xmit);