netfilter: bridge: reduce nf_bridge_info to 32 bytes again
We can use union for most of the temporary cruft (original ipv4/ipv6 address, source mac, physoutdev) since they're used during different stages of br netfilter traversal. Also get rid of the last two ->mask users. Shrinks struct from 48 to 32 on 64bit arch. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Родитель
d7ee351904
Коммит
72b1e5e4ca
|
@ -17,9 +17,6 @@ enum nf_br_hook_priorities {
|
|||
|
||||
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
|
||||
|
||||
#define BRNF_BRIDGED_DNAT 0x02
|
||||
#define BRNF_NF_BRIDGE_PREROUTING 0x08
|
||||
|
||||
int br_handle_frame_finish(struct sock *sk, struct sk_buff *skb);
|
||||
|
||||
static inline void br_drop_fake_rtable(struct sk_buff *skb)
|
||||
|
@ -63,8 +60,17 @@ nf_bridge_get_physoutdev(const struct sk_buff *skb)
|
|||
{
|
||||
return skb->nf_bridge ? skb->nf_bridge->physoutdev : NULL;
|
||||
}
|
||||
|
||||
static inline bool nf_bridge_in_prerouting(const struct sk_buff *skb)
|
||||
{
|
||||
return skb->nf_bridge && skb->nf_bridge->in_prerouting;
|
||||
}
|
||||
#else
|
||||
#define br_drop_fake_rtable(skb) do { } while (0)
|
||||
static inline bool nf_bridge_in_prerouting(const struct sk_buff *skb)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_BRIDGE_NETFILTER */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -173,17 +173,24 @@ struct nf_bridge_info {
|
|||
BRNF_PROTO_8021Q,
|
||||
BRNF_PROTO_PPPOE
|
||||
} orig_proto:8;
|
||||
bool pkt_otherhost;
|
||||
u8 pkt_otherhost:1;
|
||||
u8 in_prerouting:1;
|
||||
u8 bridged_dnat:1;
|
||||
__u16 frag_max_size;
|
||||
unsigned int mask;
|
||||
struct net_device *physindev;
|
||||
union {
|
||||
struct net_device *physoutdev;
|
||||
char neigh_header[8];
|
||||
};
|
||||
union {
|
||||
/* prerouting: detect dnat in orig/reply direction */
|
||||
__be32 ipv4_daddr;
|
||||
struct in6_addr ipv6_daddr;
|
||||
|
||||
/* after prerouting + nat detected: store original source
|
||||
* mac since neigh resolution overwrites it, only used while
|
||||
* skb is out in neigh layer.
|
||||
*/
|
||||
char neigh_header[8];
|
||||
|
||||
/* always valid & non-NULL from FORWARD on, for physdev match */
|
||||
struct net_device *physoutdev;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -284,7 +284,7 @@ int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb)
|
|||
nf_bridge->neigh_header,
|
||||
ETH_HLEN-ETH_ALEN);
|
||||
/* tell br_dev_xmit to continue with forwarding */
|
||||
nf_bridge->mask |= BRNF_BRIDGED_DNAT;
|
||||
nf_bridge->bridged_dnat = 1;
|
||||
/* FIXME Need to refragment */
|
||||
ret = neigh->output(neigh, skb);
|
||||
}
|
||||
|
@ -356,7 +356,7 @@ static int br_nf_pre_routing_finish(struct sock *sk, struct sk_buff *skb)
|
|||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
nf_bridge->pkt_otherhost = false;
|
||||
}
|
||||
nf_bridge->mask &= ~BRNF_NF_BRIDGE_PREROUTING;
|
||||
nf_bridge->in_prerouting = 0;
|
||||
if (br_nf_ipv4_daddr_was_changed(skb, nf_bridge)) {
|
||||
if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
|
||||
struct in_device *in_dev = __in_dev_get_rcu(dev);
|
||||
|
@ -444,7 +444,7 @@ struct net_device *setup_pre_routing(struct sk_buff *skb)
|
|||
nf_bridge->pkt_otherhost = true;
|
||||
}
|
||||
|
||||
nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
|
||||
nf_bridge->in_prerouting = 1;
|
||||
nf_bridge->physindev = skb->dev;
|
||||
skb->dev = brnf_get_logical_dev(skb, skb->dev);
|
||||
|
||||
|
@ -850,10 +850,8 @@ static unsigned int ip_sabotage_in(const struct nf_hook_ops *ops,
|
|||
struct sk_buff *skb,
|
||||
const struct nf_hook_state *state)
|
||||
{
|
||||
if (skb->nf_bridge &&
|
||||
!(skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) {
|
||||
if (skb->nf_bridge && !skb->nf_bridge->in_prerouting)
|
||||
return NF_STOP;
|
||||
}
|
||||
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
@ -872,7 +870,7 @@ static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
|
|||
struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
|
||||
|
||||
skb_pull(skb, ETH_HLEN);
|
||||
nf_bridge->mask &= ~BRNF_BRIDGED_DNAT;
|
||||
nf_bridge->bridged_dnat = 0;
|
||||
|
||||
BUILD_BUG_ON(sizeof(nf_bridge->neigh_header) != (ETH_HLEN - ETH_ALEN));
|
||||
|
||||
|
@ -887,7 +885,7 @@ static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
|
|||
|
||||
static int br_nf_dev_xmit(struct sk_buff *skb)
|
||||
{
|
||||
if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) {
|
||||
if (skb->nf_bridge && skb->nf_bridge->bridged_dnat) {
|
||||
br_nf_pre_routing_finish_bridge_slow(skb);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ static int br_nf_pre_routing_finish_ipv6(struct sock *sk, struct sk_buff *skb)
|
|||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
nf_bridge->pkt_otherhost = false;
|
||||
}
|
||||
nf_bridge->mask &= ~BRNF_NF_BRIDGE_PREROUTING;
|
||||
nf_bridge->in_prerouting = 0;
|
||||
if (br_nf_ipv6_daddr_was_changed(skb, nf_bridge)) {
|
||||
skb_dst_drop(skb);
|
||||
v6ops->route_input(skb);
|
||||
|
|
|
@ -49,12 +49,9 @@ static enum ip_defrag_users nf_ct_defrag_user(unsigned int hooknum,
|
|||
if (skb->nfct)
|
||||
zone = nf_ct_zone((struct nf_conn *)skb->nfct);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
|
||||
if (skb->nf_bridge &&
|
||||
skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
|
||||
if (nf_bridge_in_prerouting(skb))
|
||||
return IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
|
||||
#endif
|
||||
|
||||
if (hooknum == NF_INET_PRE_ROUTING)
|
||||
return IP_DEFRAG_CONNTRACK_IN + zone;
|
||||
else
|
||||
|
|
|
@ -39,12 +39,9 @@ static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
|
|||
if (skb->nfct)
|
||||
zone = nf_ct_zone((struct nf_conn *)skb->nfct);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
|
||||
if (skb->nf_bridge &&
|
||||
skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
|
||||
if (nf_bridge_in_prerouting(skb))
|
||||
return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
|
||||
#endif
|
||||
|
||||
if (hooknum == NF_INET_PRE_ROUTING)
|
||||
return IP6_DEFRAG_CONNTRACK_IN + zone;
|
||||
else
|
||||
|
|
Загрузка…
Ссылка в новой задаче