mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-18 10:13:57 +08:00
[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>
This commit is contained in:
parent
8bce65b95a
commit
2bf540b73e
@ -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
|
What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment
|
||||||
When: October 2008
|
When: October 2008
|
||||||
Why: The stacking of class devices makes these values misleading and
|
Why: The stacking of class devices makes these values misleading and
|
||||||
|
@ -68,7 +68,6 @@ struct bridge_skb_cb {
|
|||||||
} daddr;
|
} daddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int brnf_deferred_hooks;
|
|
||||||
#else
|
#else
|
||||||
#define nf_bridge_maybe_copy_header(skb) (0)
|
#define nf_bridge_maybe_copy_header(skb) (0)
|
||||||
#define nf_bridge_pad(skb) (0)
|
#define nf_bridge_pad(skb) (0)
|
||||||
|
@ -57,10 +57,8 @@ enum nf_ip_hook_priorities {
|
|||||||
NF_IP_PRI_RAW = -300,
|
NF_IP_PRI_RAW = -300,
|
||||||
NF_IP_PRI_SELINUX_FIRST = -225,
|
NF_IP_PRI_SELINUX_FIRST = -225,
|
||||||
NF_IP_PRI_CONNTRACK = -200,
|
NF_IP_PRI_CONNTRACK = -200,
|
||||||
NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
|
|
||||||
NF_IP_PRI_MANGLE = -150,
|
NF_IP_PRI_MANGLE = -150,
|
||||||
NF_IP_PRI_NAT_DST = -100,
|
NF_IP_PRI_NAT_DST = -100,
|
||||||
NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
|
|
||||||
NF_IP_PRI_FILTER = 0,
|
NF_IP_PRI_FILTER = 0,
|
||||||
NF_IP_PRI_NAT_SRC = 100,
|
NF_IP_PRI_NAT_SRC = 100,
|
||||||
NF_IP_PRI_SELINUX_LAST = 225,
|
NF_IP_PRI_SELINUX_LAST = 225,
|
||||||
|
@ -62,10 +62,8 @@ enum nf_ip6_hook_priorities {
|
|||||||
NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
|
NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
|
||||||
NF_IP6_PRI_SELINUX_FIRST = -225,
|
NF_IP6_PRI_SELINUX_FIRST = -225,
|
||||||
NF_IP6_PRI_CONNTRACK = -200,
|
NF_IP6_PRI_CONNTRACK = -200,
|
||||||
NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
|
|
||||||
NF_IP6_PRI_MANGLE = -150,
|
NF_IP6_PRI_MANGLE = -150,
|
||||||
NF_IP6_PRI_NAT_DST = -100,
|
NF_IP6_PRI_NAT_DST = -100,
|
||||||
NF_IP6_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
|
|
||||||
NF_IP6_PRI_FILTER = 0,
|
NF_IP6_PRI_FILTER = 0,
|
||||||
NF_IP6_PRI_NAT_SRC = 100,
|
NF_IP6_PRI_NAT_SRC = 100,
|
||||||
NF_IP6_PRI_SELINUX_LAST = 225,
|
NF_IP6_PRI_SELINUX_LAST = 225,
|
||||||
|
@ -61,9 +61,6 @@ static int brnf_filter_vlan_tagged __read_mostly = 1;
|
|||||||
#define brnf_filter_vlan_tagged 1
|
#define brnf_filter_vlan_tagged 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int brnf_deferred_hooks;
|
|
||||||
EXPORT_SYMBOL_GPL(brnf_deferred_hooks);
|
|
||||||
|
|
||||||
static __be16 inline vlan_proto(const struct sk_buff *skb)
|
static __be16 inline vlan_proto(const struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
|
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;
|
return NF_STOLEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PF_BRIDGE/LOCAL_OUT ***********************************************/
|
/* PF_BRIDGE/LOCAL_OUT ***********************************************
|
||||||
static int br_nf_local_out_finish(struct sk_buff *skb)
|
*
|
||||||
{
|
* This function sees both locally originated IP packets and forwarded
|
||||||
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
|
|
||||||
* IP packets (in both cases the destination device is a bridge
|
* IP packets (in both cases the destination device is a bridge
|
||||||
* device). It also sees bridged-and-DNAT'ed packets.
|
* 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
|
* 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()
|
* 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
|
* 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
|
* NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor
|
||||||
* will be executed.
|
* 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,
|
static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
|
||||||
const struct net_device *in,
|
const struct net_device *in,
|
||||||
const struct net_device *out,
|
const struct net_device *out,
|
||||||
int (*okfn)(struct sk_buff *))
|
int (*okfn)(struct sk_buff *))
|
||||||
{
|
{
|
||||||
struct net_device *realindev, *realoutdev;
|
struct net_device *realindev;
|
||||||
struct sk_buff *skb = *pskb;
|
struct sk_buff *skb = *pskb;
|
||||||
struct nf_bridge_info *nf_bridge;
|
struct nf_bridge_info *nf_bridge;
|
||||||
int pf;
|
|
||||||
|
|
||||||
if (!skb->nf_bridge)
|
if (!skb->nf_bridge)
|
||||||
return NF_ACCEPT;
|
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 = skb->nf_bridge;
|
||||||
nf_bridge->physoutdev = skb->dev;
|
if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT))
|
||||||
realindev = nf_bridge->physindev;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
/* Bridged, take PF_BRIDGE/FORWARD.
|
/* Bridged, take PF_BRIDGE/FORWARD.
|
||||||
* (see big note in front of br_nf_pre_routing_finish) */
|
* (see big note in front of br_nf_pre_routing_finish) */
|
||||||
if (nf_bridge->mask & BRNF_BRIDGED_DNAT) {
|
nf_bridge->physoutdev = skb->dev;
|
||||||
if (nf_bridge->mask & BRNF_PKT_TYPE) {
|
realindev = nf_bridge->physindev;
|
||||||
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_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev,
|
if (nf_bridge->mask & BRNF_PKT_TYPE) {
|
||||||
skb->dev, br_forward_finish);
|
skb->pkt_type = PACKET_OTHERHOST;
|
||||||
goto out;
|
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)) {
|
if (skb->protocol == htons(ETH_P_8021Q)) {
|
||||||
skb_pull(skb, VLAN_HLEN);
|
skb_push(skb, VLAN_HLEN);
|
||||||
(*pskb)->nh.raw += VLAN_HLEN;
|
skb->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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev,
|
||||||
|
br_forward_finish);
|
||||||
return NF_STOLEN;
|
return NF_STOLEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -894,69 +831,6 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb,
|
|||||||
return NF_ACCEPT;
|
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
|
/* 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.
|
* 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
|
* 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,
|
.pf = PF_INET6,
|
||||||
.hooknum = NF_IP6_PRE_ROUTING,
|
.hooknum = NF_IP6_PRE_ROUTING,
|
||||||
.priority = NF_IP6_PRI_FIRST, },
|
.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
|
#ifdef CONFIG_SYSCTL
|
||||||
|
@ -113,20 +113,16 @@ checkentry(const char *tablename,
|
|||||||
if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
|
if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
|
||||||
info->bitmask & ~XT_PHYSDEV_OP_MASK)
|
info->bitmask & ~XT_PHYSDEV_OP_MASK)
|
||||||
return 0;
|
return 0;
|
||||||
if (brnf_deferred_hooks == 0 &&
|
if (info->bitmask & XT_PHYSDEV_OP_OUT &&
|
||||||
info->bitmask & XT_PHYSDEV_OP_OUT &&
|
|
||||||
(!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
|
(!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
|
||||||
info->invert & XT_PHYSDEV_OP_BRIDGED) &&
|
info->invert & XT_PHYSDEV_OP_BRIDGED) &&
|
||||||
hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
|
hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
|
||||||
(1 << NF_IP_POST_ROUTING))) {
|
(1 << NF_IP_POST_ROUTING))) {
|
||||||
printk(KERN_WARNING "physdev match: using --physdev-out in the "
|
printk(KERN_WARNING "physdev match: using --physdev-out in the "
|
||||||
"OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
|
"OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
|
||||||
"traffic is deprecated and breaks other things, it will "
|
"traffic is not supported anymore.\n");
|
||||||
"be removed in January 2007. See Documentation/"
|
if (hook_mask & (1 << NF_IP_LOCAL_OUT))
|
||||||
"feature-removal-schedule.txt for details. This doesn't "
|
return 0;
|
||||||
"affect you in case you're using it for purely bridged "
|
|
||||||
"traffic.\n");
|
|
||||||
brnf_deferred_hooks = 1;
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user