[NETFILTER]: bridge-netfilter: remove deferred hooks
authorPatrick McHardy <kaber@trash.net>
Thu, 14 Dec 2006 00:54:25 +0000 (16:54 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 14 Dec 2006 00:54:25 +0000 (16:54 -0800)
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>
Documentation/feature-removal-schedule.txt
include/linux/netfilter_bridge.h
include/linux/netfilter_ipv4.h
include/linux/netfilter_ipv6.h
net/bridge/br_netfilter.c
net/netfilter/xt_physdev.c

index 040f437c421bc1bb410ce2253369fa5e1cd33e64..30f3c8c9c12aeb60f66c925949be8648a0bafd91 100644 (file)
@@ -207,22 +207,6 @@ Who:       Thomas Gleixner <tglx@linutronix.de>
 
 ---------------------------
 
-What:  Bridge netfilter deferred IPv4/IPv6 output hook calling
-When:  January 2007
-Why:   The deferred output hooks are a layering violation causing unusual
-       and broken behaviour on bridge devices. Examples of things they
-       break include QoS classifation using the MARK or CLASSIFY targets,
-       the IPsec policy match and connection tracking with VLANs on a
-       bridge. Their only use is to enable bridge output port filtering
-       within iptables with the physdev match, which can also be done by
-       combining iptables and ebtables using netfilter marks. Until it
-       will get removed the hook deferral is disabled by default and is
-       only enabled when needed.
-
-Who:   Patrick McHardy <kaber@trash.net>
-
----------------------------
-
 What:  PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment
 When:  October 2008
 Why:   The stacking of class devices makes these values misleading and
index 6c4613f8ad75ec6343d3e3178a7d43c224f8d02d..55689f39f77a69523c82221c5696bcb2c54e002b 100644 (file)
@@ -68,7 +68,6 @@ struct bridge_skb_cb {
        } daddr;
 };
 
-extern int brnf_deferred_hooks;
 #else
 #define nf_bridge_maybe_copy_header(skb)       (0)
 #define nf_bridge_pad(skb)                     (0)
index 5821eb5a0a3ec6b14a10c08781de6a4d9ace4977..ceae87a4c8911b30a6d9e2a7dcaabe0f9904e3a3 100644 (file)
@@ -57,10 +57,8 @@ enum nf_ip_hook_priorities {
        NF_IP_PRI_RAW = -300,
        NF_IP_PRI_SELINUX_FIRST = -225,
        NF_IP_PRI_CONNTRACK = -200,
-       NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
        NF_IP_PRI_MANGLE = -150,
        NF_IP_PRI_NAT_DST = -100,
-       NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
        NF_IP_PRI_FILTER = 0,
        NF_IP_PRI_NAT_SRC = 100,
        NF_IP_PRI_SELINUX_LAST = 225,
index ab81a6dc94ea7b90d80addf545aa7945dccf9366..66ca8e3100dca2eb31ae5fc8bcafdf0f43bf6750 100644 (file)
@@ -62,10 +62,8 @@ enum nf_ip6_hook_priorities {
        NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
        NF_IP6_PRI_SELINUX_FIRST = -225,
        NF_IP6_PRI_CONNTRACK = -200,
-       NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
        NF_IP6_PRI_MANGLE = -150,
        NF_IP6_PRI_NAT_DST = -100,
-       NF_IP6_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
        NF_IP6_PRI_FILTER = 0,
        NF_IP6_PRI_NAT_SRC = 100,
        NF_IP6_PRI_SELINUX_LAST = 225,
index bd221ad52eaf76e46aa8522b4db1a75176e53ecc..ea3337ad0edcf3b7b19132fc5770ce5e4c90eeb4 100644 (file)
@@ -61,9 +61,6 @@ static int brnf_filter_vlan_tagged __read_mostly = 1;
 #define brnf_filter_vlan_tagged 1
 #endif
 
-int brnf_deferred_hooks;
-EXPORT_SYMBOL_GPL(brnf_deferred_hooks);
-
 static __be16 inline vlan_proto(const struct sk_buff *skb)
 {
        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,
        return NF_STOLEN;
 }
 
-/* PF_BRIDGE/LOCAL_OUT ***********************************************/
-static int br_nf_local_out_finish(struct sk_buff *skb)
-{
-       if (skb->protocol == htons(ETH_P_8021Q)) {
-               skb_push(skb, VLAN_HLEN);
-               skb->nh.raw -= VLAN_HLEN;
-       }
-
-       NF_HOOK_THRESH(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
-                      br_forward_finish, NF_BR_PRI_FIRST + 1);
-
-       return 0;
-}
-
-/* This function sees both locally originated IP packets and forwarded
+/* PF_BRIDGE/LOCAL_OUT ***********************************************
+ *
+ * This function sees both locally originated IP packets and forwarded
  * IP packets (in both cases the destination device is a bridge
  * device). It also sees bridged-and-DNAT'ed packets.
- * To be able to filter on the physical bridge devices (with the physdev
- * module), we steal packets destined to a bridge device away from the
- * PF_INET/FORWARD and PF_INET/OUTPUT hook functions, and give them back later,
- * when we have determined the real output device. This is done in here.
  *
  * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged
  * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward()
  * will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority
  * NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor
  * will be executed.
- * Otherwise, if nf_bridge->physindev is NULL, the bridge-nf code never touched
- * this packet before, and so the packet was locally originated. We fake
- * the PF_INET/LOCAL_OUT hook.
- * Finally, if nf_bridge->physindev isn't NULL, then the packet was IP routed,
- * so we fake the PF_INET/FORWARD hook. ip_sabotage_out() makes sure
- * even routed packets that didn't arrive on a bridge interface have their
- * nf_bridge->physindev set. */
+ */
 static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
                                    const struct net_device *in,
                                    const struct net_device *out,
                                    int (*okfn)(struct sk_buff *))
 {
-       struct net_device *realindev, *realoutdev;
+       struct net_device *realindev;
        struct sk_buff *skb = *pskb;
        struct nf_bridge_info *nf_bridge;
-       int pf;
 
        if (!skb->nf_bridge)
                return NF_ACCEPT;
 
-       if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb))
-               pf = PF_INET;
-       else
-               pf = PF_INET6;
-
        nf_bridge = skb->nf_bridge;
