| @@ -61,9 +61,6 @@ static int brnf_filter_vlan_tagged __read_mostly = 1; · 60 unmodified lines |
| 61 | 61 | #define brnf_filter_vlan_tagged 1 |
| 62 | 62 | #endif |
| 63 | 63 | |
| 64 | | −int brnf_deferred_hooks; |
| 65 | | −EXPORT_SYMBOL_GPL(brnf_deferred_hooks); |
| 66 | | − |
| 67 | 64 | static __be16 inline vlan_proto(const struct sk_buff *skb) |
| 68 | 65 | { |
| 69 | 66 | return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; |
| @@ -685,110 +682,50 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb, · 615 unmodified lines |
| 685 | 682 | return NF_STOLEN; |
| 686 | 683 | } |
| 687 | 684 | |
| 688 | | −/* PF_BRIDGE/LOCAL_OUT ***********************************************/ |
| 689 | | −static int br_nf_local_out_finish(struct sk_buff *skb) |
| 690 | | −{ |
| 691 | | − if (skb->protocol == htons(ETH_P_8021Q)) { |
| 692 | | − skb_push(skb, VLAN_HLEN); |
| 693 | | − skb->nh.raw -= VLAN_HLEN; |
| 694 | | − } |
| 695 | | − |
| 696 | | − NF_HOOK_THRESH(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, |
| 697 | | − br_forward_finish, NF_BR_PRI_FIRST + 1); |
| 698 | | − |
| 699 | | − return 0; |
| 700 | | −} |
| 701 | | − |
| 702 | | −/* This function sees both locally originated IP packets and forwarded |
| 685 | +/* PF_BRIDGE/LOCAL_OUT *********************************************** |
| 686 | + * |
| 687 | + * This function sees both locally originated IP packets and forwarded |
| 703 | 688 | * IP packets (in both cases the destination device is a bridge |
| 704 | 689 | * device). It also sees bridged-and-DNAT'ed packets. |
| 705 | | − * To be able to filter on the physical bridge devices (with the physdev |
| 706 | | − * module), we steal packets destined to a bridge device away from the |
| 707 | | − * PF_INET/FORWARD and PF_INET/OUTPUT hook functions, and give them back later, |
| 708 | | − * when we have determined the real output device. This is done in here. |
| 709 | 690 | * |
| 710 | 691 | * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged |
| 711 | 692 | * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward() |
| 712 | 693 | * will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority |
| 713 | 694 | * NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor |
| 714 | 695 | * will be executed. |
| 715 | | − * Otherwise, if nf_bridge->physindev is NULL, the bridge-nf code never touched |
| 716 | | − * this packet before, and so the packet was locally originated. We fake |
| 717 | | − * the PF_INET/LOCAL_OUT hook. |
| 718 | | − * Finally, if nf_bridge->physindev isn't NULL, then the packet was IP routed, |
| 719 | | − * so we fake the PF_INET/FORWARD hook. ip_sabotage_out() makes sure |
| 720 | | − * even routed packets that didn't arrive on a bridge interface have their |
| 721 | | − * nf_bridge->physindev set. */ |
| 696 | + */ |
| 722 | 697 | static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, |
| 723 | 698 | const struct net_device *in, |
| 724 | 699 | const struct net_device *out, |
| 725 | 700 | int (*okfn)(struct sk_buff *)) |
| 726 | 701 | { |
| 727 | | − struct net_device *realindev, *realoutdev; |
| 702 | + struct net_device *realindev; |
| 728 | 703 | struct sk_buff *skb = *pskb; |
| 729 | 704 | struct nf_bridge_info *nf_bridge; |
| 730 | | − int pf; |
| 731 | 705 | |
| 732 | 706 | if (!skb->nf_bridge) |
| 733 | 707 | return NF_ACCEPT; |
| 734 | 708 | |
| 735 | | − if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb)) |
| 736 | | − pf = PF_INET; |
| 737 | | − else |
| 738 | | − pf = PF_INET6; |
| 739 | | − |
| 740 | 709 | nf_bridge = skb->nf_bridge; |
| 741 | | − nf_bridge->physoutdev = skb->dev; |
| 742 | | − realindev = nf_bridge->physindev; |
| 710 | + if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT)) |
| 711 | + return NF_ACCEPT; |
| 743 | 712 | |
| 744 | 713 | /* Bridged, take PF_BRIDGE/FORWARD. |
| 745 | 714 | * (see big note in front of br_nf_pre_routing_finish) */ |
| 746 | | − if (nf_bridge->mask & BRNF_BRIDGED_DNAT) { |
| 747 | | − if (nf_bridge->mask & BRNF_PKT_TYPE) { |
| 748 | | − skb->pkt_type = PACKET_OTHERHOST; |
| 749 | | − nf_bridge->mask ^= BRNF_PKT_TYPE; |
| 750 | | − } |
| 751 | | − if (skb->protocol == htons(ETH_P_8021Q)) { |
| 752 | | − skb_push(skb, VLAN_HLEN); |
| 753 | | − skb->nh.raw -= VLAN_HLEN; |
| 754 | | − } |
| 715 | + nf_bridge->physoutdev = skb->dev; |
| 716 | + realindev = nf_bridge->physindev; |
| 755 | 717 | |
| 756 | | − NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, |
| 757 | | − skb->dev, br_forward_finish); |
| 758 | | − goto out; |
| 718 | + if (nf_bridge->mask & BRNF_PKT_TYPE) { |
| 719 | + skb->pkt_type = PACKET_OTHERHOST; |
| 720 | + nf_bridge->mask ^= BRNF_PKT_TYPE; |
| 759 | 721 | } |
| 760 | | − realoutdev = bridge_parent(skb->dev); |
| 761 | | − if (!realoutdev) |
| 762 | | − return NF_DROP; |
| 763 | | − |
| 764 | | −#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) |
| 765 | | − /* iptables should match -o br0.x */ |
| 766 | | − if (nf_bridge->netoutdev) |
| 767 | | − realoutdev = nf_bridge->netoutdev; |
| 768 | | −#endif |
| 769 | 722 | if (skb->protocol == htons(ETH_P_8021Q)) { |
| 770 | | − skb_pull(skb, VLAN_HLEN); |
| 771 | | − (*pskb)->nh.raw += VLAN_HLEN; |
| 772 | | − } |
| 773 | | − /* IP forwarded traffic has a physindev, locally |
| 774 | | − * generated traffic hasn't. */ |
| 775 | | − if (realindev != NULL) { |
| 776 | | − if (!(nf_bridge->mask & BRNF_DONT_TAKE_PARENT)) { |
| 777 | | − struct net_device *parent = bridge_parent(realindev); |
| 778 | | − if (parent) |
| 779 | | − realindev = parent; |
| 780 | | − } |
| 781 | | − |
| 782 | | − NF_HOOK_THRESH(pf, NF_IP_FORWARD, skb, realindev, |
| 783 | | − realoutdev, br_nf_local_out_finish, |
| 784 | | − NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD + 1); |
| 785 | | − } else { |
| 786 | | − NF_HOOK_THRESH(pf, NF_IP_LOCAL_OUT, skb, realindev, |
| 787 | | − realoutdev, br_nf_local_out_finish, |
| 788 | | − NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT + 1); |
| 723 | + skb_push(skb, VLAN_HLEN); |
| 724 | + skb->nh.raw -= VLAN_HLEN; |
| 789 | 725 | } |
| 790 | 726 | |
| 791 | | −out: |
| 727 | + NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev, |
| 728 | + br_forward_finish); |
| 792 | 729 | return NF_STOLEN; |
| 793 | 730 | } |
| 794 | 731 | |
| @@ -894,69 +831,6 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb, · 99 unmodified lines |
| 894 | 831 | return NF_ACCEPT; |
| 895 | 832 | } |
| 896 | 833 | |
| 897 | | −/* Postpone execution of PF_INET(6)/FORWARD, PF_INET(6)/LOCAL_OUT |
| 898 | | − * and PF_INET(6)/POST_ROUTING until we have done the forwarding |
| 899 | | − * decision in the bridge code and have determined nf_bridge->physoutdev. */ |
| 900 | | −static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, |
| 901 | | − const struct net_device *in, |
| 902 | | − const struct net_device *out, |
| 903 | | − int (*okfn)(struct sk_buff *)) |
| 904 | | −{ |
| 905 | | − struct sk_buff *skb = *pskb; |
| 906 | | − |
| 907 | | − if ((out->hard_start_xmit == br_dev_xmit && |
| 908 | | − okfn != br_nf_forward_finish && |
| 909 | | − okfn != br_nf_local_out_finish && okfn != br_nf_dev_queue_xmit) |
| 910 | | −#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) |
| 911 | | − || ((out->priv_flags & IFF_802_1Q_VLAN) && |
| 912 | | − VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit) |
| 913 | | −#endif |
| 914 | | − ) { |
| 915 | | − struct nf_bridge_info *nf_bridge; |
| 916 | | − |
| 917 | | − if (!skb->nf_bridge) { |
| 918 | | −#ifdef CONFIG_SYSCTL |
| 919 | | − /* This code is executed while in the IP(v6) stack, |
| 920 | | − the version should be 4 or 6. We can't use |
| 921 | | − skb->protocol because that isn't set on |
| 922 | | − PF_INET(6)/LOCAL_OUT. */ |
| 923 | | − struct iphdr *ip = skb->nh.iph; |
| 924 | | − |
| 925 | | − if (ip->version == 4 && !brnf_call_iptables) |
| 926 | | − return NF_ACCEPT; |
| 927 | | − else if (ip->version == 6 && !brnf_call_ip6tables) |
| 928 | | − return NF_ACCEPT; |
| 929 | | − else if (!brnf_deferred_hooks) |
| 930 | | − return NF_ACCEPT; |
| 931 | | −#endif |
| 932 | | − if (hook == NF_IP_POST_ROUTING) |
| 933 | | − return NF_ACCEPT; |
| 934 | | − if (!nf_bridge_alloc(skb)) |
| 935 | | − return NF_DROP; |
| 936 | | − } |
| 937 | | − |
| 938 | | − nf_bridge = skb->nf_bridge; |
| 939 | | − |
| 940 | | − /* This frame will arrive on PF_BRIDGE/LOCAL_OUT and we |
| 941 | | − * will need the indev then. For a brouter, the real indev |
| 942 | | − * can be a bridge port, so we make sure br_nf_local_out() |
| 943 | | − * doesn't use the bridge parent of the indev by using |
| 944 | | − * the BRNF_DONT_TAKE_PARENT mask. */ |
| 945 | | − if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) { |
| 946 | | − nf_bridge->mask |= BRNF_DONT_TAKE_PARENT; |
| 947 | | − nf_bridge->physindev = (struct net_device *)in; |
| 948 | | − } |
| 949 | | −#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) |
| 950 | | − /* the iptables outdev is br0.x, not br0 */ |
| 951 | | − if (out->priv_flags & IFF_802_1Q_VLAN) |
| 952 | | − nf_bridge->netoutdev = (struct net_device *)out; |
| 953 | | −#endif |
| 954 | | − return NF_STOP; |
| 955 | | − } |
| 956 | | − |
| 957 | | − return NF_ACCEPT; |
| 958 | | −} |
| 959 | | − |
| 960 | 834 | /* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent |
| 961 | 835 | * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input. |
| 962 | 836 | * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because |
| @@ -1002,36 +876,6 @@ static struct nf_hook_ops br_nf_ops[] = { · 39 unmodified lines |
| 1002 | 876 | .pf = PF_INET6, |
| 1003 | 877 | .hooknum = NF_IP6_PRE_ROUTING, |
| 1004 | 878 | .priority = NF_IP6_PRI_FIRST, }, |
| 1005 | | − { .hook = ip_sabotage_out, |
| 1006 | | − .owner = THIS_MODULE, |
| 1007 | | − .pf = PF_INET, |
| 1008 | | − .hooknum = NF_IP_FORWARD, |
| 1009 | | − .priority = NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD, }, |
| 1010 | | − { .hook = ip_sabotage_out, |
| 1011 | | − .owner = THIS_MODULE, |
| 1012 | | − .pf = PF_INET6, |
| 1013 | | − .hooknum = NF_IP6_FORWARD, |
| 1014 | | − .priority = NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD, }, |
| 1015 | | − { .hook = ip_sabotage_out, |
| 1016 | | − .owner = THIS_MODULE, |
| 1017 | | − .pf = PF_INET, |
| 1018 | | − .hooknum = NF_IP_LOCAL_OUT, |
| 1019 | | − .priority = NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, }, |
| 1020 | | − { .hook = ip_sabotage_out, |
| 1021 | | − .owner = THIS_MODULE, |
| 1022 | | − .pf = PF_INET6, |
| 1023 | | − .hooknum = NF_IP6_LOCAL_OUT, |
| 1024 | | − .priority = NF_IP6_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, }, |
| 1025 | | − { .hook = ip_sabotage_out, |
| 1026 | | − .owner = THIS_MODULE, |
| 1027 | | − .pf = PF_INET, |
| 1028 | | − .hooknum = NF_IP_POST_ROUTING, |
| 1029 | | − .priority = NF_IP_PRI_FIRST, }, |
| 1030 | | − { .hook = ip_sabotage_out, |
| 1031 | | − .owner = THIS_MODULE, |
| 1032 | | − .pf = PF_INET6, |
| 1033 | | − .hooknum = NF_IP6_POST_ROUTING, |
| 1034 | | − .priority = NF_IP6_PRI_FIRST, }, |
| 1035 | 879 | }; |
| 1036 | 880 | |
| 1037 | 881 | #ifdef CONFIG_SYSCTL |