Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *	X.25 Packet Layer release 002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *	This is ALPHA test software. This code may break your machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *	randomly fail to work with new releases, misbehave and/or generally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *	screw up. It might even work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *	This code REQUIRES 2.1.15 or higher
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *	History
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *	X.25 001	Jonathan Naylor	Started coding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *	X.25 002	Jonathan Naylor	Centralised disconnect handling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *					New timer architecture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *	2000-03-11	Henner Eisen	MSG_EOR handling more POSIX compliant.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *	2000-03-22	Daniela Squassoni Allowed disabling/enabling of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *					  facilities negotiation and increased
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *					  the throughput upper limit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  *	2000-08-27	Arnaldo C. Melo s/suser/capable/ + micro cleanups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  *	2000-09-04	Henner Eisen	Set sock->state in x25_accept().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  *					Fixed x25_output() related skb leakage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  *	2000-10-02	Henner Eisen	Made x25_kick() single threaded per socket.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  *	2000-10-27	Henner Eisen    MSG_DONTWAIT for fragment allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  *	2000-11-14	Henner Eisen    Closing datalink from NETDEV_GOING_DOWN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  *	2002-10-06	Arnaldo C. Melo Get rid of cli/sti, move proc stuff to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  *					x25_proc.c, using seq_file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  *	2005-04-02	Shaun Pereira	Selective sub address matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  *					with call user data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  *	2005-04-15	Shaun Pereira	Fast select with no restriction on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  *					response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #define pr_fmt(fmt) "X25: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include <net/tcp_states.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include <linux/termios.h>	/* For TIOCINQ/OUTQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #include <net/x25.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #include <net/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) int sysctl_x25_call_request_timeout    = X25_DEFAULT_T21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) int sysctl_x25_reset_request_timeout   = X25_DEFAULT_T22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) int sysctl_x25_clear_request_timeout   = X25_DEFAULT_T23;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) int sysctl_x25_ack_holdback_timeout    = X25_DEFAULT_T2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) int sysctl_x25_forward                 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) HLIST_HEAD(x25_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) DEFINE_RWLOCK(x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) static const struct proto_ops x25_proto_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) static const struct x25_address null_x25_address = {"               "};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) struct compat_x25_subscrip_struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	char device[200-sizeof(compat_ulong_t)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	compat_ulong_t global_facil_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	compat_uint_t extended;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) int x25_parse_address_block(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 		struct x25_address *called_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 		struct x25_address *calling_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	unsigned char len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	int needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	if (!pskb_may_pull(skb, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		/* packet has no address block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 		goto empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	len = *skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	needed = 1 + ((len >> 4) + (len & 0x0f) + 1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	if (!pskb_may_pull(skb, needed)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 		/* packet is too short to hold the addresses it claims
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		   to hold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 		rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 		goto empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	return x25_addr_ntoa(skb->data, called_addr, calling_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) empty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	*called_addr->x25_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	*calling_addr->x25_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 		  struct x25_address *calling_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	unsigned int called_len, calling_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	char *called, *calling;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	called_len  = (*p >> 0) & 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	calling_len = (*p >> 4) & 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	called  = called_addr->x25_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	calling = calling_addr->x25_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	for (i = 0; i < (called_len + calling_len); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 		if (i < called_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 			if (i % 2 != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 				*called++ = ((*p >> 0) & 0x0F) + '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 				p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 				*called++ = ((*p >> 4) & 0x0F) + '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 			if (i % 2 != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 				*calling++ = ((*p >> 0) & 0x0F) + '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 				p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 				*calling++ = ((*p >> 4) & 0x0F) + '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	*called = *calling = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	return 1 + (called_len + calling_len + 1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) int x25_addr_aton(unsigned char *p, struct x25_address *called_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 		  struct x25_address *calling_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	unsigned int called_len, calling_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	char *called, *calling;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	called  = called_addr->x25_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	calling = calling_addr->x25_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	called_len  = strlen(called);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	calling_len = strlen(calling);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	*p++ = (calling_len << 4) | (called_len << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	for (i = 0; i < (called_len + calling_len); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 		if (i < called_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 			if (i % 2 != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 				*p |= (*called++ - '0') << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 				p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 				*p = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 				*p |= (*called++ - '0') << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 			if (i % 2 != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 				*p |= (*calling++ - '0') << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 				p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 				*p = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 				*p |= (*calling++ - '0') << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	return 1 + (called_len + calling_len + 1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193)  *	Socket removal during an interrupt is now safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) static void x25_remove_socket(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	write_lock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	sk_del_node_init(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	write_unlock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203)  *	Kill all bound sockets on a dropped device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) static void x25_kill_by_device(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	struct sock *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	write_lock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	sk_for_each(s, &x25_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		if (x25_sk(s)->neighbour && x25_sk(s)->neighbour->dev == dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 			x25_disconnect(s, ENETUNREACH, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	write_unlock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219)  *	Handle device status changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) static int x25_device_event(struct notifier_block *this, unsigned long event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 			    void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	struct x25_neigh *nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	if (!net_eq(dev_net(dev), &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	if (dev->type == ARPHRD_X25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) #if IS_ENABLED(CONFIG_LLC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	 || dev->type == ARPHRD_ETHER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 		switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		case NETDEV_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 			x25_link_device_up(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		case NETDEV_GOING_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 			nb = x25_get_neigh(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 			if (nb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 				x25_terminate_link(nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 				x25_neigh_put(nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		case NETDEV_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 			x25_kill_by_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 			x25_route_device_down(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 			x25_link_device_down(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258)  *	Add a socket to the bound sockets list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) static void x25_insert_socket(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	write_lock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	sk_add_node(sk, &x25_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	write_unlock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268)  *	Find a socket that wants to accept the Call Request we just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269)  *	received. Check the full list for an address/cud match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270)  *	If no cuds match return the next_best thing, an address match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271)  *	Note: if a listening socket has cud set it must only get calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272)  *	with matching cud.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) static struct sock *x25_find_listener(struct x25_address *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 					struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	struct sock *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	struct sock *next_best;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	read_lock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	next_best = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	sk_for_each(s, &x25_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		if ((!strcmp(addr->x25_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 			x25_sk(s)->source_addr.x25_addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 				!strcmp(x25_sk(s)->source_addr.x25_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 					null_x25_address.x25_addr)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 					s->sk_state == TCP_LISTEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 			 * Found a listening socket, now check the incoming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 			 * call user data vs this sockets call user data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 			if (x25_sk(s)->cudmatchlength > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 				skb->len >= x25_sk(s)->cudmatchlength) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 				if((memcmp(x25_sk(s)->calluserdata.cuddata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 					skb->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 					x25_sk(s)->cudmatchlength)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 					sock_hold(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 					goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 				 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 				next_best = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	if (next_best) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 		s = next_best;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		sock_hold(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	s = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	read_unlock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316)  *	Find a connected X.25 socket given my LCI and neighbour.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) static struct sock *__x25_find_socket(unsigned int lci, struct x25_neigh *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	struct sock *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	sk_for_each(s, &x25_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		if (x25_sk(s)->lci == lci && x25_sk(s)->neighbour == nb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 			sock_hold(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 			goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	s = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) struct sock *x25_find_socket(unsigned int lci, struct x25_neigh *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	struct sock *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	read_lock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	s = __x25_find_socket(lci, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	read_unlock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343)  *	Find a unique LCI for a given device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) static unsigned int x25_new_lci(struct x25_neigh *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	unsigned int lci = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	while ((sk = x25_find_socket(lci, nb)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		if (++lci == 4096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 			lci = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 		cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	return lci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363)  *	Deferred destroy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) static void __x25_destroy_socket(struct sock *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368)  *	handler for deferred kills.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) static void x25_destroy_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	struct sock *sk = from_timer(sk, t, sk_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	x25_destroy_socket_from_timer(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378)  *	This is called from user mode and the timers. Thus it protects itself
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379)  *	against interrupt users but doesn't worry about being called during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380)  *	work. Once it is removed from the queue no interrupt or bottom half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381)  *	will touch it and we are (fairly 8-) ) safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382)  *	Not static as it's used by the timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) static void __x25_destroy_socket(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	x25_stop_heartbeat(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	x25_stop_timer(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	x25_remove_socket(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	x25_clear_queues(sk);		/* Flush the queues */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		if (skb->sk != sk) {		/* A pending connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 			 * Queue the unaccepted socket for death
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 			skb->sk->sk_state = TCP_LISTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 			sock_set_flag(skb->sk, SOCK_DEAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 			x25_start_heartbeat(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 			x25_sk(skb->sk)->state = X25_STATE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	if (sk_has_allocations(sk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		/* Defer: outstanding buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		sk->sk_timer.expires  = jiffies + 10 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		sk->sk_timer.function = x25_destroy_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 		add_timer(&sk->sk_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		/* drop last reference so sock_put will free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		__sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) void x25_destroy_socket_from_timer(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	bh_lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	__x25_destroy_socket(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	bh_unlock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429)  *	Handling for system calls applied via the various interfaces to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430)  *	X.25 socket object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) static int x25_setsockopt(struct socket *sock, int level, int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 			  sockptr_t optval, unsigned int optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	int opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	int rc = -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	if (level != SOL_X25 || optname != X25_QBITINCL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	if (optlen < sizeof(int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	if (copy_from_sockptr(&opt, optval, sizeof(int)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	if (opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		set_bit(X25_Q_BIT_FLAG, &x25_sk(sk)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		clear_bit(X25_Q_BIT_FLAG, &x25_sk(sk)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) static int x25_getsockopt(struct socket *sock, int level, int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 			  char __user *optval, int __user *optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	int val, len, rc = -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	if (level != SOL_X25 || optname != X25_QBITINCL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	if (get_user(len, optlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	len = min_t(unsigned int, len, sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	if (len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	if (put_user(len, optlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	val = test_bit(X25_Q_BIT_FLAG, &x25_sk(sk)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	rc = copy_to_user(optval, &val, len) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) static int x25_listen(struct socket *sock, int backlog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	int rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	if (sk->sk_state != TCP_LISTEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		sk->sk_max_ack_backlog = backlog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 		sk->sk_state           = TCP_LISTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) static struct proto x25_proto = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	.name	  = "X25",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	.owner	  = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	.obj_size = sizeof(struct x25_sock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) static struct sock *x25_alloc_socket(struct net *net, int kern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	struct x25_sock *x25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	struct sock *sk = sk_alloc(net, AF_X25, GFP_ATOMIC, &x25_proto, kern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	if (!sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	sock_init_data(NULL, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	x25 = x25_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	skb_queue_head_init(&x25->ack_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	skb_queue_head_init(&x25->fragment_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	skb_queue_head_init(&x25->interrupt_in_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	skb_queue_head_init(&x25->interrupt_out_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	return sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) static int x25_create(struct net *net, struct socket *sock, int protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		      int kern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	struct x25_sock *x25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	int rc = -EAFNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	if (!net_eq(net, &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	rc = -ESOCKTNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	if (sock->type != SOCK_SEQPACKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	if (protocol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	if ((sk = x25_alloc_socket(net, kern)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	x25 = x25_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	sock_init_data(sock, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	x25_init_timers(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	sock->ops    = &x25_proto_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	sk->sk_protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	sk->sk_backlog_rcv = x25_backlog_rcv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	x25->t21   = sysctl_x25_call_request_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	x25->t22   = sysctl_x25_reset_request_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	x25->t23   = sysctl_x25_clear_request_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	x25->t2    = sysctl_x25_ack_holdback_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	x25->state = X25_STATE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	x25->cudmatchlength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	set_bit(X25_ACCPT_APPRV_FLAG, &x25->flags);	/* normally no cud  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 							/* on call accept   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	x25->facilities.winsize_in  = X25_DEFAULT_WINDOW_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	x25->facilities.pacsize_in  = X25_DEFAULT_PACKET_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	x25->facilities.throughput  = 0;	/* by default don't negotiate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 						   throughput */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	x25->facilities.reverse     = X25_DEFAULT_REVERSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	x25->dte_facilities.calling_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	x25->dte_facilities.called_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	memset(x25->dte_facilities.called_ae, '\0',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 			sizeof(x25->dte_facilities.called_ae));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	memset(x25->dte_facilities.calling_ae, '\0',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 			sizeof(x25->dte_facilities.calling_ae));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) static struct sock *x25_make_new(struct sock *osk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	struct sock *sk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	struct x25_sock *x25, *ox25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	if (osk->sk_type != SOCK_SEQPACKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	if ((sk = x25_alloc_socket(sock_net(osk), 0)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	x25 = x25_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	sk->sk_type        = osk->sk_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	sk->sk_priority    = osk->sk_priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	sk->sk_protocol    = osk->sk_protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	sk->sk_rcvbuf      = osk->sk_rcvbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	sk->sk_sndbuf      = osk->sk_sndbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	sk->sk_state       = TCP_ESTABLISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	sk->sk_backlog_rcv = osk->sk_backlog_rcv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	sock_copy_flags(sk, osk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	ox25 = x25_sk(osk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	x25->t21        = ox25->t21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	x25->t22        = ox25->t22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	x25->t23        = ox25->t23;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	x25->t2         = ox25->t2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	x25->flags	= ox25->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	x25->facilities = ox25->facilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	x25->dte_facilities = ox25->dte_facilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	x25->cudmatchlength = ox25->cudmatchlength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	clear_bit(X25_INTERRUPT_FLAG, &x25->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	x25_init_timers(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	return sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) static int x25_release(struct socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	struct x25_sock *x25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	if (!sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	x25 = x25_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	switch (x25->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		case X25_STATE_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		case X25_STATE_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 			x25_disconnect(sk, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			__x25_destroy_socket(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		case X25_STATE_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		case X25_STATE_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		case X25_STATE_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 			x25_clear_queues(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 			x25_write_internal(sk, X25_CLEAR_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 			x25_start_t23timer(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 			x25->state = X25_STATE_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 			sk->sk_state	= TCP_CLOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 			sk->sk_shutdown	|= SEND_SHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			sk->sk_state_change(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 			sock_set_flag(sk, SOCK_DEAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 			sock_set_flag(sk, SOCK_DESTROY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		case X25_STATE_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 			x25_write_internal(sk, X25_CLEAR_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 			x25_disconnect(sk, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 			__x25_destroy_socket(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	sock_orphan(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	int len, i, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	if (addr_len != sizeof(struct sockaddr_x25) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	    addr->sx25_family != AF_X25 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	    strnlen(addr->sx25_addr.x25_addr, X25_ADDR_LEN) == X25_ADDR_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	/* check for the null_x25_address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	if (strcmp(addr->sx25_addr.x25_addr, null_x25_address.x25_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		len = strlen(addr->sx25_addr.x25_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 			if (!isdigit(addr->sx25_addr.x25_addr[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 				rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	if (sock_flag(sk, SOCK_ZAPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		x25_sk(sk)->source_addr = addr->sx25_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		x25_insert_socket(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		sock_reset_flag(sk, SOCK_ZAPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	SOCK_DEBUG(sk, "x25_bind: socket is bound\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) static int x25_wait_for_connection_establishment(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	add_wait_queue_exclusive(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		__set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		rc = sock_error(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 			sk->sk_socket->state = SS_UNCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		if (sk->sk_state != TCP_ESTABLISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 			release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	__set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	remove_wait_queue(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) static int x25_connect(struct socket *sock, struct sockaddr *uaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		       int addr_len, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	struct x25_sock *x25 = x25_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	struct x25_route *rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		sock->state = SS_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		goto out; /* Connect completed during a ERESTARTSYS event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	rc = -ECONNREFUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		sock->state = SS_UNCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	rc = -EISCONN;	/* No reconnect on a seqpacket socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	if (sk->sk_state == TCP_ESTABLISHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	rc = -EALREADY;	/* Do nothing if call is already in progress */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	if (sk->sk_state == TCP_SYN_SENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	sk->sk_state   = TCP_CLOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	sock->state = SS_UNCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	if (addr_len != sizeof(struct sockaddr_x25) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	    addr->sx25_family != AF_X25 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	    strnlen(addr->sx25_addr.x25_addr, X25_ADDR_LEN) == X25_ADDR_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	rc = -ENETUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	rt = x25_get_route(&addr->sx25_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	if (!rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	x25->neighbour = x25_get_neigh(rt->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	if (!x25->neighbour)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		goto out_put_route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	x25_limit_facilities(&x25->facilities, x25->neighbour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	x25->lci = x25_new_lci(x25->neighbour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	if (!x25->lci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		goto out_put_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	if (sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		goto out_put_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	if (!strcmp(x25->source_addr.x25_addr, null_x25_address.x25_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		memset(&x25->source_addr, '\0', X25_ADDR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	x25->dest_addr = addr->sx25_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	/* Move to connecting socket, start sending Connect Requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	sock->state   = SS_CONNECTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	sk->sk_state  = TCP_SYN_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	x25->state = X25_STATE_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	x25_write_internal(sk, X25_CALL_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	x25_start_heartbeat(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	x25_start_t21timer(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	/* Now the loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	rc = -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	rc = x25_wait_for_connection_establishment(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		goto out_put_neigh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	sock->state = SS_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) out_put_neigh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	if (rc && x25->neighbour) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		read_lock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		x25_neigh_put(x25->neighbour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		x25->neighbour = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		read_unlock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		x25->state = X25_STATE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) out_put_route:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	x25_route_put(rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) static int x25_wait_for_data(struct sock *sk, long timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	add_wait_queue_exclusive(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		__set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		if (sk->sk_shutdown & RCV_SHUTDOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		rc = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		if (!timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		if (skb_queue_empty(&sk->sk_receive_queue)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 			release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 			timeout = schedule_timeout(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 			lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	__set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	remove_wait_queue(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) static int x25_accept(struct socket *sock, struct socket *newsock, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		      bool kern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	struct sock *newsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	int rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	if (!sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	if (sk->sk_type != SOCK_SEQPACKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	if (sk->sk_state != TCP_LISTEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	rc = x25_wait_for_data(sk, sk->sk_rcvtimeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	skb = skb_dequeue(&sk->sk_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	if (!skb->sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	newsk		 = skb->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	sock_graft(newsk, newsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	/* Now attach up the new socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	skb->sk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	sk_acceptq_removed(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	newsock->state = SS_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		       int peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	struct x25_sock *x25 = x25_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	if (peer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		if (sk->sk_state != TCP_ESTABLISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 			rc = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		sx25->sx25_addr = x25->dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		sx25->sx25_addr = x25->source_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	sx25->sx25_family = AF_X25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	rc = sizeof(*sx25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 			unsigned int lci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	struct sock *make;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	struct x25_sock *makex25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	struct x25_address source_addr, dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	struct x25_facilities facilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	struct x25_dte_facilities dte_facilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	int len, addr_len, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	 *	Remove the LCI and frame type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	skb_pull(skb, X25_STD_MIN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	 *	Extract the X.25 addresses and convert them to ASCII strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	 *	and remove them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	 *	Address block is mandatory in call request packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	addr_len = x25_parse_address_block(skb, &source_addr, &dest_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	if (addr_len <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		goto out_clear_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	skb_pull(skb, addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	 *	Get the length of the facilities, skip past them for the moment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	 *	get the call user data because this is needed to determine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	 *	the correct listener
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	 *	Facilities length is mandatory in call request packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	if (!pskb_may_pull(skb, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		goto out_clear_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	len = skb->data[0] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	if (!pskb_may_pull(skb, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		goto out_clear_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	skb_pull(skb,len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	 *	Ensure that the amount of call user data is valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	if (skb->len > X25_MAX_CUD_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		goto out_clear_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	 *	Get all the call user data so it can be used in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	 *	x25_find_listener and skb_copy_from_linear_data up ahead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	if (!pskb_may_pull(skb, skb->len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		goto out_clear_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	 *	Find a listener for the particular address/cud pair.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	sk = x25_find_listener(&source_addr,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	skb_push(skb,len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	if (sk != NULL && sk_acceptq_is_full(sk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		goto out_sock_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	 *	We dont have any listeners for this incoming call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	 *	Try forwarding it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	if (sk == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		skb_push(skb, addr_len + X25_STD_MIN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		if (sysctl_x25_forward &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 				x25_forward_call(&dest_addr, nb, skb, lci) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 			/* Call was forwarded, dont process it any more */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 			rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			/* No listeners, can't forward, clear the call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 			goto out_clear_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	 *	Try to reach a compromise on the requested facilities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	len = x25_negotiate_facilities(skb, sk, &facilities, &dte_facilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	if (len == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		goto out_sock_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	 * current neighbour/link might impose additional limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	 * on certain facilties
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	x25_limit_facilities(&facilities, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	 *	Try to create a new socket.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	make = x25_make_new(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	if (!make)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		goto out_sock_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	 *	Remove the facilities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	skb_pull(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	skb->sk     = make;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	make->sk_state = TCP_ESTABLISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	makex25 = x25_sk(make);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	makex25->lci           = lci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	makex25->dest_addr     = dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	makex25->source_addr   = source_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	x25_neigh_hold(nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	makex25->neighbour     = nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	makex25->facilities    = facilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	makex25->dte_facilities= dte_facilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	/* ensure no reverse facil on accept */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	makex25->vc_facil_mask &= ~X25_MASK_REVERSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	/* ensure no calling address extension on accept */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	makex25->vc_facil_mask &= ~X25_MASK_CALLING_AE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	makex25->cudmatchlength = x25_sk(sk)->cudmatchlength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	/* Normally all calls are accepted immediately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	if (test_bit(X25_ACCPT_APPRV_FLAG, &makex25->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		x25_write_internal(make, X25_CALL_ACCEPTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		makex25->state = X25_STATE_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		makex25->state = X25_STATE_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	 *	Incoming Call User Data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	skb_copy_from_linear_data(skb, makex25->calluserdata.cuddata, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	makex25->calluserdata.cudlength = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	sk_acceptq_added(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	x25_insert_socket(make);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	skb_queue_head(&sk->sk_receive_queue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	x25_start_heartbeat(make);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	if (!sock_flag(sk, SOCK_DEAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		sk->sk_data_ready(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) out_sock_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) out_clear_request:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	x25_transmit_clear_request(nb, lci, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) static int x25_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	struct x25_sock *x25 = x25_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	DECLARE_SOCKADDR(struct sockaddr_x25 *, usx25, msg->msg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	struct sockaddr_x25 sx25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	unsigned char *asmptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	int noblock = msg->msg_flags & MSG_DONTWAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	int qbit = 0, rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR|MSG_CMSG_COMPAT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	/* we currently don't support segmented records at the user interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	if (!(msg->msg_flags & (MSG_EOR|MSG_OOB)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	rc = -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	if (sock_flag(sk, SOCK_ZAPPED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	rc = -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	if (sk->sk_shutdown & SEND_SHUTDOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 		send_sig(SIGPIPE, current, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	rc = -ENETUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	if (!x25->neighbour)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	if (usx25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 		if (msg->msg_namelen < sizeof(sx25))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 		memcpy(&sx25, usx25, sizeof(sx25));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		rc = -EISCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		if (strcmp(x25->dest_addr.x25_addr, sx25.sx25_addr.x25_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		if (sx25.sx25_family != AF_X25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		 *	FIXME 1003.1g - if the socket is like this because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		 *	it has become closed (not started closed) we ought
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		 *	to SIGPIPE, EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		rc = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		if (sk->sk_state != TCP_ESTABLISHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		sx25.sx25_family = AF_X25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		sx25.sx25_addr   = x25->dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	/* Sanity check the packet size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	if (len > 65535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		rc = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	SOCK_DEBUG(sk, "x25_sendmsg: sendto: Addresses built.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	/* Build a packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	SOCK_DEBUG(sk, "x25_sendmsg: sendto: building packet.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	if ((msg->msg_flags & MSG_OOB) && len > 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		len = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	size = len + X25_MAX_L2_LEN + X25_EXT_MIN_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	skb = sock_alloc_send_skb(sk, size, noblock, &rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	X25_SKB_CB(skb)->flags = msg->msg_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	skb_reserve(skb, X25_MAX_L2_LEN + X25_EXT_MIN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	 *	Put the data on the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	SOCK_DEBUG(sk, "x25_sendmsg: Copying user data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	skb_reset_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	skb_put(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	rc = memcpy_from_msg(skb_transport_header(skb), msg, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		goto out_kfree_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	 *	If the Q BIT Include socket option is in force, the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	 *	byte of the user data is the logical value of the Q Bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		if (!pskb_may_pull(skb, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 			goto out_kfree_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 		qbit = skb->data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		skb_pull(skb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	 *	Push down the X.25 header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	SOCK_DEBUG(sk, "x25_sendmsg: Building X.25 Header.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	if (msg->msg_flags & MSG_OOB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 		if (x25->neighbour->extended) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 			asmptr    = skb_push(skb, X25_STD_MIN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 			*asmptr++ = ((x25->lci >> 8) & 0x0F) | X25_GFI_EXTSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 			*asmptr++ = (x25->lci >> 0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 			*asmptr++ = X25_INTERRUPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 			asmptr    = skb_push(skb, X25_STD_MIN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 			*asmptr++ = ((x25->lci >> 8) & 0x0F) | X25_GFI_STDSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 			*asmptr++ = (x25->lci >> 0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 			*asmptr++ = X25_INTERRUPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		if (x25->neighbour->extended) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 			/* Build an Extended X.25 header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 			asmptr    = skb_push(skb, X25_EXT_MIN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 			*asmptr++ = ((x25->lci >> 8) & 0x0F) | X25_GFI_EXTSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 			*asmptr++ = (x25->lci >> 0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 			*asmptr++ = X25_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 			*asmptr++ = X25_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 			/* Build an Standard X.25 header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 			asmptr    = skb_push(skb, X25_STD_MIN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 			*asmptr++ = ((x25->lci >> 8) & 0x0F) | X25_GFI_STDSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 			*asmptr++ = (x25->lci >> 0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 			*asmptr++ = X25_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		if (qbit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 			skb->data[0] |= X25_Q_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	SOCK_DEBUG(sk, "x25_sendmsg: Built header.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	SOCK_DEBUG(sk, "x25_sendmsg: Transmitting buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	rc = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	if (sk->sk_state != TCP_ESTABLISHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		goto out_kfree_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	if (msg->msg_flags & MSG_OOB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		skb_queue_tail(&x25->interrupt_out_queue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		rc = x25_output(sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		len = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 		if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 			kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		else if (test_bit(X25_Q_BIT_FLAG, &x25->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 			len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	x25_kick(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	rc = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) out_kfree_skb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) static int x25_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		       int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	struct x25_sock *x25 = x25_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	DECLARE_SOCKADDR(struct sockaddr_x25 *, sx25, msg->msg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	size_t copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	int qbit, header_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	unsigned char *asmptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	int rc = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	if (x25->neighbour == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	header_len = x25->neighbour->extended ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		X25_EXT_MIN_LEN : X25_STD_MIN_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	 * This works for seqpacket too. The receiver has ordered the queue for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	 * us! We do one quick check first though
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	if (sk->sk_state != TCP_ESTABLISHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	if (flags & MSG_OOB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		if (sock_flag(sk, SOCK_URGINLINE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 		    !skb_peek(&x25->interrupt_in_queue))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 		skb = skb_dequeue(&x25->interrupt_in_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 		if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 			goto out_free_dgram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 		skb_pull(skb, X25_STD_MIN_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 		 *	No Q bit information on Interrupt data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 		if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 			asmptr  = skb_push(skb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 			*asmptr = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 		msg->msg_flags |= MSG_OOB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 		/* Now we can treat all alike */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 		skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 					flags & MSG_DONTWAIT, &rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 		if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		if (!pskb_may_pull(skb, header_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 			goto out_free_dgram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 		qbit = (skb->data[0] & X25_Q_BIT) == X25_Q_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 		skb_pull(skb, header_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 		if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 			asmptr  = skb_push(skb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 			*asmptr = qbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	skb_reset_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	copied = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	if (copied > size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 		copied = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 		msg->msg_flags |= MSG_TRUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	/* Currently, each datagram always contains a complete record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	msg->msg_flags |= MSG_EOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	rc = skb_copy_datagram_msg(skb, 0, msg, copied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 		goto out_free_dgram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	if (sx25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 		sx25->sx25_family = AF_X25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		sx25->sx25_addr   = x25->dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		msg->msg_namelen = sizeof(*sx25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	x25_check_rbuf(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	rc = copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) out_free_dgram:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	skb_free_datagram(sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	struct x25_sock *x25 = x25_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	case TIOCOUTQ: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		int amount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 		if (amount < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 			amount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 		rc = put_user(amount, (unsigned int __user *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	case TIOCINQ: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 		struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		int amount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 		 * These two are safe on a single CPU system as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		 * only user tasks fiddle here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 			amount = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 		rc = put_user(amount, (unsigned int __user *)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	case SIOCGIFADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	case SIOCSIFADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	case SIOCGIFDSTADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	case SIOCSIFDSTADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	case SIOCGIFBRDADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	case SIOCSIFBRDADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	case SIOCGIFNETMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	case SIOCSIFNETMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	case SIOCGIFMETRIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	case SIOCSIFMETRIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	case SIOCADDRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	case SIOCDELRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 		rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 		if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 		rc = x25_route_ioctl(cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	case SIOCX25GSUBSCRIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 		rc = x25_subscr_ioctl(cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	case SIOCX25SSUBSCRIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 		rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 		if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 		rc = x25_subscr_ioctl(cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	case SIOCX25GFACILITIES: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 		rc = copy_to_user(argp, &x25->facilities,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 				  sizeof(x25->facilities))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 			? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	case SIOCX25SFACILITIES: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 		struct x25_facilities facilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 		rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		if (copy_from_user(&facilities, argp, sizeof(facilities)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 		if (sk->sk_state != TCP_LISTEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 		    sk->sk_state != TCP_CLOSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 			goto out_fac_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 		if (facilities.pacsize_in < X25_PS16 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 		    facilities.pacsize_in > X25_PS4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 			goto out_fac_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		if (facilities.pacsize_out < X25_PS16 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		    facilities.pacsize_out > X25_PS4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 			goto out_fac_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 		if (facilities.winsize_in < 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		    facilities.winsize_in > 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 			goto out_fac_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		if (facilities.throughput) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 			int out = facilities.throughput & 0xf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 			int in  = facilities.throughput & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 			if (!out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 				facilities.throughput |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 					X25_DEFAULT_THROUGHPUT << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 			else if (out < 0x30 || out > 0xD0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 				goto out_fac_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 			if (!in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 				facilities.throughput |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 					X25_DEFAULT_THROUGHPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 			else if (in < 0x03 || in > 0x0D)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 				goto out_fac_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 		if (facilities.reverse &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 		    (facilities.reverse & 0x81) != 0x81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 			goto out_fac_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		x25->facilities = facilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) out_fac_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	case SIOCX25GDTEFACILITIES: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 		rc = copy_to_user(argp, &x25->dte_facilities,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 				  sizeof(x25->dte_facilities));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 			rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	case SIOCX25SDTEFACILITIES: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 		struct x25_dte_facilities dtefacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 		rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 		if (copy_from_user(&dtefacs, argp, sizeof(dtefacs)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 		if (sk->sk_state != TCP_LISTEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 		    sk->sk_state != TCP_CLOSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 			goto out_dtefac_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 		if (dtefacs.calling_len > X25_MAX_AE_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 			goto out_dtefac_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 		if (dtefacs.called_len > X25_MAX_AE_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 			goto out_dtefac_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 		x25->dte_facilities = dtefacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) out_dtefac_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	case SIOCX25GCALLUSERDATA: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 		rc = copy_to_user(argp, &x25->calluserdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 				  sizeof(x25->calluserdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 			? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	case SIOCX25SCALLUSERDATA: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 		struct x25_calluserdata calluserdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 		if (copy_from_user(&calluserdata, argp, sizeof(calluserdata)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 		if (calluserdata.cudlength > X25_MAX_CUD_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 		x25->calluserdata = calluserdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	case SIOCX25GCAUSEDIAG: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 		rc = copy_to_user(argp, &x25->causediag, sizeof(x25->causediag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 			? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	case SIOCX25SCAUSEDIAG: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 		struct x25_causediag causediag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 		rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 		if (copy_from_user(&causediag, argp, sizeof(causediag)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 		x25->causediag = causediag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	case SIOCX25SCUDMATCHLEN: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 		struct x25_subaddr sub_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		if(sk->sk_state != TCP_CLOSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 			goto out_cud_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 		rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		if (copy_from_user(&sub_addr, argp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 				   sizeof(sub_addr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 			goto out_cud_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 		if (sub_addr.cudmatchlength > X25_MAX_CUD_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 			goto out_cud_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 		x25->cudmatchlength = sub_addr.cudmatchlength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) out_cud_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	case SIOCX25CALLACCPTAPPRV: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 		if (sk->sk_state == TCP_CLOSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 			clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 			rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	case SIOCX25SENDCALLACCPT:  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 		if (sk->sk_state != TCP_ESTABLISHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 			goto out_sendcallaccpt_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 		/* must call accptapprv above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 		if (test_bit(X25_ACCPT_APPRV_FLAG, &x25->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 			goto out_sendcallaccpt_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 		x25_write_internal(sk, X25_CALL_ACCEPTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 		x25->state = X25_STATE_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) out_sendcallaccpt_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 		rc = -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) static const struct net_proto_family x25_family_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	.family =	AF_X25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	.create =	x25_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	.owner	=	THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) static int compat_x25_subscr_ioctl(unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 		struct compat_x25_subscrip_struct __user *x25_subscr32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	struct compat_x25_subscrip_struct x25_subscr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	struct x25_neigh *nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	int rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	if (copy_from_user(&x25_subscr, x25_subscr32, sizeof(*x25_subscr32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	dev = x25_dev_get(x25_subscr.device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	if (dev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	nb = x25_get_neigh(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	if (nb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 		goto out_dev_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	if (cmd == SIOCX25GSUBSCRIP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 		read_lock_bh(&x25_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 		x25_subscr.extended = nb->extended;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 		x25_subscr.global_facil_mask = nb->global_facil_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 		read_unlock_bh(&x25_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 		rc = copy_to_user(x25_subscr32, &x25_subscr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 				sizeof(*x25_subscr32)) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 		if (x25_subscr.extended == 0 || x25_subscr.extended == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 			rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 			write_lock_bh(&x25_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 			nb->extended = x25_subscr.extended;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 			nb->global_facil_mask = x25_subscr.global_facil_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 			write_unlock_bh(&x25_neigh_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	x25_neigh_put(nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) out_dev_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 				unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	void __user *argp = compat_ptr(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	int rc = -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	switch(cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	case TIOCOUTQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	case TIOCINQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 		rc = x25_ioctl(sock, cmd, (unsigned long)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	case SIOCGIFADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	case SIOCSIFADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	case SIOCGIFDSTADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	case SIOCSIFDSTADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	case SIOCGIFBRDADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	case SIOCSIFBRDADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	case SIOCGIFNETMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	case SIOCSIFNETMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	case SIOCGIFMETRIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	case SIOCSIFMETRIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	case SIOCADDRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	case SIOCDELRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 		rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 		if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 		rc = x25_route_ioctl(cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	case SIOCX25GSUBSCRIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 		rc = compat_x25_subscr_ioctl(cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	case SIOCX25SSUBSCRIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 		if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 		rc = compat_x25_subscr_ioctl(cmd, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 	case SIOCX25GFACILITIES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	case SIOCX25SFACILITIES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	case SIOCX25GDTEFACILITIES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 	case SIOCX25SDTEFACILITIES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	case SIOCX25GCALLUSERDATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	case SIOCX25SCALLUSERDATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	case SIOCX25GCAUSEDIAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	case SIOCX25SCAUSEDIAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	case SIOCX25SCUDMATCHLEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	case SIOCX25CALLACCPTAPPRV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	case SIOCX25SENDCALLACCPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 		rc = x25_ioctl(sock, cmd, (unsigned long)argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 		rc = -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) static const struct proto_ops x25_proto_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	.family =	AF_X25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	.owner =	THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	.release =	x25_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	.bind =		x25_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	.connect =	x25_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	.socketpair =	sock_no_socketpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	.accept =	x25_accept,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 	.getname =	x25_getname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	.poll =		datagram_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	.ioctl =	x25_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	.compat_ioctl = compat_x25_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	.gettstamp =	sock_gettstamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	.listen =	x25_listen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	.shutdown =	sock_no_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	.setsockopt =	x25_setsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	.getsockopt =	x25_getsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	.sendmsg =	x25_sendmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	.recvmsg =	x25_recvmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	.mmap =		sock_no_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	.sendpage =	sock_no_sendpage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) static struct packet_type x25_packet_type __read_mostly = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	.type =	cpu_to_be16(ETH_P_X25),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	.func =	x25_lapb_receive_frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) static struct notifier_block x25_dev_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	.notifier_call = x25_device_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) void x25_kill_by_neigh(struct x25_neigh *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	struct sock *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	write_lock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	sk_for_each(s, &x25_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 		if (x25_sk(s)->neighbour == nb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 			write_unlock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 			lock_sock(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 			x25_disconnect(s, ENETUNREACH, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 			release_sock(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 			write_lock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	write_unlock_bh(&x25_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	/* Remove any related forwards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 	x25_clear_forward_by_dev(nb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) static int __init x25_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 	rc = proto_register(&x25_proto, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	rc = sock_register(&x25_family_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 		goto out_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	dev_add_pack(&x25_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	rc = register_netdevice_notifier(&x25_dev_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 		goto out_sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	rc = x25_register_sysctl();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 		goto out_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	rc = x25_proc_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 		goto out_sysctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	pr_info("Linux Version 0.2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) out_sysctl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	x25_unregister_sysctl();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) out_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	unregister_netdevice_notifier(&x25_dev_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) out_sock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	dev_remove_pack(&x25_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	sock_unregister(AF_X25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) out_proto:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	proto_unregister(&x25_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) module_init(x25_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) static void __exit x25_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	x25_proc_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 	x25_link_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	x25_route_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	x25_unregister_sysctl();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 	unregister_netdevice_notifier(&x25_dev_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 	dev_remove_pack(&x25_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	sock_unregister(AF_X25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	proto_unregister(&x25_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) module_exit(x25_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) MODULE_ALIAS_NETPROTO(PF_X25);