62
63static struct hlist_node *ct_get_next(struct seq_file *seq,
64 struct hlist_node *head)
65{
66 struct net *net = seq_file_net(seq);
67 struct ct_iter_state *st = seq->private;
68
69 head = rcu_dereference(head->next);
70 while (head == NULL) {
71 if (++st->bucket >= nf_conntrack_htable_size)
72 return NULL;
73 head = rcu_dereference(net->ct.hash[st->bucket].first);
74 }
75 return head;
76}
77
78static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
79{
80 struct hlist_node *head = ct_get_first(seq);
81
82 if (head)
83 while (pos && (head = ct_get_next(seq, head)))
84 pos--;
85 return pos ? NULL : head;
86}
87
88static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
89 __acquires(RCU)
90{
91 rcu_read_lock();
92 return ct_get_idx(seq, *pos);
93}
94
95static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
96{
97 (*pos)++;
98 return ct_get_next(s, v);
99}
100
101static void ct_seq_stop(struct seq_file *s, void *v)
102 __releases(RCU)