-       nf_bridge->physoutdev = skb->dev;
-       realindev = nf_bridge->physindev;
+       if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT))
+               return NF_ACCEPT;
 
        /* Bridged, take PF_BRIDGE/FORWARD.
         * (see big note in front of br_nf_pre_routing_finish) */
-       if (nf_bridge->mask & BRNF_BRIDGED_DNAT) {
-               if (nf_bridge->mask & BRNF_PKT_TYPE) {
-                       skb->pkt_type = PACKET_OTHERHOST;
-                       nf_bridge->mask ^= BRNF_PKT_TYPE;
-               }
-               if (skb->protocol == htons(ETH_P_8021Q)) {
-                       skb_push(skb, VLAN_HLEN);
-                       skb->nh.raw -= VLAN_HLEN;
-               }
+       nf_bridge->physoutdev = skb->dev;
+       realindev = nf_bridge->physindev;
 
-               NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev,
-                       skb->dev, br_forward_finish);
-               goto out;
+       if (nf_bridge->mask & BRNF_PKT_TYPE) {
+               skb->pkt_type = PACKET_OTHERHOST;
+               nf_bridge->mask ^= BRNF_PKT_TYPE;
        }
-       realoutdev = bridge_parent(skb->dev);
-       if (!realoutdev)
-               return NF_DROP;
-
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-       /* iptables should match -o br0.x */
-       if (nf_bridge->netoutdev)
-               realoutdev = nf_bridge->netoutdev;
-#endif
        if (skb->protocol == htons(ETH_P_8021Q)) {
-               skb_pull(skb, VLAN_HLEN);
-               (*pskb)->nh.raw += VLAN_HLEN;
-       }
-       /* IP forwarded traffic has a physindev, locally
-        * generated traffic hasn't. */
-       if (realindev != NULL) {
-               if (!(nf_bridge->mask & BRNF_DONT_TAKE_PARENT)) {
-                       struct net_device *parent = bridge_parent(realindev);
-                       if (parent)
-                               realindev = parent;
-               }
-
-               NF_HOOK_THRESH(pf, NF_IP_FORWARD, skb, realindev,
-                              realoutdev, br_nf_local_out_finish,
-                              NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD + 1);
-       } else {
-               NF_HOOK_THRESH(pf, NF_IP_LOCAL_OUT, skb, realindev,
-                              realoutdev, br_nf_local_out_finish,
-                              NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT + 1);
+               skb_push(skb, VLAN_HLEN);
+               skb->nh.raw -= VLAN_HLEN;
        }
 
-out:
+       NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev,
+               br_forward_finish);
        return NF_STOLEN;
 }
 
@@ -894,69 +831,6 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb,
        return NF_ACCEPT;
 }
 
