diff options
| -rw-r--r-- | include/linux/netfilter_bridge.h | 17 | ||||
| -rw-r--r-- | net/bridge/br_device.c | 9 | ||||
| -rw-r--r-- | net/bridge/br_netfilter.c | 114 |
3 files changed, 40 insertions, 100 deletions
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h index f8105e54716a..ffab6c423a57 100644 --- a/include/linux/netfilter_bridge.h +++ b/include/linux/netfilter_bridge.h | |||
| @@ -41,9 +41,8 @@ enum nf_br_hook_priorities { | |||
| 41 | 41 | ||
| 42 | #define BRNF_PKT_TYPE 0x01 | 42 | #define BRNF_PKT_TYPE 0x01 |
| 43 | #define BRNF_BRIDGED_DNAT 0x02 | 43 | #define BRNF_BRIDGED_DNAT 0x02 |
| 44 | #define BRNF_DONT_TAKE_PARENT 0x04 | 44 | #define BRNF_BRIDGED 0x04 |
| 45 | #define BRNF_BRIDGED 0x08 | 45 | #define BRNF_NF_BRIDGE_PREROUTING 0x08 |
| 46 | #define BRNF_NF_BRIDGE_PREROUTING 0x10 | ||
| 47 | 46 | ||
| 48 | 47 | ||
| 49 | /* Only used in br_forward.c */ | 48 | /* Only used in br_forward.c */ |
| @@ -68,6 +67,18 @@ static inline unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb) | |||
| 68 | } | 67 | } |
| 69 | } | 68 | } |
| 70 | 69 | ||
| 70 | extern int br_handle_frame_finish(struct sk_buff *skb); | ||
| 71 | /* Only used in br_device.c */ | ||
| 72 | static inline int br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb) | ||
| 73 | { | ||
| 74 | struct nf_bridge_info *nf_bridge = skb->nf_bridge; | ||
| 75 | |||
| 76 | skb_pull(skb, ETH_HLEN); | ||
| 77 | nf_bridge->mask ^= BRNF_BRIDGED_DNAT; | ||
| 78 | skb->dev = nf_bridge->physindev; | ||
| 79 | return br_handle_frame_finish(skb); | ||
| 80 | } | ||
| 81 | |||
| 71 | /* This is called by the IP fragmenting code and it ensures there is | 82 | /* This is called by the IP fragmenting code and it ensures there is |
| 72 | * enough room for the encapsulating header (if there is one). */ | 83 | * enough room for the encapsulating header (if there is one). */ |
| 73 | static inline unsigned int nf_bridge_pad(const struct sk_buff *skb) | 84 | static inline unsigned int nf_bridge_pad(const struct sk_buff *skb) |
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 5b8a6e73b02f..007bde87415d 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
| 16 | #include <linux/etherdevice.h> | 16 | #include <linux/etherdevice.h> |
| 17 | #include <linux/ethtool.h> | 17 | #include <linux/ethtool.h> |
| 18 | 18 | #include <linux/netfilter_bridge.h> | |
| 19 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
| 20 | #include "br_private.h" | 20 | #include "br_private.h" |
| 21 | 21 | ||
| @@ -28,6 +28,13 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 28 | struct net_bridge_mdb_entry *mdst; | 28 | struct net_bridge_mdb_entry *mdst; |
| 29 | struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats); | 29 | struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats); |
| 30 | 30 | ||
| 31 | #ifdef CONFIG_BRIDGE_NETFILTER | ||
| 32 | if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) { | ||
| 33 | br_nf_pre_routing_finish_bridge_slow(skb); | ||
| 34 | return NETDEV_TX_OK; | ||
| 35 | } | ||
| 36 | #endif | ||
| 37 | |||
| 31 | brstats->tx_packets++; | 38 | brstats->tx_packets++; |
| 32 | brstats->tx_bytes += skb->len; | 39 | brstats->tx_bytes += skb->len; |
| 33 | 40 | ||
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index dd6f538ba0b0..05dc6304992c 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
| @@ -246,8 +246,7 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb) | |||
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | /* This requires some explaining. If DNAT has taken place, | 248 | /* This requires some explaining. If DNAT has taken place, |
| 249 | * we will need to fix up the destination Ethernet address, | 249 | * we will need to fix up the destination Ethernet address. |
| 250 | * and this is a tricky process. | ||
| 251 | * | 250 | * |
| 252 | * There are two cases to consider: | 251 | * There are two cases to consider: |
| 253 | * 1. The packet was DNAT'ed to a device in the same bridge | 252 | * 1. The packet was DNAT'ed to a device in the same bridge |
| @@ -261,52 +260,38 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb) | |||
| 261 | * call ip_route_input() and to look at skb->dst->dev, which is | 260 | * call ip_route_input() and to look at skb->dst->dev, which is |
| 262 | * changed to the destination device if ip_route_input() succeeds. | 261 | * changed to the destination device if ip_route_input() succeeds. |
| 263 | * | 262 | * |
| 264 | * Let us first consider the case that ip_route_input() succeeds: | 263 | * Let's first consider the case that ip_route_input() succeeds: |
| 265 | * | ||
| 266 | * If skb->dst->dev equals the logical bridge device the packet | ||
| 267 | * came in on, we can consider this bridging. The packet is passed | ||
| 268 | * through the neighbour output function to build a new destination | ||
| 269 | * MAC address, which will make the packet enter br_nf_local_out() | ||
| 270 | * not much later. In that function it is assured that the iptables | ||
| 271 | * FORWARD chain is traversed for the packet. | ||
| 272 | * | 264 | * |
| 265 | * If the output device equals the logical bridge device the packet | ||
| 266 | * came in on, we can consider this bridging. The corresponding MAC | ||
| 267 | * address will be obtained in br_nf_pre_routing_finish_bridge. | ||
| 273 | * Otherwise, the packet is considered to be routed and we just | 268 | * Otherwise, the packet is considered to be routed and we just |
| 274 | * change the destination MAC address so that the packet will | 269 | * change the destination MAC address so that the packet will |
| 275 | * later be passed up to the IP stack to be routed. For a redirected | 270 | * later be passed up to the IP stack to be routed. For a redirected |
| 276 | * packet, ip_route_input() will give back the localhost as output device, | 271 | * packet, ip_route_input() will give back the localhost as output device, |
| 277 | * which differs from the bridge device. | 272 | * which differs from the bridge device. |
| 278 | * | 273 | * |
| 279 | * Let us now consider the case that ip_route_input() fails: | 274 | * Let's now consider the case that ip_route_input() fails: |
| 280 | * | 275 | * |
| 281 | * This can be because the destination address is martian, in which case | 276 | * This can be because the destination address is martian, in which case |
| 282 | * the packet will be dropped. | 277 | * the packet will be dropped. |
| 283 | * After a "echo '0' > /proc/sys/net/ipv4/ip_forward" ip_route_input() | 278 | * If IP forwarding is disabled, ip_route_input() will fail, while |
| 284 | * will fail, while __ip_route_output_key() will return success. The source | 279 | * ip_route_output_key() can return success. The source |
| 285 | * address for __ip_route_output_key() is set to zero, so __ip_route_output_key | 280 | * address for ip_route_output_key() is set to zero, so ip_route_output_key() |
| 286 | * thinks we're handling a locally generated packet and won't care | 281 | * thinks we're handling a locally generated packet and won't care |
| 287 | * if IP forwarding is allowed. We send a warning message to the users's | 282 | * if IP forwarding is enabled. If the output device equals the logical bridge |
| 288 | * log telling her to put IP forwarding on. | 283 | * device, we proceed as if ip_route_input() succeeded. If it differs from the |
| 289 | * | 284 | * logical bridge port or if ip_route_output_key() fails we drop the packet. |
| 290 | * ip_route_input() will also fail if there is no route available. | 285 | */ |
| 291 | * In that case we just drop the packet. | 286 | |
| 292 | * | ||
| 293 | * --Lennert, 20020411 | ||
| 294 | * --Bart, 20020416 (updated) | ||
| 295 | * --Bart, 20021007 (updated) | ||
| 296 | * --Bart, 20062711 (updated) */ | ||
| 297 | static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) | 287 | static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) |
| 298 | { | 288 | { |
| 299 | if (skb->pkt_type == PACKET_OTHERHOST) { | ||
| 300 | skb->pkt_type = PACKET_HOST; | ||
| 301 | skb->nf_bridge->mask |= BRNF_PKT_TYPE; | ||
| 302 | } | ||
| 303 | skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; | ||
| 304 | |||
| 305 | skb->dev = bridge_parent(skb->dev); | 289 | skb->dev = bridge_parent(skb->dev); |
| 306 | if (skb->dev) { | 290 | if (skb->dev) { |
| 307 | struct dst_entry *dst = skb_dst(skb); | 291 | struct dst_entry *dst = skb_dst(skb); |
| 308 | 292 | ||
| 309 | nf_bridge_pull_encap_header(skb); | 293 | nf_bridge_pull_encap_header(skb); |
| 294 | skb->nf_bridge->mask |= BRNF_BRIDGED_DNAT; | ||
| 310 | 295 | ||
| 311 | if (dst->hh) | 296 | if (dst->hh) |
| 312 | return neigh_hh_output(dst->hh, skb); | 297 | return neigh_hh_output(dst->hh, skb); |
| @@ -368,9 +353,6 @@ free_skb: | |||
| 368 | } else { | 353 | } else { |
| 369 | if (skb_dst(skb)->dev == dev) { | 354 | if (skb_dst(skb)->dev == dev) { |
| 370 | bridged_dnat: | 355 | bridged_dnat: |
| 371 | /* Tell br_nf_local_out this is a | ||
| 372 | * bridged frame */ | ||
| 373 | nf_bridge->mask |= BRNF_BRIDGED_DNAT; | ||
| 374 | skb->dev = nf_bridge->physindev; | 356 | skb->dev = nf_bridge->physindev; |
| 375 | nf_bridge_push_encap_header(skb); | 357 | nf_bridge_push_encap_header(skb); |
| 376 | NF_HOOK_THRESH(NFPROTO_BRIDGE, | 358 | NF_HOOK_THRESH(NFPROTO_BRIDGE, |
| @@ -721,54 +703,6 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb, | |||
| 721 | return NF_STOLEN; | 703 | return NF_STOLEN; |
| 722 | } | 704 | } |
| 723 | 705 | ||
| 724 | /* PF_BRIDGE/LOCAL_OUT *********************************************** | ||
| 725 | * | ||
| 726 | * This function sees both locally originated IP packets and forwarded | ||
| 727 | * IP packets (in both cases the destination device is a bridge | ||
| 728 | * device). It also sees bridged-and-DNAT'ed packets. | ||
| 729 | * | ||
| 730 | * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged | ||
| 731 | * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward() | ||
| 732 | * will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority | ||
| 733 | * NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor | ||
| 734 | * will be executed. | ||
| 735 | */ | ||
| 736 | static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff *skb, | ||
| 737 | const struct net_device *in, | ||
| 738 | const struct net_device *out, | ||
| 739 | int (*okfn)(struct sk_buff *)) | ||
| 740 | { | ||
| 741 | struct net_device *realindev; | ||
| 742 | struct nf_bridge_info *nf_bridge; | ||
| 743 | |||
| 744 | if (!skb->nf_bridge) | ||
| 745 | return NF_ACCEPT; | ||
| 746 | |||
| 747 | /* Need exclusive nf_bridge_info since we might have multiple | ||
| 748 | * different physoutdevs. */ | ||
| 749 | if (!nf_bridge_unshare(skb)) | ||
| 750 | return NF_DROP; | ||
| 751 | |||
| 752 | nf_bridge = skb->nf_bridge; | ||
| 753 | if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT)) | ||
| 754 | return NF_ACCEPT; | ||
| 755 | |||
| 756 | /* Bridged, take PF_BRIDGE/FORWARD. | ||
| 757 | * (see big note in front of br_nf_pre_routing_finish) */ | ||
| 758 | nf_bridge->physoutdev = skb->dev; | ||
| 759 | realindev = nf_bridge->physindev; | ||
| 760 | |||
| 761 | if (nf_bridge->mask & BRNF_PKT_TYPE) { | ||
| 762 | skb->pkt_type = PACKET_OTHERHOST; | ||
| 763 | nf_bridge->mask ^= BRNF_PKT_TYPE; | ||
| 764 | } | ||
| 765 | nf_bridge_push_encap_header(skb); | ||
| 766 | |||
| 767 | NF_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev, | ||
| 768 | br_forward_finish); | ||
| 769 | return NF_STOLEN; | ||
| 770 | } | ||
| 771 | |||
| 772 | #if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE) | 706 | #if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE) |
| 773 | static int br_nf_dev_queue_xmit(struct sk_buff *skb) | 707 | static int br_nf_dev_queue_xmit(struct sk_buff *skb) |
| 774 | { | 708 | { |
| @@ -797,10 +731,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb, | |||
| 797 | struct net_device *realoutdev = bridge_parent(skb->dev); | 731 | struct net_device *realoutdev = bridge_parent(skb->dev); |
| 798 | u_int8_t pf; | 732 | u_int8_t pf; |
| 799 | 733 | ||
| 800 | if (!nf_bridge) | 734 | if (!nf_bridge || !(nf_bridge->mask & BRNF_BRIDGED)) |
| 801 | return NF_ACCEPT; | ||
| 802 | |||
| 803 | if (!(nf_bridge->mask & (BRNF_BRIDGED | BRNF_BRIDGED_DNAT))) | ||
| 804 | return NF_ACCEPT; | 735 | return NF_ACCEPT; |
| 805 | 736 | ||
| 806 | if (!realoutdev) | 737 | if (!realoutdev) |
| @@ -847,10 +778,8 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff *skb, | |||
| 847 | return NF_ACCEPT; | 778 | return NF_ACCEPT; |
| 848 | } | 779 | } |
| 849 | 780 | ||
| 850 | /* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent | 781 | /* For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because |
| 851 | * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input. | 782 | * br_dev_queue_push_xmit is called afterwards */ |
| 852 | * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because | ||
| 853 | * ip_refrag() can return NF_STOLEN. */ | ||
| 854 | static struct nf_hook_ops br_nf_ops[] __read_mostly = { | 783 | static struct nf_hook_ops br_nf_ops[] __read_mostly = { |
| 855 | { | 784 | { |
| 856 | .hook = br_nf_pre_routing, | 785 | .hook = br_nf_pre_routing, |
| @@ -881,13 +810,6 @@ static struct nf_hook_ops br_nf_ops[] __read_mostly = { | |||
| 881 | .priority = NF_BR_PRI_BRNF, | 810 | .priority = NF_BR_PRI_BRNF, |
| 882 | }, | 811 | }, |
| 883 | { | 812 | { |
| 884 | .hook = br_nf_local_out, | ||
| 885 | .owner = THIS_MODULE, | ||
| 886 | .pf = PF_BRIDGE, | ||
| 887 | .hooknum = NF_BR_LOCAL_OUT, | ||
| 888 | .priority = NF_BR_PRI_FIRST, | ||
| 889 | }, | ||
| 890 | { | ||
| 891 | .hook = br_nf_post_routing, | 813 | .hook = br_nf_post_routing, |
| 892 | .owner = THIS_MODULE, | 814 | .owner = THIS_MODULE, |
| 893 | .pf = PF_BRIDGE, | 815 | .pf = PF_BRIDGE, |
