[X25]: Fast select with no restriction on response

This patch is a follow up to patch 1 regarding "Selective Sub Address
matching with call user data". It allows use of the Fast-Select-Acceptance
optional user facility for X.25.

This patch just implements fast select with no restriction on response
(NRR). What this means (according to ITU-T Recomendation 10/96 section
6.16) is that if in an incoming call packet, the relevant facility bits are
set for fast-select-NRR, then the called DTE can issue a direct response to
the incoming packet using a call-accepted packet that contains
call-user-data. This patch allows such a response.

The called DTE can also respond with a clear-request packet that contains
call-user-data. However, this feature is currently not implemented by the
patch.

How is Fast Select Acceptance used?
By default, the system does not allow fast select acceptance (as before).
To enable a response to fast select acceptance,
After a listen socket in created and bound as follows
socket(AF_X25, SOCK_SEQPACKET, 0);
bind(call_soc, (struct sockaddr *)&locl_addr, sizeof(locl_addr));
but before a listen system call is made, the following ioctl should be used.
ioctl(call_soc,SIOCX25CALLACCPTAPPRV);
Now the listen system call can be made
listen(call_soc, 4);
After this, an incoming-call packet will be accepted, but no call-accepted
packet will be sent back until the following system call is made on the socket
that accepts the call
ioctl(vc_soc,SIOCX25SENDCALLACCPT);
The network (or cisco xot router used for testing here) will allow the
application server's call-user-data in the call-accepted packet,
provided the call-request was made with Fast-select NRR.

Signed-off-by: Shaun Pereira <spereira@tusc.com.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Shaun Pereira and committed by David S. Miller ebc3f64b cb65d506

