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: 055c4b34b9
("netfilter: nft_fib: Support existence check")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Родитель
946c0d8e6e
Коммит
e633508a95
|
@ -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,
|
||||||
}
|
}
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
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)
|
||||||
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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче