Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ebc3f64b authored by Shaun Pereira's avatar Shaun Pereira Committed by David S. Miller
Browse files

[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: default avatarShaun Pereira <spereira@tusc.com.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cb65d506
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#define	SIOCX25SCALLUSERDATA	(SIOCPROTOPRIVATE + 5)
#define	SIOCX25GCAUSEDIAG	(SIOCPROTOPRIVATE + 6)
#define SIOCX25SCUDMATCHLEN	(SIOCPROTOPRIVATE + 7)
#define SIOCX25CALLACCPTAPPRV   (SIOCPROTOPRIVATE + 8)
#define SIOCX25SENDCALLACCPT    (SIOCPROTOPRIVATE + 9)

/*
 *	Values for {get,set}sockopt.
+4 −2
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@ enum {
#define	X25_DEFAULT_PACKET_SIZE	X25_PS128		/* Default Packet Size */
#define	X25_DEFAULT_THROUGHPUT	0x0A			/* Deafult Throughput */
#define	X25_DEFAULT_REVERSE	0x00			/* Default Reverse Charging */
#define X25_DENY_ACCPT_APPRV   0x01			/* Default value */
#define X25_ALLOW_ACCPT_APPRV  0x00			/* Control enabled */

#define X25_SMODULUS 		8
#define	X25_EMODULUS		128
@@ -94,7 +96,7 @@ enum {
#define	X25_FAC_CLASS_C		0x80
#define	X25_FAC_CLASS_D		0xC0

#define	X25_FAC_REVERSE		0x01
#define	X25_FAC_REVERSE		0x01			/* also fast select */
#define	X25_FAC_THROUGHPUT	0x02
#define	X25_FAC_PACKET_SIZE	0x42
#define	X25_FAC_WINDOW_SIZE	0x43
@@ -135,7 +137,7 @@ struct x25_sock {
	struct x25_address	source_addr, dest_addr;
	struct x25_neigh	*neighbour;
	unsigned int		lci, cudmatchlength;
	unsigned char		state, condition, qbitincl, intflag;
	unsigned char		state, condition, qbitincl, intflag, accptapprv;
	unsigned short		vs, vr, va, vl;
	unsigned long		t2, t21, t22, t23;
	unsigned short		fraglen;
+33 −4
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@
 *					x25_proc.c, using seq_file
 *	2005-04-02	Shaun Pereira	Selective sub address matching
 *					with call user data
 *	2005-04-15	Shaun Pereira	Fast select with no restriction on
 *					response
 */

#include <linux/config.h>
@@ -502,6 +504,8 @@ static int x25_create(struct socket *sock, int protocol)
	x25->t2    = sysctl_x25_ack_holdback_timeout;
	x25->state = X25_STATE_0;
	x25->cudmatchlength = 0;
	x25->accptapprv = X25_DENY_ACCPT_APPRV;		/* normally no cud  */
							/* on call accept   */

	x25->facilities.winsize_in  = X25_DEFAULT_WINDOW_SIZE;
	x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
@@ -551,6 +555,7 @@ static struct sock *x25_make_new(struct sock *osk)
	x25->facilities = ox25->facilities;
	x25->qbitincl   = ox25->qbitincl;
	x25->cudmatchlength = ox25->cudmatchlength;
	x25->accptapprv = ox25->accptapprv;

	x25_init_timers(sk);
out:
@@ -900,9 +905,11 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
	makex25->vc_facil_mask &= ~X25_MASK_REVERSE;
	makex25->cudmatchlength = x25_sk(sk)->cudmatchlength;

	/* Normally all calls are accepted immediatly */
	if(makex25->accptapprv & X25_DENY_ACCPT_APPRV) {
		x25_write_internal(make, X25_CALL_ACCEPTED);

		makex25->state = X25_STATE_3;
	}

	/*
	 *	Incoming Call User Data.
@@ -1294,7 +1301,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
			if (facilities.throughput < 0x03 ||
			    facilities.throughput > 0xDD)
				break;
			if (facilities.reverse && facilities.reverse != 1)
			if (facilities.reverse &&
				(facilities.reverse | 0x81)!= 0x81)
				break;
			x25->facilities = facilities;
			rc = 0;
@@ -1348,6 +1356,27 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
			break;
		}

		case SIOCX25CALLACCPTAPPRV: {
			rc = -EINVAL;
			if (sk->sk_state != TCP_CLOSE)
				break;
			x25->accptapprv = X25_ALLOW_ACCPT_APPRV;
			rc = 0;
			break;
		}

		case SIOCX25SENDCALLACCPT:  {
			rc = -EINVAL;
			if (sk->sk_state != TCP_ESTABLISHED)
				break;
			if (x25->accptapprv)	/* must call accptapprv above */
				break;
			x25_write_internal(sk, X25_CALL_ACCEPTED);
			x25->state = X25_STATE_3;
			rc = 0;
			break;
		}

 		default:
			rc = dev_ioctl(cmd, argp);
			break;
+29 −5
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
 *	X.25 001	Split from x25_subr.c
 *	mar/20/00	Daniela Squassoni Disabling/enabling of facilities 
 *					  negotiation.
 *	apr/14/05	Shaun Pereira - Allow fast select with no restriction
 *					on response.
 */

#include <linux/kernel.h>
@@ -43,9 +45,31 @@ int x25_parse_facilities(struct sk_buff *skb,
		case X25_FAC_CLASS_A:
			switch (*p) {
			case X25_FAC_REVERSE:
				if((p[1] & 0x81) == 0x81) {
					facilities->reverse = p[1] & 0x81;
					*vc_fac_mask |= X25_MASK_REVERSE;
					break;
				}

				if((p[1] & 0x01) == 0x01) {
					facilities->reverse = p[1] & 0x01;
					*vc_fac_mask |= X25_MASK_REVERSE;
					break;
				}

				if((p[1] & 0x80) == 0x80) {
					facilities->reverse = p[1] & 0x80;
					*vc_fac_mask |= X25_MASK_REVERSE;
					break;
				}

				if(p[1] == 0x00) {
					facilities->reverse
						= X25_DEFAULT_REVERSE;
					*vc_fac_mask |= X25_MASK_REVERSE;
					break;
				}

			case X25_FAC_THROUGHPUT:
				facilities->throughput = p[1];
				*vc_fac_mask |= X25_MASK_THROUGHPUT;
@@ -122,7 +146,7 @@ int x25_create_facilities(unsigned char *buffer,

	if (facilities->reverse && (facil_mask & X25_MASK_REVERSE)) {
		*p++ = X25_FAC_REVERSE;
		*p++ = !!facilities->reverse;
		*p++ = facilities->reverse;
	}

	if (facilities->throughput && (facil_mask & X25_MASK_THROUGHPUT)) {
@@ -171,7 +195,7 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
	/*
	 *	They want reverse charging, we won't accept it.
	 */
	if (theirs.reverse && ours->reverse) {
	if ((theirs.reverse & 0x01 ) && (ours->reverse & 0x01)) {
		SOCK_DEBUG(sk, "X.25: rejecting reverse charging request");
		return -1;
	}
+18 −5
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
 *	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>
@@ -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:
		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:
@@ -203,9 +209,16 @@ void x25_write_internal(struct sock *sk, int frametype)
							x25->vc_facil_mask);
			dptr    = skb_put(skb, len);
			memcpy(dptr, facilities, len);
			dptr = skb_put(skb, 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;