netfilter: nft_fib: Support existence check
[linux-2.6-microblaze.git] / net / netfilter / nft_fib.c
index fd0b193..21df8cc 100644 (file)
@@ -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)
@@ -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);