History

[NETFILTER]: bridge-netfilter: remove deferred hooks

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

Patrick McHardy committed 19 years ago

Commit 2bf540b1 parent 8bce65b6 files · +20 −201Browse files

Unified · Split

6 files
  1. Documentation/feature-removal-schedule.txt +0 −16
  2. include/linux/netfilter_bridge.h +0 −1
  3. include/linux/netfilter_ipv4.h +0 −2
  4. include/linux/netfilter_ipv6.h +0 −2
  5. net/bridge/br_netfilter.c +16 −172
  6. net/netfilter/xt_physdev.c +4 −8
Documentation/feature-removal-schedule.txt+0−16
@@ -207,22 +207,6 @@ Who: Thomas Gleixner <tglx@linutronix.de> · 206 unmodified lines
207 207
208---------------------------208---------------------------
209 209
210What: Bridge netfilter deferred IPv4/IPv6 output hook calling
211When: January 2007
212Why: 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
222Who: Patrick McHardy <kaber@trash.net>
223
224---------------------------
225
226What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment210What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment
227When: October 2008211When: October 2008
228Why: The stacking of class devices makes these values misleading and212Why: The stacking of class devices makes these values misleading and
include/linux/netfilter_bridge.h+0−1
@@ -68,7 +68,6 @@ struct bridge_skb_cb { · 67 unmodified lines
68 } daddr;68 } daddr;
69};69};
70 70
71extern int brnf_deferred_hooks;
72#else71#else
73#define nf_bridge_maybe_copy_header(skb) (0)72#define nf_bridge_maybe_copy_header(skb) (0)
74#define nf_bridge_pad(skb) (0)73#define nf_bridge_pad(skb) (0)
include/linux/netfilter_ipv4.h+0−2
@@ -57,10 +57,8 @@ enum nf_ip_hook_priorities { · 56 unmodified lines
57 NF_IP_PRI_RAW = -300,57 NF_IP_PRI_RAW = -300,
58 NF_IP_PRI_SELINUX_FIRST = -225,58 NF_IP_PRI_SELINUX_FIRST = -225,
59 NF_IP_PRI_CONNTRACK = -200,59 NF_IP_PRI_CONNTRACK = -200,
60 NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
61 NF_IP_PRI_MANGLE = -150,60 NF_IP_PRI_MANGLE = -150,
62 NF_IP_PRI_NAT_DST = -100,61 NF_IP_PRI_NAT_DST = -100,
63 NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
64 NF_IP_PRI_FILTER = 0,62 NF_IP_PRI_FILTER = 0,
65 NF_IP_PRI_NAT_SRC = 100,63 NF_IP_PRI_NAT_SRC = 100,
66 NF_IP_PRI_SELINUX_LAST = 225,64 NF_IP_PRI_SELINUX_LAST = 225,
include/linux/netfilter_ipv6.h+0−2
@@ -62,10 +62,8 @@ enum nf_ip6_hook_priorities { · 61 unmodified lines
62 NF_IP6_PRI_CONNTRACK_DEFRAG = -400,62 NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
63 NF_IP6_PRI_SELINUX_FIRST = -225,63 NF_IP6_PRI_SELINUX_FIRST = -225,
64 NF_IP6_PRI_CONNTRACK = -200,64 NF_IP6_PRI_CONNTRACK = -200,
65 NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
66 NF_IP6_PRI_MANGLE = -150,65 NF_IP6_PRI_MANGLE = -150,
67 NF_IP6_PRI_NAT_DST = -100,66 NF_IP6_PRI_NAT_DST = -100,
68 NF_IP6_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
69 NF_IP6_PRI_FILTER = 0,67 NF_IP6_PRI_FILTER = 0,
70 NF_IP6_PRI_NAT_SRC = 100,68 NF_IP6_PRI_NAT_SRC = 100,
71 NF_IP6_PRI_SELINUX_LAST = 225,69 NF_IP6_PRI_SELINUX_LAST = 225,
net/bridge/br_netfilter.c+16−172
@@ -61,9 +61,6 @@ static int brnf_filter_vlan_tagged __read_mostly = 1; · 60 unmodified lines
61#define brnf_filter_vlan_tagged 161#define brnf_filter_vlan_tagged 1
62#endif62#endif
63 63
64int brnf_deferred_hooks;
65EXPORT_SYMBOL_GPL(brnf_deferred_hooks);
66
67static __be16 inline vlan_proto(const struct sk_buff *skb)64static __be16 inline vlan_proto(const struct sk_buff *skb)
68{65{
69 return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;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 return NF_STOLEN;682 return NF_STOLEN;
686}683}
687 684
688/* PF_BRIDGE/LOCAL_OUT ***********************************************/685/* PF_BRIDGE/LOCAL_OUT ***********************************************
689static int br_nf_local_out_finish(struct sk_buff *skb)686 *
690{687 * This function sees both locally originated IP packets and forwarded
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
703 * IP packets (in both cases the destination device is a bridge688 * IP packets (in both cases the destination device is a bridge
704 * device). It also sees bridged-and-DNAT'ed packets.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 * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged691 * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged
711 * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward()692 * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward()
712 * will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority693 * will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority
713 * NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor694 * NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor
714 * will be executed.695 * will be executed.
715 * Otherwise, if nf_bridge->physindev is NULL, the bridge-nf code never touched696 */
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. */
722static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,697static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
723 const struct net_device *in,698 const struct net_device *in,
724 const struct net_device *out,699 const struct net_device *out,
725 int (*okfn)(struct sk_buff *))700 int (*okfn)(struct sk_buff *))
726{701{
727 struct net_device *realindev, *realoutdev;702 struct net_device *realindev;
728 struct sk_buff *skb = *pskb;703 struct sk_buff *skb = *pskb;
729 struct nf_bridge_info *nf_bridge;704 struct nf_bridge_info *nf_bridge;
730 int pf;
731 705
732 if (!skb->nf_bridge)706 if (!skb->nf_bridge)
733 return NF_ACCEPT;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 nf_bridge = skb->nf_bridge;709 nf_bridge = skb->nf_bridge;
741 nf_bridge->physoutdev = skb->dev;710 if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT))
742 realindev = nf_bridge->physindev;711 return NF_ACCEPT;
743 712
744 /* Bridged, take PF_BRIDGE/FORWARD.713 /* Bridged, take PF_BRIDGE/FORWARD.
745 * (see big note in front of br_nf_pre_routing_finish) */714 * (see big note in front of br_nf_pre_routing_finish) */
746 if (nf_bridge->mask & BRNF_BRIDGED_DNAT) {715 nf_bridge->physoutdev = skb->dev;
747 if (nf_bridge->mask & BRNF_PKT_TYPE) {716 realindev = nf_bridge->physindev;
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 }
755 717
756 NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev,718 if (nf_bridge->mask & BRNF_PKT_TYPE) {
757 skb->dev, br_forward_finish);719 skb->pkt_type = PACKET_OTHERHOST;
758 goto out;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 if (skb->protocol == htons(ETH_P_8021Q)) {722 if (skb->protocol == htons(ETH_P_8021Q)) {
770 skb_pull(skb, VLAN_HLEN);723 skb_push(skb, VLAN_HLEN);
771 (*pskb)->nh.raw += VLAN_HLEN;724 skb->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);
789 }725 }
790 726
791out:727 NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev,
728 br_forward_finish);
792 return NF_STOLEN;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 return NF_ACCEPT;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. */
900static 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/* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent834/* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent
961 * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input.835 * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input.
962 * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because836 * 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 .pf = PF_INET6,876 .pf = PF_INET6,
1003 .hooknum = NF_IP6_PRE_ROUTING,877 .hooknum = NF_IP6_PRE_ROUTING,
1004 .priority = NF_IP6_PRI_FIRST, },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#ifdef CONFIG_SYSCTL881#ifdef CONFIG_SYSCTL
net/netfilter/xt_physdev.c+4−8
@@ -113,20 +113,16 @@ checkentry(const char *tablename, · 112 unmodified lines
113 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||113 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
114 info->bitmask & ~XT_PHYSDEV_OP_MASK)114 info->bitmask & ~XT_PHYSDEV_OP_MASK)
115 return 0;115 return 0;
116 if (brnf_deferred_hooks == 0 &&116 if (info->bitmask & XT_PHYSDEV_OP_OUT &&
117 info->bitmask & XT_PHYSDEV_OP_OUT &&
118 (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||117 (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
119 info->invert & XT_PHYSDEV_OP_BRIDGED) &&118 info->invert & XT_PHYSDEV_OP_BRIDGED) &&
120 hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |119 hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
121 (1 << NF_IP_POST_ROUTING))) {120 (1 << NF_IP_POST_ROUTING))) {
122 printk(KERN_WARNING "physdev match: using --physdev-out in the "121 printk(KERN_WARNING "physdev match: using --physdev-out in the "
123 "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "122 "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
124 "traffic is deprecated and breaks other things, it will "123 "traffic is not supported anymore.\n");
125 "be removed in January 2007. See Documentation/"124 if (hook_mask & (1 << NF_IP_LOCAL_OUT))
126 "feature-removal-schedule.txt for details. This doesn't "125 return 0;
127 "affect you in case you're using it for purely bridged "
128 "traffic.\n");
129 brnf_deferred_hooks = 1;
130 }126 }
131 return 1;127 return 1;
132}128}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t