diff options
-rw-r--r-- | Documentation/feature-removal-schedule.txt | 16 | ||||
-rw-r--r-- | include/linux/netfilter_bridge.h | 1 | ||||
-rw-r--r-- | include/linux/netfilter_ipv4.h | 2 | ||||
-rw-r--r-- | include/linux/netfilter_ipv6.h | 2 | ||||
-rw-r--r-- | net/bridge/br_netfilter.c | 188 | ||||
-rw-r--r-- | net/netfilter/xt_physdev.c | 12 |
6 files changed, 20 insertions, 201 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 040f437c421b..30f3c8c9c12a 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -207,22 +207,6 @@ Who: Thomas Gleixner <tglx@linutronix.de> | |||
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 | What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment | 210 | What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment |
227 | When: October 2008 | 211 | When: October 2008 |
228 | Why: The stacking of class devices makes these values misleading and | 212 | Why: The stacking of class devices makes these values misleading and |
diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h index 6c4613f8ad75..55689f39f77a 100644 --- a/include/linux/netfilter_bridge.h +++ b/include/linux/netfilter_bridge.h | |||
@@ -68,7 +68,6 @@ struct bridge_skb_cb { | |||
68 | } daddr; | 68 | } daddr; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | extern int brnf_deferred_hooks; | ||
72 | #else | 71 | #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) |
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h index 5821eb5a0a3e..ceae87a4c891 100644 --- a/include/linux/netfilter_ipv4.h +++ b/include/linux/netfilter_ipv4.h | |||
@@ -57,10 +57,8 @@ enum nf_ip_hook_priorities { | |||
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, |
diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h index ab81a6dc94ea..66ca8e3100dc 100644 --- a/include/linux/netfilter_ipv6.h +++ b/include/linux/netfilter_ipv6.h | |||
@@ -62,10 +62,8 @@ enum nf_ip6_hook_priorities { | |||
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, |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index bd221ad52eaf..ea3337ad0edc 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -61,9 +61,6 @@ static int brnf_filter_vlan_tagged __read_mostly = 1; | |||
61 | #define brnf_filter_vlan_tagged 1 | 61 | #define brnf_filter_vlan_tagged 1 |
62 | #endif | 62 | #endif |
63 | 63 | ||
64 | int brnf_deferred_hooks; | ||
65 | EXPORT_SYMBOL_GPL(brnf_deferred_hooks); | ||
66 | |||
67 | static __be16 inline vlan_proto(const struct sk_buff *skb) | 64 | static __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, | |||
685 | return NF_STOLEN; | 682 | return NF_STOLEN; |
686 | } | 683 | } |
687 | 684 | ||
688 | /* PF_BRIDGE/LOCAL_OUT ***********************************************/ | 685 | /* PF_BRIDGE/LOCAL_OUT *********************************************** |
689 | static 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 bridge | 688 | * 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 bridged | 691 | * 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 priority | 693 | * 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 nor | 694 | * 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 touched | 696 | */ |
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. */ | ||
722 | static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, | 697 | static 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 | ||
791 | out: | 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, | |||
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. */ | ||
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 | /* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent | 834 | /* 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), because | 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[] = { | |||
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_SYSCTL | 881 | #ifdef CONFIG_SYSCTL |
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c index fd8f954cded5..b9b3ffc5451d 100644 --- a/net/netfilter/xt_physdev.c +++ b/net/netfilter/xt_physdev.c | |||
@@ -113,20 +113,16 @@ checkentry(const char *tablename, | |||
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 | } |