Lines Matching refs:chain

32  * batadv_frag_clear_chain() - delete entries in the fragment buffer chain
33 * @head: head of chain with entries.
34 * @dropped: whether the chain is cleared because all fragments are dropped
63 struct batadv_frag_table_entry *chain;
67 chain = &orig_node->fragments[i];
68 spin_lock_bh(&chain->lock);
70 if (!check_cb || check_cb(chain)) {
71 batadv_frag_clear_chain(&chain->fragment_list, true);
72 chain->size = 0;
75 spin_unlock_bh(&chain->lock);
95 * batadv_frag_init_chain() - check and prepare fragment chain for new fragment
96 * @chain: chain in fragments table to init
99 * Make chain ready for a fragment with sequence number "seqno". Delete existing
102 * Caller must hold chain->lock.
104 * Return: true if chain is empty and the caller can just insert the new
107 static bool batadv_frag_init_chain(struct batadv_frag_table_entry *chain,
110 lockdep_assert_held(&chain->lock);
112 if (chain->seqno == seqno)
115 if (!hlist_empty(&chain->fragment_list))
116 batadv_frag_clear_chain(&chain->fragment_list, true);
118 chain->size = 0;
119 chain->seqno = seqno;
125 * batadv_frag_insert_packet() - insert a fragment into a fragment chain
130 * Insert a new fragment into the reverse ordered chain in the right table
133 * Return: true if skb is buffered, false on error. If the chain has all the
134 * fragments needed to merge the packet, the chain is moved to the passed head
135 * to avoid locking the chain in the table.
141 struct batadv_frag_table_entry *chain;
167 /* Select entry in the "chain table" and delete any prior fragments
171 chain = &orig_node->fragments[bucket];
172 spin_lock_bh(&chain->lock);
173 if (batadv_frag_init_chain(chain, seqno)) {
174 hlist_add_head(&frag_entry_new->list, &chain->fragment_list);
175 chain->size = skb->len - hdr_size;
176 chain->timestamp = jiffies;
177 chain->total_size = ntohs(frag_packet->total_size);
183 hlist_for_each_entry(frag_entry_curr, &chain->fragment_list, list) {
192 chain->size += skb->len - hdr_size;
193 chain->timestamp = jiffies;
205 chain->size += skb->len - hdr_size;
206 chain->timestamp = jiffies;
211 if (chain->size > batadv_frag_size_limit() ||
212 chain->total_size != ntohs(frag_packet->total_size) ||
213 chain->total_size > batadv_frag_size_limit()) {
214 /* Clear chain if total size of either the list or the packet
218 batadv_frag_clear_chain(&chain->fragment_list, true);
219 chain->size = 0;
220 } else if (ntohs(frag_packet->total_size) == chain->size) {
221 /* All fragments received. Hand over chain to caller. */
222 hlist_move_list(&chain->fragment_list, chain_out);
223 chain->size = 0;
227 spin_unlock_bh(&chain->lock);
239 * batadv_frag_merge_packets() - merge a chain of fragments
240 * @chain: head of chain with fragments
242 * Expand the first skb in the chain and copy the content of the remaining
243 * skb's into the expanded one. After doing so, clear the chain.
248 batadv_frag_merge_packets(struct hlist_head *chain)
259 entry = hlist_entry(chain->first, struct batadv_frag_list_entry, list);
286 hlist_for_each_entry(entry, chain, list) {
292 /* Locking is not needed, because 'chain' is not part of any orig. */
293 batadv_frag_clear_chain(chain, dropped);