[v2] vrf: Fix conntrack-dnat conflict in vrf-device PREROUTING hook

Message ID 1547186027-3607-1-git-send-email-wenxu@ucloud.cn
State Changes Requested
Delegated to: David Miller
Headers show
Series
  • [v2] vrf: Fix conntrack-dnat conflict in vrf-device PREROUTING hook
Related show

Commit Message

wenxu Jan. 11, 2019, 5:53 a.m.
From: wenxu <wenxu@ucloud.cn>

In the ip_rcv the skb go through the PREROUTING hook first,
Then jump in vrf device go through the same hook again.
When conntrack dnat work with vrf, there will be some conflict for rules.
Because the package go through the hook twice with different nf status

ip link add user1 type vrf table 1
ip link add user2 type vrf table 2
ip l set dev tun1 master user1
ip l set dev tun2 master user2

nft add table firewall
nft add chain firewall zones { type filter hook prerouting  priority - 300 \; }
nft add rule firewall zones counter ct zone set iif map { "tun1" : 1, "tun2" : 2 }
nft add chain firewall rule-1000-ingress
nft add rule firewall rule-1000-ingress ct zone 1 tcp dport 22 ct state new counter accept
nft add rule firewall rule-1000-ingress counter drop
nft add chain firewall rule-1000-egress
nft add rule firewall rule-1000-egress tcp dport 22 ct state new counter drop
nft add rule firewall rule-1000-egress counter accept

nft add chain firewall rules-all { type filter hook prerouting priority - 150 \; }
nft add rule firewall rules-all ip daddr vmap { "2.2.2.11" : jump rule-1000-ingress }
nft add rule firewall rules-all ct zone vmap { 1 : jump rule-1000-egress }

nft add rule firewall dnat-all ct zone vmap { 1 : jump dnat-1000 }
nft add rule firewall dnat-1000 ip daddr 2.2.2.11 counter dnat to 10.0.0.7

For a package with ip daddr 2.2.2.11 and tcp dport 22, first time accept in the
rule-1000-ingress and dnat to 10.0.0.7. Then second time the packet goto the wrong
chain rule-1000-egress which leads the packet drop

So This patch avoid already dnat packet go through the prerouting hook for the
second time.

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 drivers/net/vrf.c | 7 +++++++
 1 file changed, 7 insertions(+)

Comments

