Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / net / x25 / x25_subr.c
index 183fea3..8d6220a 100644 (file)
  *     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.
  */
 
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
-#include <net/tcp.h>
+#include <net/tcp_states.h>
 #include <net/x25.h>
 
 /*
@@ -78,7 +80,7 @@ void x25_requeue_frames(struct sock *sk)
                if (!skb_prev)
                        skb_queue_head(&sk->sk_write_queue, skb);
                else
-                       skb_append(skb_prev, skb);
+                       skb_append(skb_prev, skb, &sk->sk_write_queue);
                skb_prev = skb;
        }
 }
@@ -127,8 +129,12 @@ void x25_write_internal(struct sock *sk, int frametype)
                        len += 1 + X25_ADDR_LEN + X25_MAX_FAC_LEN +
                               X25_MAX_CUD_LEN;
                        break;
-               case X25_CALL_ACCEPTED:
-                       len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
+               case X25_CALL_ACCEPTED: /* fast sel with no restr on resp */
+                       if(x25->facilities.reverse & 0x80) {
+                               len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
+                       } else {
+                               len += 1 + X25_MAX_FAC_LEN;
+                       }
                        break;
                case X25_CLEAR_REQUEST:
                case X25_RESET_REQUEST:
@@ -184,8 +190,9 @@ void x25_write_internal(struct sock *sk, int frametype)
                        dptr    = skb_put(skb, len);
                        memcpy(dptr, addresses, len);
                        len     = x25_create_facilities(facilities,
-                                                       &x25->facilities,
-                                            x25->neighbour->global_facil_mask);
+                                       &x25->facilities,
+                                       &x25->dte_facilities,
+                                       x25->neighbour->global_facil_mask);
                        dptr    = skb_put(skb, len);
                        memcpy(dptr, facilities, len);
                        dptr = skb_put(skb, x25->calluserdata.cudlength);
@@ -200,12 +207,20 @@ void x25_write_internal(struct sock *sk, int frametype)
                        *dptr++ = 0x00;         /* Address lengths */
                        len     = x25_create_facilities(facilities,
                                                        &x25->facilities,
+                                                       &x25->dte_facilities,
                                                        x25->vc_facil_mask);
                        dptr    = skb_put(skb, len);
                        memcpy(dptr, facilities, len);
-                       dptr = skb_put(skb, x25->calluserdata.cudlength);
-                       memcpy(dptr, x25->calluserdata.cuddata,
-                              x25->calluserdata.cudlength);
+
+                       /* fast select with no restriction on response
+                               allows call user data. Userland must
+                               ensure it is ours and not theirs */
+                       if(x25->facilities.reverse & 0x80) {
+                               dptr = skb_put(skb,
+                                       x25->calluserdata.cudlength);
+                               memcpy(dptr, x25->calluserdata.cuddata,
+                                      x25->calluserdata.cudlength);
+                       }
                        x25->calluserdata.cudlength = 0;
                        break;
 
@@ -354,21 +369,3 @@ void x25_check_rbuf(struct sock *sk)
        }
 }
 
-/*
- * Compare 2 calluserdata structures, used to find correct listening sockets
- * when call user data is used.
- */
-int x25_check_calluserdata(struct x25_calluserdata *ours, struct x25_calluserdata *theirs)
-{
-       int i;
-       if (ours->cudlength != theirs->cudlength)
-               return 0;
-
-       for (i=0;i<ours->cudlength;i++) {
-               if (ours->cuddata[i] != theirs->cuddata[i]) {
-                       return 0;
-               }
-       }
-       return 1;
-}
-