+86 -16
+2
include/linux/x25.h
··· 19 19 #define SIOCX25SCALLUSERDATA (SIOCPROTOPRIVATE + 5) 20 20 #define SIOCX25GCAUSEDIAG (SIOCPROTOPRIVATE + 6) 21 21 #define SIOCX25SCUDMATCHLEN (SIOCPROTOPRIVATE + 7) 22 + #define SIOCX25CALLACCPTAPPRV (SIOCPROTOPRIVATE + 8) 23 + #define SIOCX25SENDCALLACCPT (SIOCPROTOPRIVATE + 9) 22 24 23 25 /* 24 26 * Values for {get,set}sockopt.
+4 -2
include/net/x25.h
··· 79 79 #define X25_DEFAULT_PACKET_SIZE X25_PS128 /* Default Packet Size */ 80 80 #define X25_DEFAULT_THROUGHPUT 0x0A /* Deafult Throughput */ 81 81 #define X25_DEFAULT_REVERSE 0x00 /* Default Reverse Charging */ 82 + #define X25_DENY_ACCPT_APPRV 0x01 /* Default value */ 83 + #define X25_ALLOW_ACCPT_APPRV 0x00 /* Control enabled */ 82 84 83 85 #define X25_SMODULUS 8 84 86 #define X25_EMODULUS 128 ··· 96 94 #define X25_FAC_CLASS_C 0x80 97 95 #define X25_FAC_CLASS_D 0xC0 98 96 99 - #define X25_FAC_REVERSE 0x01 97 + #define X25_FAC_REVERSE 0x01 /* also fast select */ 100 98 #define X25_FAC_THROUGHPUT 0x02 101 99 #define X25_FAC_PACKET_SIZE 0x42 102 100 #define X25_FAC_WINDOW_SIZE 0x43 ··· 137 135 struct x25_address source_addr, dest_addr; 138 136 struct x25_neigh *neighbour; 139 137 unsigned int lci, cudmatchlength; 140 - unsigned char state, condition, qbitincl, intflag; 138 + unsigned char state, condition, qbitincl, intflag, accptapprv; 141 139 unsigned short vs, vr, va, vl; 142 140 unsigned long t2, t21, t22, t23; 143 141 unsigned short fraglen;
+33 -4
net/x25/af_x25.c
··· 31 31 * x25_proc.c, using seq_file 32 32 * 2005-04-02 Shaun Pereira Selective sub address matching 33 33 * with call user data 34 + * 2005-04-15 Shaun Pereira Fast select with no restriction on 35 + * response 34 36 */ 35 37 36 38 #include <linux/config.h> ··· 504 502 x25->t2 = sysctl_x25_ack_holdback_timeout; 505 503 x25->state = X25_STATE_0; 506 504 x25->cudmatchlength = 0; 505 + x25->accptapprv = X25_DENY_ACCPT_APPRV; /* normally no cud */ 506 + /* on call accept */ 507 507 508 508 x25->facilities.winsize_in = X25_DEFAULT_WINDOW_SIZE; 509 509 x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE; ··· 555 551 x25->facilities = ox25->facilities; 556 552 x25->qbitincl = ox25->qbitincl; 557 553 x25->cudmatchlength = ox25->cudmatchlength; 554 + x25->accptapprv = ox25->accptapprv; 558 555 559 556 x25_init_timers(sk); 560 557 out: ··· 905 900 makex25->vc_facil_mask &= ~X25_MASK_REVERSE; 906 901 makex25->cudmatchlength = x25_sk(sk)->cudmatchlength; 907 902 908 - x25_write_internal(make, X25_CALL_ACCEPTED); 909 - 910 - makex25->state = X25_STATE_3; 903 + /* Normally all calls are accepted immediatly */ 904 + if(makex25->accptapprv & X25_DENY_ACCPT_APPRV) { 905 + x25_write_internal(make, X25_CALL_ACCEPTED); 906 + makex25->state = X25_STATE_3; 907 + } 911 908 912 909 /* 913 910 * Incoming Call User Data. ··· 1301 1294 if (facilities.throughput < 0x03 || 1302 1295 facilities.throughput > 0xDD) 1303 1296 break; 1304 - if (facilities.reverse && facilities.reverse != 1) 1297 + if (facilities.reverse && 1298 + (facilities.reverse | 0x81)!= 0x81) 1305 1299 break; 1306 1300 x25->facilities = facilities; 1307 1301 rc = 0; ··· 1352 1344 if(sub_addr.cudmatchlength > X25_MAX_CUD_LEN) 1353 1345 break; 1354 1346 x25->cudmatchlength = sub_addr.cudmatchlength; 1347 + rc = 0; 1348 + break; 1349 + } 1350 + 1351 + case SIOCX25CALLACCPTAPPRV: { 1352 + rc = -EINVAL; 1353 + if (sk->sk_state != TCP_CLOSE) 1354 + break; 1355 + x25->accptapprv = X25_ALLOW_ACCPT_APPRV; 1356 + rc = 0; 1357 + break; 1358 + } 1359 + 1360 + case SIOCX25SENDCALLACCPT: { 1361 + rc = -EINVAL; 1362 + if (sk->sk_state != TCP_ESTABLISHED) 1363 + break; 1364 + if (x25->accptapprv) /* must call accptapprv above */ 1365 + break; 1366 + x25_write_internal(sk, X25_CALL_ACCEPTED); 1367 + x25->state = X25_STATE_3; 1355 1368 rc = 0; 1356 1369 break; 1357 1370 }
+29 -5
net/x25/x25_facilities.c
··· 17 17 * X.25 001 Split from x25_subr.c 18 18 * mar/20/00 Daniela Squassoni Disabling/enabling of facilities 19 19 * negotiation. 20 + * apr/14/05 Shaun Pereira - Allow fast select with no restriction 21 + * on response. 20 22 */ 21 23 22 24 #include <linux/kernel.h> ··· 45 43 case X25_FAC_CLASS_A: 46 44 switch (*p) { 47 45 case X25_FAC_REVERSE: 48 - facilities->reverse = p[1] & 0x01; 49 - *vc_fac_mask |= X25_MASK_REVERSE; 50 - break; 46 + if((p[1] & 0x81) == 0x81) { 47 + facilities->reverse = p[1] & 0x81; 48 + *vc_fac_mask |= X25_MASK_REVERSE; 49 + break; 50 + } 51 + 52 + if((p[1] & 0x01) == 0x01) { 53 + facilities->reverse = p[1] & 0x01; 54 + *vc_fac_mask |= X25_MASK_REVERSE; 55 + break; 56 + } 57 + 58 + if((p[1] & 0x80) == 0x80) { 59 + facilities->reverse = p[1] & 0x80; 60 + *vc_fac_mask |= X25_MASK_REVERSE; 61 + break; 62 + } 63 + 64 + if(p[1] == 0x00) { 65 + facilities->reverse 66 + = X25_DEFAULT_REVERSE; 67 + *vc_fac_mask |= X25_MASK_REVERSE; 68 + break; 69 + } 70 + 51 71 case X25_FAC_THROUGHPUT: 52 72 facilities->throughput = p[1]; 53 73 *vc_fac_mask |= X25_MASK_THROUGHPUT; ··· 146 122 147 123 if (facilities->reverse && (facil_mask & X25_MASK_REVERSE)) { 148 124 *p++ = X25_FAC_REVERSE; 149 - *p++ = !!facilities->reverse; 125 + *p++ = facilities->reverse; 150 126 } 151 127 152 128 if (facilities->throughput && (facil_mask & X25_MASK_THROUGHPUT)) { ··· 195 171 /* 196 172 * They want reverse charging, we won't accept it. 197 173 */ 198 - if (theirs.reverse && ours->reverse) { 174 + if ((theirs.reverse & 0x01 ) && (ours->reverse & 0x01)) { 199 175 SOCK_DEBUG(sk, "X.25: rejecting reverse charging request"); 200 176 return -1; 201 177 }
+18 -5
net/x25/x25_subr.c
··· 19 19 * mar/20/00 Daniela Squassoni Disabling/enabling of facilities 20 20 * negotiation. 21 21 * jun/24/01 Arnaldo C. Melo use skb_queue_purge, cleanups 22 + * apr/04/15 Shaun Pereira Fast select with no 23 + * restriction on response. 22 24 */ 23 25 24 26 #include <linux/kernel.h> ··· 129 127 len += 1 + X25_ADDR_LEN + X25_MAX_FAC_LEN + 130 128 X25_MAX_CUD_LEN; 131 129 break; 132 - case X25_CALL_ACCEPTED: 133 - len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN; 130 + case X25_CALL_ACCEPTED: /* fast sel with no restr on resp */ 131 + if(x25->facilities.reverse & 0x80) { 132 + len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN; 133 + } else { 134 + len += 1 + X25_MAX_FAC_LEN; 135 + } 134 136 break; 135 137 case X25_CLEAR_REQUEST: 136 138 case X25_RESET_REQUEST: ··· 209 203 x25->vc_facil_mask); 210 204 dptr = skb_put(skb, len); 211 205 memcpy(dptr, facilities, len); 212 - dptr = skb_put(skb, x25->calluserdata.cudlength); 213 - memcpy(dptr, x25->calluserdata.cuddata, 214 - x25->calluserdata.cudlength); 206 + 207 + /* fast select with no restriction on response 208 + allows call user data. Userland must 209 + ensure it is ours and not theirs */ 210 + if(x25->facilities.reverse & 0x80) { 211 + dptr = skb_put(skb, 212 + x25->calluserdata.cudlength); 213 + memcpy(dptr, x25->calluserdata.cuddata, 214 + x25->calluserdata.cudlength); 215 + } 215 216 x25->calluserdata.cudlength = 0; 216 217 break; 217 218