Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[NETFILTER]: bridge-netfilter: remove deferred hooks

Remove the deferred hooks and all related code as scheduled in
feature-removal-schedule.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Patrick McHardy and committed by
David S. Miller
2bf540b7 8bce65b9

+20 -201
-16
Documentation/feature-removal-schedule.txt
··· 207 207 208 208 --------------------------- 209 209 210 - What: Bridge netfilter deferred IPv4/IPv6 output hook calling 211 - When: January 2007 212 - Why: The deferred output hooks are a layering violation causing unusual 213 - and broken behaviour on bridge devices. Examples of things they 214 - break include QoS classifation using the MARK or CLASSIFY targets, 215 - the IPsec policy match and connection tracking with VLANs on a 216 - bridge. Their only use is to enable bridge output port filtering 217 - within iptables with the physdev match, which can also be done by 218 - combining iptables and ebtables using netfilter marks. Until it 219 - will get removed the hook deferral is disabled by default and is 220 - only enabled when needed. 221 - 222 - Who: Patrick McHardy <kaber@trash.net> 223 - 224 - --------------------------- 225 - 226 210 What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment 227 211 When: October 2008 228 212 Why: The stacking of class devices makes these values misleading and
-1
include/linux/netfilter_bridge.h
··· 68 68 } daddr; 69 69 }; 70 70 71 - extern int brnf_deferred_hooks; 72 71 #else 73 72 #define nf_bridge_maybe_copy_header(skb) (0) 74 73 #define nf_bridge_pad(skb) (0)
-2
include/linux/netfilter_ipv4.h
··· 57 57 NF_IP_PRI_RAW = -300, 58 58 NF_IP_PRI_SELINUX_FIRST = -225, 59 59 NF_IP_PRI_CONNTRACK = -200, 60 - NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175, 61 60 NF_IP_PRI_MANGLE = -150, 62 61 NF_IP_PRI_NAT_DST = -100, 63 - NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50, 64 62 NF_IP_PRI_FILTER = 0, 65 63 NF_IP_PRI_NAT_SRC = 100, 66 64 NF_IP_PRI_SELINUX_LAST = 225,
-2
include/linux/netfilter_ipv6.h
··· 62 62 NF_IP6_PRI_CONNTRACK_DEFRAG = -400, 63 63 NF_IP6_PRI_SELINUX_FIRST = -225, 64 64 NF_IP6_PRI_CONNTRACK = -200, 65 - NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175, 66 65 NF_IP6_PRI_MANGLE = -150, 67 66 NF_IP6_PRI_NAT_DST = -100, 68 - NF_IP6_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50, 69 67 NF_IP6_PRI_FILTER = 0, 70 68 NF_IP6_PRI_NAT_SRC = 100, 71 69 NF_IP6_PRI_SELINUX_LAST = 225,
+16 -172
net/bridge/br_netfilter.c
··· 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; ··· 682 685 return NF_STOLEN; 683 686 } 684 687 685 - /* PF_BRIDGE/LOCAL_OUT ***********************************************/ 686 - static int br_nf_local_out_finish(struct sk_buff *skb) 687 - { 688 - if (skb->protocol == htons(ETH_P_8021Q)) { 689 - skb_push(skb, VLAN_HLEN); 690 - skb->nh.raw -= VLAN_HLEN; 691 - } 692 - 693 - NF_HOOK_THRESH(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, 694 - br_forward_finish, NF_BR_PRI_FIRST + 1); 695 - 696 - return 0; 697 - } 698 - 699 - /* This function sees both locally originated IP packets and forwarded 688 + /* PF_BRIDGE/LOCAL_OUT *********************************************** 689 + * 690 + * This function sees both locally originated IP packets and forwarded 700 691 * IP packets (in both cases the destination device is a bridge 701 692 * device). It also sees bridged-and-DNAT'ed packets. 702 - * To be able to filter on the physical bridge devices (with the physdev 703 - * module), we steal packets destined to a bridge device away from the 704 - * PF_INET/FORWARD and PF_INET/OUTPUT hook functions, and give them back later, 705 - * when we have determined the real output device. This is done in here. 706 693 * 707 694 * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged 708 695 * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward() 709 696 * will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority 710 697 * NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor 711 698 * will be executed. 712 - * Otherwise, if nf_bridge->physindev is NULL, the bridge-nf code never touched 713 - * this packet before, and so the packet was locally originated. We fake 714 - * the PF_INET/LOCAL_OUT hook. 715 - * Finally, if nf_bridge->physindev isn't NULL, then the packet was IP routed, 716 - * so we fake the PF_INET/FORWARD hook. ip_sabotage_out() makes sure 717 - * even routed packets that didn't arrive on a bridge interface have their 718 - * nf_bridge->physindev set. */ 699 + */ 719 700 static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, 720 701 const struct net_device *in, 721 702 const struct net_device *out, 722 703 int (*okfn)(struct sk_buff *)) 723 704 { 724 - struct net_device *realindev, *realoutdev; 705 + struct net_device *realindev; 725 706 struct sk_buff *skb = *pskb; 726 707 struct nf_bridge_info *nf_bridge; 727 - int pf; 728 708 729 709 if (!skb->nf_bridge) 730 710 return NF_ACCEPT; 731 711 732 - if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb)) 733 - pf = PF_INET; 734 - else 735 - pf = PF_INET6; 736 - 737 712 nf_bridge = skb->nf_bridge; 738 - nf_bridge->physoutdev = skb->dev; 739 - realindev = nf_bridge->physindev; 713 + if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT)) 714 + return NF_ACCEPT; 740 715 741 716 /* Bridged, take PF_BRIDGE/FORWARD. 742 717 * (see big note in front of br_nf_pre_routing_finish) */ 743 - if (nf_bridge->mask & BRNF_BRIDGED_DNAT) { 744 - if (nf_bridge->mask & BRNF_PKT_TYPE) { 745 - skb->pkt_type = PACKET_OTHERHOST; 746 - nf_bridge->mask ^= BRNF_PKT_TYPE; 747 - } 748 - if (skb->protocol == htons(ETH_P_8021Q)) { 749 - skb_push(skb, VLAN_HLEN); 750 - skb->nh.raw -= VLAN_HLEN; 751 - } 718 + nf_bridge->physoutdev = skb->dev; 719 + realindev = nf_bridge->physindev; 752 720 753 - NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, 754 - skb->dev, br_forward_finish); 755 - goto out; 721 + if (nf_bridge->mask & BRNF_PKT_TYPE) { 722 + skb->pkt_type = PACKET_OTHERHOST; 723 + nf_bridge->mask ^= BRNF_PKT_TYPE; 756 724 } 757 - realoutdev = bridge_parent(skb->dev); 758 - if (!realoutdev) 759 - return NF_DROP; 760 - 761 - #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) 762 - /* iptables should match -o br0.x */ 763 - if (nf_bridge->netoutdev) 764 - realoutdev = nf_bridge->netoutdev; 765 - #endif 766 725 if (skb->protocol == htons(ETH_P_8021Q)) { 767 - skb_pull(skb, VLAN_HLEN); 768 - (*pskb)->nh.raw += VLAN_HLEN; 769 - } 770 - /* IP forwarded traffic has a physindev, locally 771 - * generated traffic hasn't. */ 772 - if (realindev != NULL) { 773 - if (!(nf_bridge->mask & BRNF_DONT_TAKE_PARENT)) { 774 - struct net_device *parent = bridge_parent(realindev); 775 - if (parent) 776 - realindev = parent; 777 - } 778 - 779 - NF_HOOK_THRESH(pf, NF_IP_FORWARD, skb, realindev, 780 - realoutdev, br_nf_local_out_finish, 781 - NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD + 1); 782 - } else { 783 - NF_HOOK_THRESH(pf, NF_IP_LOCAL_OUT, skb, realindev, 784 - realoutdev, br_nf_local_out_finish, 785 - NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT + 1); 726 + skb_push(skb, VLAN_HLEN); 727 + skb->nh.raw -= VLAN_HLEN; 786 728 } 787 729 788 - out: 730 + NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev, 731 + br_forward_finish); 789 732 return NF_STOLEN; 790 733 } 791 734 ··· 831 894 return NF_ACCEPT; 832 895 } 833 896 834 - /* Postpone execution of PF_INET(6)/FORWARD, PF_INET(6)/LOCAL_OUT 835 - * and PF_INET(6)/POST_ROUTING until we have done the forwarding 836 - * decision in the bridge code and have determined nf_bridge->physoutdev. */ 837 - static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, 838 - const struct net_device *in, 839 - const struct net_device *out, 840 - int (*okfn)(struct sk_buff *)) 841 - { 842 - struct sk_buff *skb = *pskb; 843 - 844 - if ((out->hard_start_xmit == br_dev_xmit && 845 - okfn != br_nf_forward_finish && 846 - okfn != br_nf_local_out_finish && okfn != br_nf_dev_queue_xmit) 847 - #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) 848 - || ((out->priv_flags & IFF_802_1Q_VLAN) && 849 - VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit) 850 - #endif 851 - ) { 852 - struct nf_bridge_info *nf_bridge; 853 - 854 - if (!skb->nf_bridge) { 855 - #ifdef CONFIG_SYSCTL 856 - /* This code is executed while in the IP(v6) stack, 857 - the version should be 4 or 6. We can't use 858 - skb->protocol because that isn't set on 859 - PF_INET(6)/LOCAL_OUT. */ 860 - struct iphdr *ip = skb->nh.iph; 861 - 862 - if (ip->version == 4 && !brnf_call_iptables) 863 - return NF_ACCEPT; 864 - else if (ip->version == 6 && !brnf_call_ip6tables) 865 - return NF_ACCEPT; 866 - else if (!brnf_deferred_hooks) 867 - return NF_ACCEPT; 868 - #endif 869 - if (hook == NF_IP_POST_ROUTING) 870 - return NF_ACCEPT; 871 - if (!nf_bridge_alloc(skb)) 872 - return NF_DROP; 873 - } 874 - 875 - nf_bridge = skb->nf_bridge; 876 - 877 - /* This frame will arrive on PF_BRIDGE/LOCAL_OUT and we 878 - * will need the indev then. For a brouter, the real indev 879 - * can be a bridge port, so we make sure br_nf_local_out() 880 - * doesn't use the bridge parent of the indev by using 881 - * the BRNF_DONT_TAKE_PARENT mask. */ 882 - if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) { 883 - nf_bridge->mask |= BRNF_DONT_TAKE_PARENT; 884 - nf_bridge->physindev = (struct net_device *)in; 885 - } 886 - #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) 887 - /* the iptables outdev is br0.x, not br0 */ 888 - if (out->priv_flags & IFF_802_1Q_VLAN) 889 - nf_bridge->netoutdev = (struct net_device *)out; 890 - #endif 891 - return NF_STOP; 892 - } 893 - 894 - return NF_ACCEPT; 895 - } 896 - 897 897 /* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent 898 898 * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input. 899 899 * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because ··· 875 1001 .owner = THIS_MODULE, 876 1002 .pf = PF_INET6, 877 1003 .hooknum = NF_IP6_PRE_ROUTING, 878 - .priority = NF_IP6_PRI_FIRST, }, 879 - { .hook = ip_sabotage_out, 880 - .owner = THIS_MODULE, 881 - .pf = PF_INET, 882 - .hooknum = NF_IP_FORWARD, 883 - .priority = NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD, }, 884 - { .hook = ip_sabotage_out, 885 - .owner = THIS_MODULE, 886 - .pf = PF_INET6, 887 - .hooknum = NF_IP6_FORWARD, 888 - .priority = NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD, }, 889 - { .hook = ip_sabotage_out, 890 - .owner = THIS_MODULE, 891 - .pf = PF_INET, 892 - .hooknum = NF_IP_LOCAL_OUT, 893 - .priority = NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, }, 894 - { .hook = ip_sabotage_out, 895 - .owner = THIS_MODULE, 896 - .pf = PF_INET6, 897 - .hooknum = NF_IP6_LOCAL_OUT, 898 - .priority = NF_IP6_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, }, 899 - { .hook = ip_sabotage_out, 900 - .owner = THIS_MODULE, 901 - .pf = PF_INET, 902 - .hooknum = NF_IP_POST_ROUTING, 903 - .priority = NF_IP_PRI_FIRST, }, 904 - { .hook = ip_sabotage_out, 905 - .owner = THIS_MODULE, 906 - .pf = PF_INET6, 907 - .hooknum = NF_IP6_POST_ROUTING, 908 1004 .priority = NF_IP6_PRI_FIRST, }, 909 1005 }; 910 1006
+4 -8
net/netfilter/xt_physdev.c
··· 113 113 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || 114 114 info->bitmask & ~XT_PHYSDEV_OP_MASK) 115 115 return 0; 116 - if (brnf_deferred_hooks == 0 && 117 - info->bitmask & XT_PHYSDEV_OP_OUT && 116 + if (info->bitmask & XT_PHYSDEV_OP_OUT && 118 117 (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) || 119 118 info->invert & XT_PHYSDEV_OP_BRIDGED) && 120 119 hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | 121 120 (1 << NF_IP_POST_ROUTING))) { 122 121 printk(KERN_WARNING "physdev match: using --physdev-out in the " 123 122 "OUTPUT, FORWARD and POSTROUTING chains for non-bridged " 124 - "traffic is deprecated and breaks other things, it will " 125 - "be removed in January 2007. See Documentation/" 126 - "feature-removal-schedule.txt for details. This doesn't " 127 - "affect you in case you're using it for purely bridged " 128 - "traffic.\n"); 129 - brnf_deferred_hooks = 1; 123 + "traffic is not supported anymore.\n"); 124 + if (hook_mask & (1 << NF_IP_LOCAL_OUT)) 125 + return 0; 130 126 } 131 127 return 1; 132 128 }