Commit e633508a authored by Phil Sutter's avatar Phil Sutter Committed by Pablo Neira Ayuso

netfilter: nft_fib: Fix existence check support

NFTA_FIB_F_PRESENT flag was not always honored since eval functions did
not call nft_fib_store_result in all cases.

Given that in all callsites there is a struct net_device pointer
available which holds the interface data to be stored in destination
register, simplify nft_fib_store_result() to just accept that pointer
instead of the nft_pktinfo pointer and interface index. This also
allows to drop the index to interface lookup previously needed to get
the name associated with given index.

Fixes: 055c4b34 ("netfilter: nft_fib: Support existence check")
Signed-off-by: default avatarPhil Sutter <phil@nwl.cc>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 946c0d8e
...@@ -34,5 +34,5 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, ...@@ -34,5 +34,5 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
const struct nft_pktinfo *pkt); const struct nft_pktinfo *pkt);
void nft_fib_store_result(void *reg, const struct nft_fib *priv, void nft_fib_store_result(void *reg, const struct nft_fib *priv,
const struct nft_pktinfo *pkt, int index); const struct net_device *dev);
#endif #endif
...@@ -58,11 +58,6 @@ void nft_fib4_eval_type(const struct nft_expr *expr, struct nft_regs *regs, ...@@ -58,11 +58,6 @@ void nft_fib4_eval_type(const struct nft_expr *expr, struct nft_regs *regs,
} }
EXPORT_SYMBOL_GPL(nft_fib4_eval_type); EXPORT_SYMBOL_GPL(nft_fib4_eval_type);
static int get_ifindex(const struct net_device *dev)
{
return dev ? dev->ifindex : 0;
}
void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs, void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
const struct nft_pktinfo *pkt) const struct nft_pktinfo *pkt)
{ {
...@@ -94,8 +89,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs, ...@@ -94,8 +89,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
if (nft_hook(pkt) == NF_INET_PRE_ROUTING && if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
nft_fib_is_loopback(pkt->skb, nft_in(pkt))) { nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
nft_fib_store_result(dest, priv, pkt, nft_fib_store_result(dest, priv, nft_in(pkt));
nft_in(pkt)->ifindex);
return; return;
} }
...@@ -108,8 +102,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs, ...@@ -108,8 +102,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
if (ipv4_is_zeronet(iph->saddr)) { if (ipv4_is_zeronet(iph->saddr)) {
if (ipv4_is_lbcast(iph->daddr) || if (ipv4_is_lbcast(iph->daddr) ||
ipv4_is_local_multicast(iph->daddr)) { ipv4_is_local_multicast(iph->daddr)) {
nft_fib_store_result(dest, priv, pkt, nft_fib_store_result(dest, priv, pkt->skb->dev);
get_ifindex(pkt->skb->dev));
return; return;
} }
} }
...@@ -150,17 +143,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs, ...@@ -150,17 +143,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
found = oif; found = oif;
} }
switch (priv->result) { nft_fib_store_result(dest, priv, found);
case NFT_FIB_RESULT_OIF:
*dest = found->ifindex;
break;
case NFT_FIB_RESULT_OIFNAME:
strncpy((char *)dest, found->name, IFNAMSIZ);
break;
default:
WARN_ON_ONCE(1);
break;
}
} }
EXPORT_SYMBOL_GPL(nft_fib4_eval); EXPORT_SYMBOL_GPL(nft_fib4_eval);
......
...@@ -169,8 +169,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, ...@@ -169,8 +169,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
if (nft_hook(pkt) == NF_INET_PRE_ROUTING && if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
nft_fib_is_loopback(pkt->skb, nft_in(pkt))) { nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
nft_fib_store_result(dest, priv, pkt, nft_fib_store_result(dest, priv, nft_in(pkt));
nft_in(pkt)->ifindex);
return; return;
} }
...@@ -187,18 +186,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, ...@@ -187,18 +186,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
if (oif && oif != rt->rt6i_idev->dev) if (oif && oif != rt->rt6i_idev->dev)
goto put_rt_err; goto put_rt_err;
switch (priv->result) { nft_fib_store_result(dest, priv, rt->rt6i_idev->dev);
case NFT_FIB_RESULT_OIF:
*dest = rt->rt6i_idev->dev->ifindex;
break;
case NFT_FIB_RESULT_OIFNAME:
strncpy((char *)dest, rt->rt6i_idev->dev->name, IFNAMSIZ);
break;
default:
WARN_ON_ONCE(1);
break;
}
put_rt_err: put_rt_err:
ip6_rt_put(rt); ip6_rt_put(rt);
} }
......
...@@ -135,17 +135,17 @@ int nft_fib_dump(struct sk_buff *skb, const struct nft_expr *expr) ...@@ -135,17 +135,17 @@ int nft_fib_dump(struct sk_buff *skb, const struct nft_expr *expr)
EXPORT_SYMBOL_GPL(nft_fib_dump); EXPORT_SYMBOL_GPL(nft_fib_dump);
void nft_fib_store_result(void *reg, const struct nft_fib *priv, void nft_fib_store_result(void *reg, const struct nft_fib *priv,
const struct nft_pktinfo *pkt, int index) const struct net_device *dev)
{ {
struct net_device *dev;
u32 *dreg = reg; u32 *dreg = reg;
int index;
switch (priv->result) { switch (priv->result) {
case NFT_FIB_RESULT_OIF: case NFT_FIB_RESULT_OIF:
index = dev ? dev->ifindex : 0;
*dreg = (priv->flags & NFTA_FIB_F_PRESENT) ? !!index : index; *dreg = (priv->flags & NFTA_FIB_F_PRESENT) ? !!index : index;
break; break;
case NFT_FIB_RESULT_OIFNAME: case NFT_FIB_RESULT_OIFNAME:
dev = dev_get_by_index_rcu(nft_net(pkt), index);
if (priv->flags & NFTA_FIB_F_PRESENT) if (priv->flags & NFTA_FIB_F_PRESENT)
*dreg = !!dev; *dreg = !!dev;
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment