netfilter: nf_tables: remove xt_action_param from nft_pktinfo

Init it on demand in the nft_compat expression.  This reduces size
of nft_pktinfo from 48 to 24 bytes on x86_64.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Florian Westphal 2021-05-28 12:30:08 +02:00 коммит произвёл Pablo Neira Ayuso
Родитель f06ad944b6
Коммит 897389de48
4 изменённых файлов: 43 добавлений и 34 удалений

Просмотреть файл

@ -23,45 +23,46 @@ struct module;
struct nft_pktinfo {
struct sk_buff *skb;
const struct nf_hook_state *state;
bool tprot_set;
u8 tprot;
/* for x_tables compatibility */
struct xt_action_param xt;
u16 fragoff;
unsigned int thoff;
};
static inline struct sock *nft_sk(const struct nft_pktinfo *pkt)
{
return pkt->xt.state->sk;
return pkt->state->sk;
}
static inline unsigned int nft_thoff(const struct nft_pktinfo *pkt)
{
return pkt->xt.thoff;
return pkt->thoff;
}
static inline struct net *nft_net(const struct nft_pktinfo *pkt)
{
return pkt->xt.state->net;
return pkt->state->net;
}
static inline unsigned int nft_hook(const struct nft_pktinfo *pkt)
{
return pkt->xt.state->hook;
return pkt->state->hook;
}
static inline u8 nft_pf(const struct nft_pktinfo *pkt)
{
return pkt->xt.state->pf;
return pkt->state->pf;
}
static inline const struct net_device *nft_in(const struct nft_pktinfo *pkt)
{
return pkt->xt.state->in;
return pkt->state->in;
}
static inline const struct net_device *nft_out(const struct nft_pktinfo *pkt)
{
return pkt->xt.state->out;
return pkt->state->out;
}
static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
@ -69,15 +70,15 @@ static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
const struct nf_hook_state *state)
{
pkt->skb = skb;
pkt->xt.state = state;
pkt->state = state;
}
static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt)
{
pkt->tprot_set = false;
pkt->tprot = 0;
pkt->xt.thoff = 0;
pkt->xt.fragoff = 0;
pkt->thoff = 0;
pkt->fragoff = 0;
}
/**

Просмотреть файл

@ -12,8 +12,8 @@ static inline void nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt)
ip = ip_hdr(pkt->skb);
pkt->tprot_set = true;
pkt->tprot = ip->protocol;
pkt->xt.thoff = ip_hdrlen(pkt->skb);
pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
pkt->thoff = ip_hdrlen(pkt->skb);
pkt->fragoff = ntohs(ip->frag_off) & IP_OFFSET;
}
static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)
@ -38,8 +38,8 @@ static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)
pkt->tprot_set = true;
pkt->tprot = iph->protocol;
pkt->xt.thoff = thoff;
pkt->xt.fragoff = ntohs(iph->frag_off) & IP_OFFSET;
pkt->thoff = thoff;
pkt->fragoff = ntohs(iph->frag_off) & IP_OFFSET;
return 0;
}
@ -73,8 +73,8 @@ static inline int nft_set_pktinfo_ipv4_ingress(struct nft_pktinfo *pkt)
pkt->tprot_set = true;
pkt->tprot = iph->protocol;
pkt->xt.thoff = thoff;
pkt->xt.fragoff = ntohs(iph->frag_off) & IP_OFFSET;
pkt->thoff = thoff;
pkt->fragoff = ntohs(iph->frag_off) & IP_OFFSET;
return 0;

Просмотреть файл

@ -20,8 +20,8 @@ static inline void nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt)
pkt->tprot_set = true;
pkt->tprot = protohdr;
pkt->xt.thoff = thoff;
pkt->xt.fragoff = frag_off;
pkt->thoff = thoff;
pkt->fragoff = frag_off;
}
static inline int __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt)
@ -52,8 +52,8 @@ static inline int __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt)
pkt->tprot_set = true;
pkt->tprot = protohdr;
pkt->xt.thoff = thoff;
pkt->xt.fragoff = frag_off;
pkt->thoff = thoff;
pkt->fragoff = frag_off;
return 0;
#else
@ -98,8 +98,8 @@ static inline int nft_set_pktinfo_ipv6_ingress(struct nft_pktinfo *pkt)
pkt->tprot_set = true;
pkt->tprot = protohdr;
pkt->xt.thoff = thoff;
pkt->xt.fragoff = frag_off;
pkt->thoff = thoff;
pkt->fragoff = frag_off;
return 0;

Просмотреть файл

@ -57,8 +57,13 @@ union nft_entry {
};
static inline void
nft_compat_set_par(struct xt_action_param *par, void *xt, const void *xt_info)
nft_compat_set_par(struct xt_action_param *par,
const struct nft_pktinfo *pkt,
const void *xt, const void *xt_info)
{
par->state = pkt->state;
par->thoff = nft_thoff(pkt);
par->fragoff = pkt->fragoff;
par->target = xt;
par->targinfo = xt_info;
par->hotdrop = false;
@ -71,13 +76,14 @@ static void nft_target_eval_xt(const struct nft_expr *expr,
void *info = nft_expr_priv(expr);
struct xt_target *target = expr->ops->data;
struct sk_buff *skb = pkt->skb;
struct xt_action_param xt;
int ret;
nft_compat_set_par((struct xt_action_param *)&pkt->xt, target, info);
nft_compat_set_par(&xt, pkt, target, info);
ret = target->target(skb, &pkt->xt);
ret = target->target(skb, &xt);
if (pkt->xt.hotdrop)
if (xt.hotdrop)
ret = NF_DROP;
switch (ret) {
@ -97,13 +103,14 @@ static void nft_target_eval_bridge(const struct nft_expr *expr,
void *info = nft_expr_priv(expr);
struct xt_target *target = expr->ops->data;
struct sk_buff *skb = pkt->skb;
struct xt_action_param xt;
int ret;
nft_compat_set_par((struct xt_action_param *)&pkt->xt, target, info);
nft_compat_set_par(&xt, pkt, target, info);
ret = target->target(skb, &pkt->xt);
ret = target->target(skb, &xt);
if (pkt->xt.hotdrop)
if (xt.hotdrop)
ret = NF_DROP;
switch (ret) {
@ -350,13 +357,14 @@ static void __nft_match_eval(const struct nft_expr *expr,
{
struct xt_match *match = expr->ops->data;
struct sk_buff *skb = pkt->skb;
struct xt_action_param xt;
bool ret;
nft_compat_set_par((struct xt_action_param *)&pkt->xt, match, info);
nft_compat_set_par(&xt, pkt, match, info);
ret = match->match(skb, (struct xt_action_param *)&pkt->xt);
ret = match->match(skb, &xt);
if (pkt->xt.hotdrop) {
if (xt.hotdrop) {
regs->verdict.code = NF_DROP;
return;
}