-/* Postpone execution of PF_INET(6)/FORWARD, PF_INET(6)/LOCAL_OUT
- * and PF_INET(6)/POST_ROUTING until we have done the forwarding
- * decision in the bridge code and have determined nf_bridge->physoutdev. */
-static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb,
-                                   const struct net_device *in,
-                                   const struct net_device *out,
-                                   int (*okfn)(struct sk_buff *))
-{
-       struct sk_buff *skb = *pskb;
-
-       if ((out->hard_start_xmit == br_dev_xmit &&
-            okfn != br_nf_forward_finish &&
-            okfn != br_nf_local_out_finish && okfn != br_nf_dev_queue_xmit)
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-           || ((out->priv_flags & IFF_802_1Q_VLAN) &&
-               VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit)
-#endif
-           ) {
-               struct nf_bridge_info *nf_bridge;
-
-               if (!skb->nf_bridge) {
-#ifdef CONFIG_SYSCTL
-                       /* This code is executed while in the IP(v6) stack,
-                          the version should be 4 or 6. We can't use
-                          skb->protocol because that isn't set on
-                          PF_INET(6)/LOCAL_OUT. */
-                       struct iphdr *ip = skb->nh.iph;
-
-                       if (ip->version == 4 && !brnf_call_iptables)
-                               return NF_ACCEPT;
-                       else if (ip->version == 6 && !brnf_call_ip6tables)
-                               return NF_ACCEPT;
-                       else if (!brnf_deferred_hooks)
-                               return NF_ACCEPT;
-#endif
-                       if (hook == NF_IP_POST_ROUTING)
-                               return NF_ACCEPT;
-                       if (!nf_bridge_alloc(skb))
-                               return NF_DROP;
-               }
-
-               nf_bridge = skb->nf_bridge;
-
-               /* This frame will arrive on PF_BRIDGE/LOCAL_OUT and we
-                * will need the indev then. For a brouter, the real indev
-                * can be a bridge port, so we make sure br_nf_local_out()
-                * doesn't use the bridge parent of the indev by using
-                * the BRNF_DONT_TAKE_PARENT mask. */
-               if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) {
-                       nf_bridge->mask |= BRNF_DONT_TAKE_PARENT;
-                       nf_bridge->physindev = (struct net_device *)in;
-               }
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-               /* the iptables outdev is br0.x, not br0 */
-               if (out->priv_flags & IFF_802_1Q_VLAN)
-                       nf_bridge->netoutdev = (struct net_device *)out;
-#endif
-               return NF_STOP;
-       }
-
-       return NF_ACCEPT;
-}
-
 /* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent
  * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input.
  * 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[] = {
          .pf = PF_INET6,
          .hooknum = NF_IP6_PRE_ROUTING,
          .priority = NF_IP6_PRI_FIRST, },
-       { .hook = ip_sabotage_out,
-         .owner = THIS_MODULE,
-         .pf = PF_INET,
-         .hooknum = NF_IP_FORWARD,
-         .priority = NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD, },
-       { .hook = ip_sabotage_out,
-         .owner = THIS_MODULE,
-         .pf = PF_INET6,
-         .hooknum = NF_IP6_FORWARD,
-         .priority = NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD, },
-       { .hook = ip_sabotage_out,
-         .owner = THIS_MODULE,
-         .pf = PF_INET,
-         .hooknum = NF_IP_LOCAL_OUT,
-         .priority = NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, },
-       { .hook = ip_sabotage_out,
-         .owner = THIS_MODULE,
-         .pf = PF_INET6,
-         .hooknum = NF_IP6_LOCAL_OUT,
-         .priority = NF_IP6_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, },
-       { .hook = ip_sabotage_out,
-         .owner = THIS_MODULE,
-         .pf = PF_INET,
-         .hooknum = NF_IP_POST_ROUTING,
-         .priority = NF_IP_PRI_FIRST, },
-       { .hook = ip_sabotage_out,
-         .owner = THIS_MODULE,
-         .pf = PF_INET6,
-         .hooknum = NF_IP6_POST_ROUTING,
-         .priority = NF_IP6_PRI_FIRST, },
 };
 
 #ifdef CONFIG_SYSCTL
index fd8f954cded5b5a3f786c28ef93b8a438a5d079c..b9b3ffc5451dc2138e035b7a7d4fd7428d9b94c5 100644 (file)
@@ -113,20 +113,16 @@ checkentry(const char *tablename,
        if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
            info->bitmask & ~XT_PHYSDEV_OP_MASK)
                return 0;
-       if (brnf_deferred_hooks == 0 &&
-           info->bitmask & XT_PHYSDEV_OP_OUT &&
+       if (info->bitmask & XT_PHYSDEV_OP_OUT &&
            (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
             info->invert & XT_PHYSDEV_OP_BRIDGED) &&
            hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
                         (1 << NF_IP_POST_ROUTING))) {
                printk(KERN_WARNING "physdev match: using --physdev-out in the "
                       "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
-                      "traffic is deprecated and breaks other things, it will "
-                      "be removed in January 2007. See Documentation/"
-                      "feature-removal-schedule.txt for details. This doesn't "
-                      "affect you in case you're using it for purely bridged "
-                      "traffic.\n");
-               brnf_deferred_hooks = 1;
+                      "traffic is not supported anymore.\n");
+               if (hook_mask & (1 << NF_IP_LOCAL_OUT))
+                       return 0;
        }
        return 1;
 }