patch-2.0.35 linux/net/netrom/nr_in.c

Next file: linux/net/netrom/nr_loopback.c
Previous file: linux/net/netrom/nr_dev.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.34/linux/net/netrom/nr_in.c linux/net/netrom/nr_in.c
@@ -1,8 +1,5 @@
 /*
- *	NET/ROM release 003
- *
- *	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. 
+ *	NET/ROM release 006
  *
  *	This code REQUIRES 1.2.1 or higher/ NET3.029
  *
@@ -26,7 +23,7 @@
  */
 
 #include <linux/config.h>
-#ifdef CONFIG_NETROM
+#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/socket.h>
@@ -54,36 +51,30 @@
 {
 	struct sk_buff *skbo, *skbn = skb;
 
+	skb_pull(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
+
 	if (more) {
-		sk->nr->fraglen += skb->len;
-		skb_queue_tail(&sk->nr->frag_queue, skb);
+		sk->protinfo.nr->fraglen += skb->len;
+		skb_queue_tail(&sk->protinfo.nr->frag_queue, skb);
 		return 0;
 	}
-	
-	if (!more && sk->nr->fraglen > 0) {	/* End of fragment */
-		sk->nr->fraglen += skb->len;
-		skb_queue_tail(&sk->nr->frag_queue, skb);
 
-		if ((skbn = alloc_skb(sk->nr->fraglen, GFP_ATOMIC)) == NULL)
+	if (!more && sk->protinfo.nr->fraglen > 0) {	/* End of fragment */
+		sk->protinfo.nr->fraglen += skb->len;
+		skb_queue_tail(&sk->protinfo.nr->frag_queue, skb);
+
+		if ((skbn = alloc_skb(sk->protinfo.nr->fraglen, GFP_ATOMIC)) == NULL)
 			return 1;
 
-		skbn->free = 1;
-		skbn->arp  = 1;
-		skbn->sk   = sk;
-		sk->rmem_alloc += skbn->truesize;
+		skbn->free  = 1;
 		skbn->h.raw = skbn->data;
 
-		skbo = skb_dequeue(&sk->nr->frag_queue);
-		memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
-		kfree_skb(skbo, FREE_READ);
-
-		while ((skbo = skb_dequeue(&sk->nr->frag_queue)) != NULL) {
-			skb_pull(skbo, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
+		while ((skbo = skb_dequeue(&sk->protinfo.nr->frag_queue)) != NULL) {
 			memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
 			kfree_skb(skbo, FREE_READ);
 		}
 
-		sk->nr->fraglen = 0;		
+		sk->protinfo.nr->fraglen = 0;		
 	}
 
 	return sock_queue_rcv_skb(sk, skbn);
@@ -99,20 +90,19 @@
 	switch (frametype) {
 
 		case NR_CONNACK:
-			nr_calculate_rtt(sk);
-			sk->window         = skb->data[20];
-			sk->nr->your_index = skb->data[17];
-			sk->nr->your_id    = skb->data[18];
-			sk->nr->t1timer    = 0;
-			sk->nr->t2timer    = 0;
-			sk->nr->t4timer    = 0;
-			sk->nr->vs         = 0;
-			sk->nr->va         = 0;
-			sk->nr->vr         = 0;
-			sk->nr->vl	   = 0;
-			sk->nr->state      = NR_STATE_3;
-			sk->state          = TCP_ESTABLISHED;
-			sk->nr->n2count    = 0;
+			sk->protinfo.nr->your_index = skb->data[17];
+			sk->protinfo.nr->your_id    = skb->data[18];
+			sk->protinfo.nr->t1timer    = 0;
+			sk->protinfo.nr->t2timer    = 0;
+			sk->protinfo.nr->t4timer    = 0;
+			sk->protinfo.nr->vs         = 0;
+			sk->protinfo.nr->va         = 0;
+			sk->protinfo.nr->vr         = 0;
+			sk->protinfo.nr->vl	    = 0;
+			sk->protinfo.nr->state      = NR_STATE_3;
+			sk->protinfo.nr->n2count    = 0;
+			sk->protinfo.nr->window     = skb->data[20];
+			sk->state                   = TCP_ESTABLISHED;
 			/* For WAIT_SABM connections we will produce an accept ready socket here */
 			if (!sk->dead)
 				sk->state_change(sk);
@@ -120,12 +110,13 @@
 
 		case NR_CONNACK | NR_CHOKE_FLAG:
 			nr_clear_queues(sk);
-			sk->nr->state = NR_STATE_0;
-			sk->state     = TCP_CLOSE;
-			sk->err       = ECONNREFUSED;
+			sk->protinfo.nr->state = NR_STATE_0;
+			sk->state              = TCP_CLOSE;
+			sk->err                = ECONNREFUSED;
+			sk->shutdown          |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
-			sk->dead      = 1;
+			sk->dead               = 1;
 			break;
 
 		default:
@@ -144,16 +135,27 @@
 {
 	switch (frametype) {
 
+		case NR_CONNACK | NR_CHOKE_FLAG:
+			sk->protinfo.nr->state = NR_STATE_0;
+			sk->state              = TCP_CLOSE;
+			sk->err                = ECONNRESET;
+			sk->shutdown          |= SEND_SHUTDOWN;
+			if (!sk->dead)
+				sk->state_change(sk);
+			sk->dead               = 1;
+			break;
+
 		case NR_DISCREQ:
 			nr_write_internal(sk, NR_DISCACK);
 
 		case NR_DISCACK:
-			sk->nr->state = NR_STATE_0;
-			sk->state     = TCP_CLOSE;
-			sk->err       = 0;
+			sk->protinfo.nr->state = NR_STATE_0;
+			sk->state              = TCP_CLOSE;
+			sk->err                = 0;
+			sk->shutdown          |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
-			sk->dead      = 1;
+			sk->dead               = 1;
 			break;
 
 		default:
@@ -188,22 +190,25 @@
 		case NR_DISCREQ:
 			nr_clear_queues(sk);
 			nr_write_internal(sk, NR_DISCACK);
-			sk->nr->state = NR_STATE_0;
-			sk->state     = TCP_CLOSE;
-			sk->err       = 0;
+			sk->protinfo.nr->state = NR_STATE_0;
+			sk->state              = TCP_CLOSE;
+			sk->err                = 0;
+			sk->shutdown          |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
-			sk->dead      = 1;
+			sk->dead               = 1;
 			break;
 
+		case NR_CONNACK | NR_CHOKE_FLAG:
 		case NR_DISCACK:
 			nr_clear_queues(sk);
-			sk->nr->state = NR_STATE_0;
-			sk->state     = TCP_CLOSE;
-			sk->err       = ECONNRESET;
+			sk->protinfo.nr->state = NR_STATE_0;
+			sk->state              = TCP_CLOSE;
+			sk->err                = ECONNRESET;
+			sk->shutdown          |= SEND_SHUTDOWN;
 			if (!sk->dead)
 				sk->state_change(sk);
-			sk->dead      = 1;
+			sk->dead               = 1;
 			break;
 
 		case NR_INFOACK:
@@ -211,11 +216,11 @@
 		case NR_INFOACK | NR_NAK_FLAG:
 		case NR_INFOACK | NR_NAK_FLAG | NR_CHOKE_FLAG:
 			if (frametype & NR_CHOKE_FLAG) {
-				sk->nr->condition |= PEER_RX_BUSY_CONDITION;
-				sk->nr->t4timer = nr_default.busy_delay;
+				sk->protinfo.nr->condition |= NR_COND_PEER_RX_BUSY;
+				sk->protinfo.nr->t4timer = sk->protinfo.nr->t4;
 			} else {
-				sk->nr->condition &= ~PEER_RX_BUSY_CONDITION;
-				sk->nr->t4timer = 0;
+				sk->protinfo.nr->condition &= ~NR_COND_PEER_RX_BUSY;
+				sk->protinfo.nr->t4timer = 0;
 			}
 			if (!nr_validate_nr(sk, nr)) {
 				break;
@@ -224,14 +229,14 @@
 				nr_frames_acked(sk, nr);
 				nr_send_nak_frame(sk);
 			} else {
-				if (sk->nr->condition & PEER_RX_BUSY_CONDITION) {
+				if (sk->protinfo.nr->condition & NR_COND_PEER_RX_BUSY) {
 					nr_frames_acked(sk, nr);
 				} else {
 					nr_check_iframes_acked(sk, nr);
 				}
 			}
 			break;
-			
+
 		case NR_INFO:
 		case NR_INFO | NR_NAK_FLAG:
 		case NR_INFO | NR_CHOKE_FLAG:
@@ -241,18 +246,18 @@
 		case NR_INFO | NR_NAK_FLAG | NR_MORE_FLAG:
 		case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG | NR_MORE_FLAG:
 			if (frametype & NR_CHOKE_FLAG) {
-				sk->nr->condition |= PEER_RX_BUSY_CONDITION;
-				sk->nr->t4timer = nr_default.busy_delay;
+				sk->protinfo.nr->condition |= NR_COND_PEER_RX_BUSY;
+				sk->protinfo.nr->t4timer = sk->protinfo.nr->t4;
 			} else {
-				sk->nr->condition &= ~PEER_RX_BUSY_CONDITION;
-				sk->nr->t4timer = 0;
+				sk->protinfo.nr->condition &= ~NR_COND_PEER_RX_BUSY;
+				sk->protinfo.nr->t4timer = 0;
 			}
 			if (nr_validate_nr(sk, nr)) {
 				if (frametype & NR_NAK_FLAG) {
 					nr_frames_acked(sk, nr);
 					nr_send_nak_frame(sk);
 				} else {
-					if (sk->nr->condition & PEER_RX_BUSY_CONDITION) {
+					if (sk->protinfo.nr->condition & NR_COND_PEER_RX_BUSY) {
 						nr_frames_acked(sk, nr);
 					} else {
 						nr_check_iframes_acked(sk, nr);
@@ -260,19 +265,19 @@
 				}
 			}
 			queued = 1;
-			skb_queue_head(&sk->nr->reseq_queue, skb);
-			if (sk->nr->condition & OWN_RX_BUSY_CONDITION)
+			skb_queue_head(&sk->protinfo.nr->reseq_queue, skb);
+			if (sk->protinfo.nr->condition & NR_COND_OWN_RX_BUSY)
 				break;
 			skb_queue_head_init(&temp_queue);
 			do {
-				save_vr = sk->nr->vr;
-				while ((skbn = skb_dequeue(&sk->nr->reseq_queue)) != NULL) {
+				save_vr = sk->protinfo.nr->vr;
+				while ((skbn = skb_dequeue(&sk->protinfo.nr->reseq_queue)) != NULL) {
 					ns = skbn->data[17];
-					if (ns == sk->nr->vr) {
+					if (ns == sk->protinfo.nr->vr) {
 						if (nr_queue_rx_frame(sk, skbn, frametype & NR_MORE_FLAG) == 0) {
-							sk->nr->vr = (sk->nr->vr + 1) % NR_MODULUS;
+							sk->protinfo.nr->vr = (sk->protinfo.nr->vr + 1) % NR_MODULUS;
 						} else {
-							sk->nr->condition |= OWN_RX_BUSY_CONDITION;
+							sk->protinfo.nr->condition |= NR_COND_OWN_RX_BUSY;
 							skb_queue_tail(&temp_queue, skbn);
 						}
 					} else if (nr_in_rx_window(sk, ns)) {
@@ -283,18 +288,18 @@
 					}
 				}
 				while ((skbn = skb_dequeue(&temp_queue)) != NULL) {
-					skb_queue_tail(&sk->nr->reseq_queue, skbn);
+					skb_queue_tail(&sk->protinfo.nr->reseq_queue, skbn);
 				}
-			} while (save_vr != sk->nr->vr);
+			} while (save_vr != sk->protinfo.nr->vr);
 			/*
 			 * Window is full, ack it immediately.
 			 */
-			if (((sk->nr->vl + sk->window) % NR_MODULUS) == sk->nr->vr) {
+			if (((sk->protinfo.nr->vl + sk->protinfo.nr->window) % NR_MODULUS) == sk->protinfo.nr->vr) {
 				nr_enquiry_response(sk);
 			} else {
-				if (!(sk->nr->condition & ACK_PENDING_CONDITION)) {
-					sk->nr->t2timer = sk->nr->t2;
-					sk->nr->condition |= ACK_PENDING_CONDITION;
+				if (!(sk->protinfo.nr->condition & NR_COND_ACK_PENDING)) {
+					sk->protinfo.nr->t2timer = sk->protinfo.nr->t2;
+					sk->protinfo.nr->condition |= NR_COND_ACK_PENDING;
 				}
 			}
 			break;
@@ -310,22 +315,15 @@
 int nr_process_rx_frame(struct sock *sk, struct sk_buff *skb)
 {
 	int queued = 0, frametype;
-	
-	if (sk->nr->state == NR_STATE_0 && sk->dead)
-		return queued;
-
-	if (sk->nr->state != NR_STATE_1 && sk->nr->state != NR_STATE_2 &&
-	    sk->nr->state != NR_STATE_3) {
-		printk(KERN_ERR "nr_process_rx_frame: frame received - state: %d\n", sk->nr->state);
-		return queued;
-	}
+
+	if (sk->protinfo.nr->state == NR_STATE_0)
+		return 0;
 
 	del_timer(&sk->timer);
 
 	frametype = skb->data[19];
 
-	switch (sk->nr->state)
-	{
+	switch (sk->protinfo.nr->state) {
 		case NR_STATE_1:
 			queued = nr_state1_machine(sk, skb, frametype);
 			break;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov