Source
x
int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
/*
* X.25 Packet Layer release 002
*
* This is ALPHA test software. This code may break your machine,
* randomly fail to work with new releases, misbehave and/or generally
* screw up. It might even work.
*
* This code REQUIRES 2.1.15 or higher
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* X.25 001 Jonathan Naylor Started coding.
* X.25 002 Jonathan Naylor Centralised disconnection processing.
* mar/20/00 Daniela Squassoni Disabling/enabling of facilities
* negotiation.
* jun/24/01 Arnaldo C. Melo use skb_queue_purge, cleanups
* apr/04/15 Shaun Pereira Fast select with no
* restriction on response.
*/
/*
* This routine purges all of the queues of frames.
*/
void x25_clear_queues(struct sock *sk)
{
struct x25_sock *x25 = x25_sk(sk);
skb_queue_purge(&sk->sk_write_queue);
skb_queue_purge(&x25->ack_queue);
skb_queue_purge(&x25->interrupt_in_queue);
skb_queue_purge(&x25->interrupt_out_queue);
skb_queue_purge(&x25->fragment_queue);
}
/*
* This routine purges the input queue of those frames that have been
* acknowledged. This replaces the boxes labelled "V(a) <- N(r)" on the
* SDL diagram.
*/
void x25_frames_acked(struct sock *sk, unsigned short nr)
{
struct sk_buff *skb;
struct x25_sock *x25 = x25_sk(sk);
int modulus = x25->neighbour->extended ? X25_EMODULUS : X25_SMODULUS;
/*
* Remove all the ack-ed frames from the ack queue.
*/
if (x25->va != nr)
while (skb_peek(&x25->ack_queue) && x25->va != nr) {
skb = skb_dequeue(&x25->ack_queue);
kfree_skb(skb);
x25->va = (x25->va + 1) % modulus;
}
}
void x25_requeue_frames(struct sock *sk)
{
struct sk_buff *skb, *skb_prev = NULL;
/*
* Requeue all the un-ack-ed frames on the output queue to be picked
* up by x25_kick. This arrangement handles the possibility of an empty
* output queue.
*/
while ((skb = skb_dequeue(&x25_sk(sk)->ack_queue)) != NULL) {
if (!skb_prev)
skb_queue_head(&sk->sk_write_queue, skb);
else
skb_append(skb_prev, skb, &sk->sk_write_queue);
skb_prev = skb;
}
}
/*
* Validate that the value of nr is between va and vs. Return true or