Skip to content
This repository has been archived by the owner on Sep 24, 2020. It is now read-only.

Commit

Permalink
netfilter: nft_fib: Support existence check
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Phil Sutter authored and ummakynes committed Mar 13, 2017
1 parent 1a64edf commit 055c4b3
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 9 deletions.
2 changes: 1 addition & 1 deletion include/net/netfilter/nft_fib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
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);
#endif
1 change: 1 addition & 0 deletions include/uapi/linux/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,7 @@ enum nft_fib_flags {
NFTA_FIB_F_MARK = 1 << 2, /* use skb->mark */
NFTA_FIB_F_IIF = 1 << 3, /* restrict to iif */
NFTA_FIB_F_OIF = 1 << 4, /* restrict to oif */
NFTA_FIB_F_PRESENT = 1 << 5, /* check existence only */
};

enum nft_ct_helper_attributes {
Expand Down
4 changes: 2 additions & 2 deletions net/ipv4/netfilter/nft_fib_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
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);
return;
}
Expand All @@ -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_lbcast(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));
return;
}
Expand Down
2 changes: 1 addition & 1 deletion net/ipv6/netfilter/nft_fib_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
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);
return;
}
Expand Down
14 changes: 9 additions & 5 deletions net/netfilter/nft_fib.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ const struct nla_policy nft_fib_policy[NFTA_FIB_MAX + 1] = {
EXPORT_SYMBOL(nft_fib_policy);

#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,
const struct nft_data **data)
Expand Down Expand Up @@ -133,19 +134,22 @@ int nft_fib_dump(struct sk_buff *skb, const struct nft_expr *expr)
}
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)
{
struct net_device *dev;
u32 *dreg = reg;

switch (r) {
switch (priv->result) {
case NFT_FIB_RESULT_OIF:
*dreg = index;
*dreg = (priv->flags & NFTA_FIB_F_PRESENT) ? !!index : index;
break;
case NFT_FIB_RESULT_OIFNAME:
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;
default:
WARN_ON_ONCE(1);
Expand Down

0 comments on commit 055c4b3

Please sign in to comment.