David Ahern Jan. 11, 2019, 3:30 p.m. | #1
On 1/10/19 10:53 PM, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> In the ip_rcv the skb go through the PREROUTING hook first,
> Then jump in vrf device go through the same hook again.
> When conntrack dnat work with vrf, there will be some conflict for rules.
> Because the package go through the hook twice with different nf status
> 
> ip link add user1 type vrf table 1
> ip link add user2 type vrf table 2
> ip l set dev tun1 master user1
> ip l set dev tun2 master user2
> 
> nft add table firewall
> nft add chain firewall zones { type filter hook prerouting  priority - 300 \; }
> nft add rule firewall zones counter ct zone set iif map { "tun1" : 1, "tun2" : 2 }
> nft add chain firewall rule-1000-ingress
> nft add rule firewall rule-1000-ingress ct zone 1 tcp dport 22 ct state new counter accept
> nft add rule firewall rule-1000-ingress counter drop
> nft add chain firewall rule-1000-egress
> nft add rule firewall rule-1000-egress tcp dport 22 ct state new counter drop
> nft add rule firewall rule-1000-egress counter accept
> 
> nft add chain firewall rules-all { type filter hook prerouting priority - 150 \; }
> nft add rule firewall rules-all ip daddr vmap { "2.2.2.11" : jump rule-1000-ingress }
> nft add rule firewall rules-all ct zone vmap { 1 : jump rule-1000-egress }
> 
> nft add rule firewall dnat-all ct zone vmap { 1 : jump dnat-1000 }
> nft add rule firewall dnat-1000 ip daddr 2.2.2.11 counter dnat to 10.0.0.7
> 
> For a package with ip daddr 2.2.2.11 and tcp dport 22, first time accept in the
> rule-1000-ingress and dnat to 10.0.0.7. Then second time the packet goto the wrong
> chain rule-1000-egress which leads the packet drop
> 
> So This patch avoid already dnat packet go through the prerouting hook for the
> second time.
> 
> Signed-off-by: wenxu <wenxu@ucloud.cn>
> ---
>  drivers/net/vrf.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
> index 95909e2..e61a045 100644
> --- a/drivers/net/vrf.c
> +++ b/drivers/net/vrf.c
> @@ -37,6 +37,7 @@
>  #include <net/l3mdev.h>
>  #include <net/fib_rules.h>
>  #include <net/netns/generic.h>
> +#include <net/netfilter/nf_conntrack.h>
>  
>  #define DRV_NAME	"vrf"
>  #define DRV_VERSION	"1.0"
> @@ -898,6 +899,12 @@ static struct sk_buff *vrf_rcv_nfhook(u8 pf, unsigned int hook,
>  				      struct net_device *dev)
>  {
>  	struct net *net = dev_net(dev);
> +	enum ip_conntrack_info ctinfo;
> +	struct nf_conn *ct;
> +
> +	ct = nf_ct_get(skb, &ctinfo);
> +	if (ct && (ct->status & IPS_DST_NAT))
> +		return skb;
>  
>  	if (nf_hook(pf, hook, net, NULL, skb, dev, NULL, vrf_rcv_finish) != 1)
>  		skb = NULL;    /* kfree_skb(skb) handled by nf code */
> 

That looks better to me. I am not familiar enough with netfilter
internals to know if this is acceptable; you should cc the netfilter
list to get opinions.

And for this to go into net and back to stable releases, you need a
Fixes tag:

Fixes: 73e20b761acf8 ("net: vrf: Add support for PREROUTING rules on vrf
device")
kbuild test robot Jan. 11, 2019, 5:47 p.m. | #2
Hi wenxu,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]
[also build test ERROR on v5.0-rc1 next-20190111]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/wenxu-ucloud-cn/vrf-Fix-conntrack-dnat-conflict-in-vrf-device-PREROUTING-hook/20190111-151714
config: x86_64-lkp (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

   In file included from include/net/netfilter/nf_conntrack_tuple.h:14:0,
                    from include/linux/netfilter/nf_conntrack_proto_gre.h:14,
                    from include/net/netfilter/nf_conntrack.h:25,
                    from drivers//net/vrf.c:40:
   include/linux/netfilter/x_tables.h: In function 'xt_net':
>> include/linux/netfilter/x_tables.h:46:19: error: dereferencing pointer to incomplete type 'const struct nf_hook_state'
     return par->state->net;
                      ^~
   In file included from include/net/netfilter/nf_conntrack_tuple.h:14:0,
                    from include/linux/netfilter/nf_conntrack_proto_gre.h:14,
                    from include/net/netfilter/nf_conntrack.h:25,
                    from drivers//net/vrf.c:40:
   include/linux/netfilter/x_tables.h: At top level:
>> include/linux/netfilter/x_tables.h:450:64: error: unknown type name 'nf_hookfn'
    struct nf_hook_ops *xt_hook_ops_alloc(const struct xt_table *, nf_hookfn *);
                                                                   ^~~~~~~~~
   In file included from include/linux/netfilter/nf_conntrack_proto_gre.h:14:0,
                    from include/net/netfilter/nf_conntrack.h:25,
                    from drivers//net/vrf.c:40:
   include/net/netfilter/nf_conntrack_tuple.h: In function '__nf_ct_tuple_src_equal':
>> include/net/netfilter/nf_conntrack_tuple.h:127:10: error: implicit declaration of function 'nf_inet_addr_cmp'; did you mean 'inet_addr_type'? [-Werror=implicit-function-declaration]
     return (nf_inet_addr_cmp(&t1->src.u3, &t2->src.u3) &&
             ^~~~~~~~~~~~~~~~
             inet_addr_type
   In file included from include/net/netfilter/nf_conntrack.h:25:0,
                    from drivers//net/vrf.c:40:
   include/linux/netfilter/nf_conntrack_proto_gre.h: At top level:
>> include/linux/netfilter/nf_conntrack_proto_gre.h:31:22: error: field 'nf' has incomplete type
     struct nf_proto_net nf;
                         ^~
   In file included from drivers//net/vrf.c:40:0:
>> include/net/netfilter/nf_conntrack.h:69:22: error: field 'ct_general' has incomplete type
     struct nf_conntrack ct_general;
                         ^~~~~~~~~~
   include/net/netfilter/nf_conntrack.h: In function 'nf_ct_get':
>> include/net/netfilter/nf_conntrack.h:158:15: error: 'const struct sk_buff' has no member named '_nfct'
     *ctinfo = skb->_nfct & NFCT_INFOMASK;
                  ^~
   include/net/netfilter/nf_conntrack.h:160:31: error: 'const struct sk_buff' has no member named '_nfct'
     return (struct nf_conn *)(skb->_nfct & NFCT_PTRMASK);
                                  ^~
   include/net/netfilter/nf_conntrack.h: In function 'nf_ct_put':
>> include/net/netfilter/nf_conntrack.h:167:2: error: implicit declaration of function 'nf_conntrack_put'; did you mean 'nf_ct_put'? [-Werror=implicit-function-declaration]
     nf_conntrack_put(&ct->ct_general);
     ^~~~~~~~~~~~~~~~
     nf_ct_put
   include/net/netfilter/nf_conntrack.h: In function 'nf_ct_set':
>> include/net/netfilter/nf_conntrack.h:324:5: error: 'struct sk_buff' has no member named '_nfct'
     skb->_nfct = (unsigned long)ct | info;
        ^~
   include/net/netfilter/nf_conntrack.h: In function 'nf_ct_get':
>> include/net/netfilter/nf_conntrack.h:161:1: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^
   cc1: some warnings being treated as errors

vim +/ct_general +69 include/net/netfilter/nf_conntrack.h

9fb9cbb10 Yasuyuki Kozakai       2005-11-09   21  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   22  #include <linux/netfilter/nf_conntrack_tcp.h>
2bc780499 Patrick McHardy        2008-03-20   23  #include <linux/netfilter/nf_conntrack_dccp.h>
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   24  #include <linux/netfilter/nf_conntrack_sctp.h>
f09943fef Patrick McHardy        2006-12-02  @25  #include <linux/netfilter/nf_conntrack_proto_gre.h>
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   26  #include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   27  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   28  #include <net/netfilter/nf_conntrack_tuple.h>
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   29  
d535c8a69 Florian Westphal       2018-12-06   30  struct nf_ct_udp {
d535c8a69 Florian Westphal       2018-12-06   31  	unsigned long	stream_ts;
d535c8a69 Florian Westphal       2018-12-06   32  };
d535c8a69 Florian Westphal       2018-12-06   33  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   34  /* per conntrack: protocol private data */
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   35  union nf_conntrack_proto {
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   36  	/* insert conntrack proto private data here */
2bc780499 Patrick McHardy        2008-03-20   37  	struct nf_ct_dccp dccp;
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   38  	struct ip_ct_sctp sctp;
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   39  	struct ip_ct_tcp tcp;
d535c8a69 Florian Westphal       2018-12-06   40  	struct nf_ct_udp udp;
f09943fef Patrick McHardy        2006-12-02   41  	struct nf_ct_gre gre;
c74454fad Florian Westphal       2017-01-23   42  	unsigned int tmpl_padto;
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   43  };
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   44  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   45  union nf_conntrack_expect_proto {
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   46  	/* insert expect proto private data here */
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   47  };
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   48  
a0ae2562c Florian Westphal       2018-06-29   49  struct nf_conntrack_net {
a0ae2562c Florian Westphal       2018-06-29   50  	unsigned int users4;
a0ae2562c Florian Westphal       2018-06-29   51  	unsigned int users6;
a0ae2562c Florian Westphal       2018-06-29   52  };
a0ae2562c Florian Westphal       2018-06-29   53  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   54  #include <linux/types.h>
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   55  #include <linux/skbuff.h>
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   56  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   57  #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
f8eb24a89 Patrick McHardy        2006-11-29   58  #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
f8eb24a89 Patrick McHardy        2006-11-29   59  
ea781f197 Eric Dumazet           2009-03-25   60  struct nf_conn {
f330a7fdb Florian Westphal       2016-08-25   61  	/* Usage count in here is 1 for hash table, 1 per skb,
b476b72a0 Jesper Dangaard Brouer 2014-03-03   62  	 * plus 1 for any connection(s) we are `master' for
b476b72a0 Jesper Dangaard Brouer 2014-03-03   63  	 *
a9e419dc7 Florian Westphal       2017-01-23   64  	 * Hint, SKB address this struct and refcnt via skb->_nfct and
b476b72a0 Jesper Dangaard Brouer 2014-03-03   65  	 * helpers nf_conntrack_get() and nf_conntrack_put().
b476b72a0 Jesper Dangaard Brouer 2014-03-03   66  	 * Helper nf_ct_put() equals nf_conntrack_put() by dec refcnt,
b476b72a0 Jesper Dangaard Brouer 2014-03-03   67  	 * beware nf_ct_get() is different and don't inc refcnt.
b476b72a0 Jesper Dangaard Brouer 2014-03-03   68  	 */
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  @69  	struct nf_conntrack ct_general;
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   70  
440f0d588 Patrick McHardy        2009-06-10   71  	spinlock_t	lock;
b7779d06f Jesper Dangaard Brouer 2014-03-03   72  	u16		cpu;
440f0d588 Patrick McHardy        2009-06-10   73  
6c8dee984 Florian Westphal       2016-06-11   74  #ifdef CONFIG_NF_CONNTRACK_ZONES
6c8dee984 Florian Westphal       2016-06-11   75  	struct nf_conntrack_zone zone;
6c8dee984 Florian Westphal       2016-06-11   76  #endif
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   77  	/* XXX should I move this to the tail ? - Y.K */
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   78  	/* These are my tuples; original and reply */
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   79  	struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   80  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   81  	/* Have we seen traffic both ways yet? (bitset) */
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   82  	unsigned long status;
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   83  
f330a7fdb Florian Westphal       2016-08-25   84  	/* jiffies32 when this ct is considered dead */
f330a7fdb Florian Westphal       2016-08-25   85  	u32 timeout;
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   86  
0c5c9fb55 Eric W. Biederman      2015-03-11   87  	possible_net_t ct_net;
0c5c9fb55 Eric W. Biederman      2015-03-11   88  
5173bc679 Florian Westphal       2016-11-23   89  #if IS_ENABLED(CONFIG_NF_NAT)
e1bf16877 Florian Westphal       2017-09-06   90  	struct hlist_node	nat_bysource;
5173bc679 Florian Westphal       2016-11-23   91  #endif
c41884ce0 Florian Westphal       2014-11-24   92  	/* all members below initialized via memset */
c41884ce0 Florian Westphal       2014-11-24   93  	u8 __nfct_init_offset[0];
c41884ce0 Florian Westphal       2014-11-24   94  
c41884ce0 Florian Westphal       2014-11-24   95  	/* If we were expected by an expectation, this will be it */
c41884ce0 Florian Westphal       2014-11-24   96  	struct nf_conn *master;
c41884ce0 Florian Westphal       2014-11-24   97  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   98  #if defined(CONFIG_NF_CONNTRACK_MARK)
9fb9cbb10 Yasuyuki Kozakai       2005-11-09   99  	u_int32_t mark;
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  100  #endif
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  101  
7c9728c39 James Morris           2006-06-09  102  #ifdef CONFIG_NF_CONNTRACK_SECMARK
7c9728c39 James Morris           2006-06-09  103  	u_int32_t secmark;
7c9728c39 James Morris           2006-06-09  104  #endif
7c9728c39 James Morris           2006-06-09  105  
ecfab2c9f Yasuyuki Kozakai       2007-07-07  106  	/* Extensions */
ecfab2c9f Yasuyuki Kozakai       2007-07-07  107  	struct nf_ct_ext *ext;
e5fc9e7a6 Changli Gao            2010-11-12  108  
e5fc9e7a6 Changli Gao            2010-11-12  109  	/* Storage reserved for other modules, must be the last member */
e5fc9e7a6 Changli Gao            2010-11-12  110  	union nf_conntrack_proto proto;
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  111  };
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  112  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  113  static inline struct nf_conn *
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  114  nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash)
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  115  {
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  116  	return container_of(hash, struct nf_conn,
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  117  			    tuplehash[hash->tuple.dst.dir]);
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  118  }
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  119  
5e8fbe2ac Patrick McHardy        2008-04-14  120  static inline u_int16_t nf_ct_l3num(const struct nf_conn *ct)
5e8fbe2ac Patrick McHardy        2008-04-14  121  {
5e8fbe2ac Patrick McHardy        2008-04-14  122  	return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
5e8fbe2ac Patrick McHardy        2008-04-14  123  }
5e8fbe2ac Patrick McHardy        2008-04-14  124  
5e8fbe2ac Patrick McHardy        2008-04-14  125  static inline u_int8_t nf_ct_protonum(const struct nf_conn *ct)
5e8fbe2ac Patrick McHardy        2008-04-14  126  {
5e8fbe2ac Patrick McHardy        2008-04-14  127  	return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
5e8fbe2ac Patrick McHardy        2008-04-14  128  }
5e8fbe2ac Patrick McHardy        2008-04-14  129  
f2f3e38c6 Pablo Neira Ayuso      2009-06-02  130  #define nf_ct_tuple(ct, dir) (&(ct)->tuplehash[dir].tuple)
f2f3e38c6 Pablo Neira Ayuso      2009-06-02  131  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  132  /* get master conntrack via master expectation */
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  133  #define master_ct(conntr) (conntr->master)
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  134  
5a1fb391d Alexey Dobriyan        2008-10-08  135  extern struct net init_net;
5a1fb391d Alexey Dobriyan        2008-10-08  136  
5a1fb391d Alexey Dobriyan        2008-10-08  137  static inline struct net *nf_ct_net(const struct nf_conn *ct)
5a1fb391d Alexey Dobriyan        2008-10-08  138  {
c2d9ba9bc Eric Dumazet           2010-06-01  139  	return read_pnet(&ct->ct_net);
5a1fb391d Alexey Dobriyan        2008-10-08  140  }
5a1fb391d Alexey Dobriyan        2008-10-08  141  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  142  /* Alter reply tuple (maybe alter helper). */
4e77be463 Joe Perches            2013-09-23  143  void nf_conntrack_alter_reply(struct nf_conn *ct,
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  144  			      const struct nf_conntrack_tuple *newreply);
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  145  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  146  /* Is this tuple taken? (ignoring any belonging to the given
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  147     conntrack). */
4e77be463 Joe Perches            2013-09-23  148  int nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  149  			     const struct nf_conn *ignored_conntrack);
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  150  
303223092 Florian Westphal       2017-01-23  151  #define NFCT_INFOMASK	7UL
a9e419dc7 Florian Westphal       2017-01-23  152  #define NFCT_PTRMASK	~(NFCT_INFOMASK)
303223092 Florian Westphal       2017-01-23  153  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  154  /* Return conntrack_info and tuple hash for given skb. */
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  155  static inline struct nf_conn *
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  156  nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  157  {
a9e419dc7 Florian Westphal       2017-01-23 @158  	*ctinfo = skb->_nfct & NFCT_INFOMASK;
a9e419dc7 Florian Westphal       2017-01-23  159  
a9e419dc7 Florian Westphal       2017-01-23 @160  	return (struct nf_conn *)(skb->_nfct & NFCT_PTRMASK);
9fb9cbb10 Yasuyuki Kozakai       2005-11-09 @161  }
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  162  
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  163  /* decrement reference count on a conntrack */
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  164  static inline void nf_ct_put(struct nf_conn *ct)
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  165  {
44d6e2f27 Varsha Rao             2017-08-30  166  	WARN_ON(!ct);
9fb9cbb10 Yasuyuki Kozakai       2005-11-09 @167  	nf_conntrack_put(&ct->ct_general);
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  168  }
9fb9cbb10 Yasuyuki Kozakai       2005-11-09  169  

:::::: The code at line 69 was first introduced by commit
:::::: 9fb9cbb1082d6b31fb45aa1a14432449a0df6cf1 [NETFILTER]: Add nf_conntrack subsystem.

:::::: TO: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
:::::: CC: David S. Miller <davem@davemloft.net>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kbuild test robot Jan. 13, 2019, 8:14 p.m. | #3
Hi wenxu,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]
[also build test ERROR on v5.0-rc1 next-20190111]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/wenxu-ucloud-cn/vrf-Fix-conntrack-dnat-conflict-in-vrf-device-PREROUTING-hook/20190111-151714
config: i386-randconfig-b0-01140058 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   In file included from include/net/netfilter/nf_conntrack.h:25:0,
                    from drivers/net/vrf.c:40:
   include/linux/netfilter/nf_conntrack_proto_gre.h:31:22: error: field 'nf' has incomplete type
     struct nf_proto_net nf;
                         ^
   In file included from drivers/net/vrf.c:40:0:
   include/net/netfilter/nf_conntrack.h:69:22: error: field 'ct_general' has incomplete type
     struct nf_conntrack ct_general;
                         ^
   include/net/netfilter/nf_conntrack.h: In function 'nf_ct_get':
   include/net/netfilter/nf_conntrack.h:158:15: error: 'const struct sk_buff' has no member named '_nfct'
     *ctinfo = skb->_nfct & NFCT_INFOMASK;
                  ^
   include/net/netfilter/nf_conntrack.h:160:31: error: 'const struct sk_buff' has no member named '_nfct'
     return (struct nf_conn *)(skb->_nfct & NFCT_PTRMASK);
                                  ^
   include/net/netfilter/nf_conntrack.h: In function 'nf_ct_put':
>> include/net/netfilter/nf_conntrack.h:167:2: error: implicit declaration of function 'nf_conntrack_put' [-Werror=implicit-function-declaration]
     nf_conntrack_put(&ct->ct_general);
     ^
   include/net/netfilter/nf_conntrack.h: In function 'nf_ct_set':
   include/net/netfilter/nf_conntrack.h:324:5: error: 'struct sk_buff' has no member named '_nfct'
     skb->_nfct = (unsigned long)ct | info;
        ^
   include/net/netfilter/nf_conntrack.h: In function 'nf_ct_get':
   include/net/netfilter/nf_conntrack.h:161:1: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^
   cc1: some warnings being treated as errors

vim +/nf_conntrack_put +167 include/net/netfilter/nf_conntrack.h

303223092 Florian Westphal 2017-01-23  153  
9fb9cbb10 Yasuyuki Kozakai 2005-11-09  154  /* Return conntrack_info and tuple hash for given skb. */
9fb9cbb10 Yasuyuki Kozakai 2005-11-09  155  static inline struct nf_conn *
9fb9cbb10 Yasuyuki Kozakai 2005-11-09  156  nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
9fb9cbb10 Yasuyuki Kozakai 2005-11-09  157  {
a9e419dc7 Florian Westphal 2017-01-23 @158  	*ctinfo = skb->_nfct & NFCT_INFOMASK;
a9e419dc7 Florian Westphal 2017-01-23  159  
a9e419dc7 Florian Westphal 2017-01-23  160  	return (struct nf_conn *)(skb->_nfct & NFCT_PTRMASK);
9fb9cbb10 Yasuyuki Kozakai 2005-11-09  161  }
9fb9cbb10 Yasuyuki Kozakai 2005-11-09  162  
9fb9cbb10 Yasuyuki Kozakai 2005-11-09  163  /* decrement reference count on a conntrack */
9fb9cbb10 Yasuyuki Kozakai 2005-11-09  164  static inline void nf_ct_put(struct nf_conn *ct)
9fb9cbb10 Yasuyuki Kozakai 2005-11-09  165  {
44d6e2f27 Varsha Rao       2017-08-30  166  	WARN_ON(!ct);
9fb9cbb10 Yasuyuki Kozakai 2005-11-09 @167  	nf_conntrack_put(&ct->ct_general);
9fb9cbb10 Yasuyuki Kozakai 2005-11-09  168  }
9fb9cbb10 Yasuyuki Kozakai 2005-11-09  169  

:::::: The code at line 167 was first introduced by commit
:::::: 9fb9cbb1082d6b31fb45aa1a14432449a0df6cf1 [NETFILTER]: Add nf_conntrack subsystem.

:::::: TO: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
:::::: CC: David S. Miller <davem@davemloft.net>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

Patch

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 95909e2..e61a045 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -37,6 +37,7 @@ 
 #include <net/l3mdev.h>
 #include <net/fib_rules.h>
 #include <net/netns/generic.h>
+#include <net/netfilter/nf_conntrack.h>
 
 #define DRV_NAME	"vrf"
 #define DRV_VERSION	"1.0"
@@ -898,6 +899,12 @@  static struct sk_buff *vrf_rcv_nfhook(u8 pf, unsigned int hook,
 				      struct net_device *dev)
 {
 	struct net *net = dev_net(dev);
+	enum ip_conntrack_info ctinfo;
+	struct nf_conn *ct;
+
+	ct = nf_ct_get(skb, &ctinfo);
+	if (ct && (ct->status & IPS_DST_NAT))
+		return skb;
 
 	if (nf_hook(pf, hook, net, NULL, skb, dev, NULL, vrf_rcv_finish) != 1)
 		skb = NULL;    /* kfree_skb(skb) handled by nf code */