OSDN Git Service

netfilter: nft_fib: Fix existence check support
authorPhil Sutter <phil@nwl.cc>
Wed, 15 May 2019 18:15:32 +0000 (20:15 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 21 May 2019 14:10:38 +0000 (16:10 +0200)
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: 055c4b34b94f6 ("netfilter: nft_fib: Support existence check")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/nft_fib.h
net/ipv4/netfilter/nft_fib_ipv4.c
net/ipv6/netfilter/nft_fib_ipv6.c
net/netfilter/nft_fib.c

index a88f927..e4c4d8e 100644 (file)
@@ -34,5 +34,5 @@ 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, const struct nft_fib *priv,
-                         const struct nft_pktinfo *pkt, int index);
+                         const struct net_device *dev);
 #endif
index 94eb25b..c8888e5 100644 (file)
@@ -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);
 
-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,
                   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 &&
            nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
-               nft_fib_store_result(dest, priv, pkt,
-                                    nft_in(pkt)->ifindex);
+               nft_fib_store_result(dest, priv, nft_in(pkt));
                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_lbcast(iph->daddr) ||
                    ipv4_is_local_multicast(iph->daddr)) {
-                       nft_fib_store_result(dest, priv, pkt,
-                                            get_ifindex(pkt->skb->dev));
+                       nft_fib_store_result(dest, priv, pkt->skb->dev);
                        return;
                }
        }
@@ -150,17 +143,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
                found = oif;
        }
 
-       switch (priv->result) {
-       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;
-       }
+       nft_fib_store_result(dest, priv, found);
 }
 EXPORT_SYMBOL_GPL(nft_fib4_eval);
 
index 73cdc0b..ec068b0 100644 (file)
@@ -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 &&
            nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
-               nft_fib_store_result(dest, priv, pkt,
-                                    nft_in(pkt)->ifindex);
+               nft_fib_store_result(dest, priv, nft_in(pkt));
                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)
                goto put_rt_err;
 
-       switch (priv->result) {
-       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;
-       }
-
+       nft_fib_store_result(dest, priv, rt->rt6i_idev->dev);
  put_rt_err:
        ip6_rt_put(rt);
 }
index 21df8cc..77f00a9 100644 (file)
@@ -135,17 +135,17 @@ 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, const struct nft_fib *priv,
-                         const struct nft_pktinfo *pkt, int index)
+                         const struct net_device *dev)
 {
-       struct net_device *dev;
        u32 *dreg = reg;
+       int index;
 
        switch (priv->result) {
        case NFT_FIB_RESULT_OIF:
+               index = dev ? dev->ifindex : 0;
                *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);
                if (priv->flags & NFTA_FIB_F_PRESENT)
                        *dreg = !!dev;
                else