netfilter: nft_fib: Support existence check
Instead of the actual interface index or name, set destination register to just 1 or 0 depending on whether the lookup succeeded or not if NFTA_FIB_F_PRESENT was set in userspace. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Родитель
1a64edf54f
Коммит
055c4b34b9
|
@ -32,6 +32,6 @@ void nft_fib6_eval_type(const struct nft_expr *expr, struct nft_regs *regs,
|
||||||
void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
|
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, enum nft_fib_result r,
|
void nft_fib_store_result(void *reg, const struct nft_fib *priv,
|
||||||
const struct nft_pktinfo *pkt, int index);
|
const struct nft_pktinfo *pkt, int index);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1257,6 +1257,7 @@ enum nft_fib_flags {
|
||||||
NFTA_FIB_F_MARK = 1 << 2, /* use skb->mark */
|
NFTA_FIB_F_MARK = 1 << 2, /* use skb->mark */
|
||||||
NFTA_FIB_F_IIF = 1 << 3, /* restrict to iif */
|
NFTA_FIB_F_IIF = 1 << 3, /* restrict to iif */
|
||||||
NFTA_FIB_F_OIF = 1 << 4, /* restrict to oif */
|
NFTA_FIB_F_OIF = 1 << 4, /* restrict to oif */
|
||||||
|
NFTA_FIB_F_PRESENT = 1 << 5, /* check existence only */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum nft_ct_helper_attributes {
|
enum nft_ct_helper_attributes {
|
||||||
|
|
|
@ -90,7 +90,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->result, pkt,
|
nft_fib_store_result(dest, priv, pkt,
|
||||||
nft_in(pkt)->ifindex);
|
nft_in(pkt)->ifindex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,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->result, pkt,
|
nft_fib_store_result(dest, priv, pkt,
|
||||||
get_ifindex(pkt->skb->dev));
|
get_ifindex(pkt->skb->dev));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,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->result, pkt,
|
nft_fib_store_result(dest, priv, pkt,
|
||||||
nft_in(pkt)->ifindex);
|
nft_in(pkt)->ifindex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,8 @@ const struct nla_policy nft_fib_policy[NFTA_FIB_MAX + 1] = {
|
||||||
EXPORT_SYMBOL(nft_fib_policy);
|
EXPORT_SYMBOL(nft_fib_policy);
|
||||||
|
|
||||||
#define NFTA_FIB_F_ALL (NFTA_FIB_F_SADDR | NFTA_FIB_F_DADDR | \
|
#define NFTA_FIB_F_ALL (NFTA_FIB_F_SADDR | NFTA_FIB_F_DADDR | \
|
||||||
NFTA_FIB_F_MARK | NFTA_FIB_F_IIF | NFTA_FIB_F_OIF)
|
NFTA_FIB_F_MARK | NFTA_FIB_F_IIF | NFTA_FIB_F_OIF | \
|
||||||
|
NFTA_FIB_F_PRESENT)
|
||||||
|
|
||||||
int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
||||||
const struct nft_data **data)
|
const struct nft_data **data)
|
||||||
|
@ -133,19 +134,22 @@ 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, enum nft_fib_result r,
|
void nft_fib_store_result(void *reg, const struct nft_fib *priv,
|
||||||
const struct nft_pktinfo *pkt, int index)
|
const struct nft_pktinfo *pkt, int index)
|
||||||
{
|
{
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
u32 *dreg = reg;
|
u32 *dreg = reg;
|
||||||
|
|
||||||
switch (r) {
|
switch (priv->result) {
|
||||||
case NFT_FIB_RESULT_OIF:
|
case NFT_FIB_RESULT_OIF:
|
||||||
*dreg = 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);
|
dev = dev_get_by_index_rcu(nft_net(pkt), index);
|
||||||
strncpy(reg, dev ? dev->name : "", IFNAMSIZ);
|
if (priv->flags & NFTA_FIB_F_PRESENT)
|
||||||
|
*dreg = !!dev;
|
||||||
|
else
|
||||||
|
strncpy(reg, dev ? dev->name : "", IFNAMSIZ);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WARN_ON_ONCE(1);
|
WARN_ON_ONCE(1);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче