@@ -60,7 +60,7 @@ MODULE_LICENSE("GPL");
6060MODULE_DESCRIPTION ("List and change connection tracking table" );
6161
6262struct ctnetlink_list_dump_ctx {
63- struct nf_conn * last ;
63+ unsigned long last_id ;
6464 unsigned int cpu ;
6565 bool done ;
6666};
@@ -1733,16 +1733,6 @@ static int ctnetlink_get_conntrack(struct sk_buff *skb,
17331733 return nfnetlink_unicast (skb2 , info -> net , NETLINK_CB (skb ).portid );
17341734}
17351735
1736- static int ctnetlink_done_list (struct netlink_callback * cb )
1737- {
1738- struct ctnetlink_list_dump_ctx * ctx = (void * )cb -> ctx ;
1739-
1740- if (ctx -> last )
1741- nf_ct_put (ctx -> last );
1742-
1743- return 0 ;
1744- }
1745-
17461736#ifdef CONFIG_NF_CONNTRACK_EVENTS
17471737static int ctnetlink_dump_one_entry (struct sk_buff * skb ,
17481738 struct netlink_callback * cb ,
@@ -1757,11 +1747,11 @@ static int ctnetlink_dump_one_entry(struct sk_buff *skb,
17571747 if (l3proto && nf_ct_l3num (ct ) != l3proto )
17581748 return 0 ;
17591749
1760- if (ctx -> last ) {
1761- if (ct != ctx -> last )
1750+ if (ctx -> last_id ) {
1751+ if (ctnetlink_get_id ( ct ) != ctx -> last_id )
17621752 return 0 ;
17631753
1764- ctx -> last = NULL ;
1754+ ctx -> last_id = 0 ;
17651755 }
17661756
17671757 /* We can't dump extension info for the unconfirmed
@@ -1775,12 +1765,8 @@ static int ctnetlink_dump_one_entry(struct sk_buff *skb,
17751765 cb -> nlh -> nlmsg_seq ,
17761766 NFNL_MSG_TYPE (cb -> nlh -> nlmsg_type ),
17771767 ct , dying , 0 );
1778- if (res < 0 ) {
1779- if (!refcount_inc_not_zero (& ct -> ct_general .use ))
1780- return 0 ;
1781-
1782- ctx -> last = ct ;
1783- }
1768+ if (res < 0 )
1769+ ctx -> last_id = ctnetlink_get_id (ct );
17841770
17851771 return res ;
17861772}
@@ -1796,18 +1782,18 @@ static int
17961782ctnetlink_dump_dying (struct sk_buff * skb , struct netlink_callback * cb )
17971783{
17981784 struct ctnetlink_list_dump_ctx * ctx = (void * )cb -> ctx ;
1799- struct nf_conn * last = ctx -> last ;
18001785#ifdef CONFIG_NF_CONNTRACK_EVENTS
18011786 const struct net * net = sock_net (skb -> sk );
18021787 struct nf_conntrack_net_ecache * ecache_net ;
1788+ unsigned long last_id = ctx -> last_id ;
18031789 struct nf_conntrack_tuple_hash * h ;
18041790 struct hlist_nulls_node * n ;
18051791#endif
18061792
18071793 if (ctx -> done )
18081794 return 0 ;
18091795
1810- ctx -> last = NULL ;
1796+ ctx -> last_id = 0 ;
18111797
18121798#ifdef CONFIG_NF_CONNTRACK_EVENTS
18131799 ecache_net = nf_conn_pernet_ecache (net );
@@ -1818,24 +1804,21 @@ ctnetlink_dump_dying(struct sk_buff *skb, struct netlink_callback *cb)
18181804 int res ;
18191805
18201806 ct = nf_ct_tuplehash_to_ctrack (h );
1821- if (last && last != ct )
1807+ if (last_id && last_id != ctnetlink_get_id ( ct ) )
18221808 continue ;
18231809
18241810 res = ctnetlink_dump_one_entry (skb , cb , ct , true);
18251811 if (res < 0 ) {
18261812 spin_unlock_bh (& ecache_net -> dying_lock );
1827- nf_ct_put (last );
18281813 return skb -> len ;
18291814 }
18301815
1831- nf_ct_put (last );
1832- last = NULL ;
1816+ last_id = 0 ;
18331817 }
18341818
18351819 spin_unlock_bh (& ecache_net -> dying_lock );
18361820#endif
18371821 ctx -> done = true;
1838- nf_ct_put (last );
18391822
18401823 return skb -> len ;
18411824}
@@ -1847,7 +1830,6 @@ static int ctnetlink_get_ct_dying(struct sk_buff *skb,
18471830 if (info -> nlh -> nlmsg_flags & NLM_F_DUMP ) {
18481831 struct netlink_dump_control c = {
18491832 .dump = ctnetlink_dump_dying ,
1850- .done = ctnetlink_done_list ,
18511833 };
18521834 return netlink_dump_start (info -> sk , skb , info -> nlh , & c );
18531835 }
@@ -1862,7 +1844,6 @@ static int ctnetlink_get_ct_unconfirmed(struct sk_buff *skb,
18621844 if (info -> nlh -> nlmsg_flags & NLM_F_DUMP ) {
18631845 struct netlink_dump_control c = {
18641846 .dump = ctnetlink_dump_unconfirmed ,
1865- .done = ctnetlink_done_list ,
18661847 };
18671848 return netlink_dump_start (info -> sk , skb , info -> nlh , & c );
18681849 }
0 commit comments