^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * DECnet An implementation of the DECnet protocol suite for the LINUX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * operating system. DECnet is implemented using the BSD Socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * interface as the means of communication with the user level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * DECnet Socket Layer Interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Authors: Eduardo Marcelo Serrat <emserrat@geocities.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Patrick Caulfield <patrick@pandh.demon.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Changes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Steve Whitehouse: Copied from Eduardo Serrat and Patrick Caulfield's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * version of the code. Original copyright preserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Steve Whitehouse: Some bug fixes, cleaning up some code to make it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * compatible with my routing layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Steve Whitehouse: Merging changes from Eduardo Serrat and Patrick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Caulfield.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Steve Whitehouse: Further bug fixes, checking module code still works
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * with new routing layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Steve Whitehouse: Additional set/get_sockopt() calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Steve Whitehouse: Fixed TIOCINQ ioctl to be same as Eduardo's new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Steve Whitehouse: recvmsg() changed to try and behave in a POSIX like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * way. Didn't manage it entirely, but its better.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Steve Whitehouse: ditto for sendmsg().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Steve Whitehouse: A selection of bug fixes to various things.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Steve Whitehouse: Added TIOCOUTQ ioctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Steve Whitehouse: Fixes to username2sockaddr & sockaddr2username.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * Steve Whitehouse: Fixes to connect() error returns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * Patrick Caulfield: Fixes to delayed acceptance logic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * David S. Miller: New socket locking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * Steve Whitehouse: Socket list hashing/locking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * Arnaldo C. Melo: use capable, not suser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Steve Whitehouse: Removed unused code. Fix to use sk->allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * when required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * Patrick Caulfield: /proc/net/decnet now has object name/number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * Steve Whitehouse: Fixed local port allocation, hashed sk list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Matthew Wilcox: Fixes for dn_ioctl()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * Steve Whitehouse: New connect/accept logic to allow timeouts and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * prepare for sendpage etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) (c) 1995-1998 E.M. Serrat emserrat@geocities.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) HISTORY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) Version Kernel Date Author/Comments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ------- ------ ---- ---------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) Version 0.0.1 2.0.30 01-dic-97 Eduardo Marcelo Serrat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) (emserrat@geocities.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) First Development of DECnet Socket La-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) yer for Linux. Only supports outgoing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) connections.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) Version 0.0.2 2.1.105 20-jun-98 Patrick J. Caulfield
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) (patrick@pandh.demon.co.uk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) Port to new kernel development version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) Version 0.0.3 2.1.106 25-jun-98 Eduardo Marcelo Serrat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) (emserrat@geocities.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) Added support for incoming connections
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) so we can start developing server apps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) on Linux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) Module Support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) Version 0.0.4 2.1.109 21-jul-98 Eduardo Marcelo Serrat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) (emserrat@geocities.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) Added support for X11R6.4. Now we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) use DECnet transport for X on Linux!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) Version 0.0.5 2.1.110 01-aug-98 Eduardo Marcelo Serrat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) (emserrat@geocities.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) Removed bugs on flow control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) Removed bugs on incoming accessdata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) Version 0.0.6 2.1.110 07-aug-98 Eduardo Marcelo Serrat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) dn_recvmsg fixes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) Patrick J. Caulfield
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) dn_bind fixes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) *******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #include <linux/sockios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #include <linux/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #include <linux/route.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #include <linux/netfilter.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #include <net/tcp_states.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #include <net/flow.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #include <asm/ioctls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #include <net/neighbour.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #include <net/dst.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #include <net/fib_rules.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #include <net/tcp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #include <net/dn.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #include <net/dn_nsp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #include <net/dn_dev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #include <net/dn_route.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #include <net/dn_fib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #include <net/dn_neigh.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct dn_sock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct sock sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct dn_scp scp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static void dn_keepalive(struct sock *sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define DN_SK_HASH_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define DN_SK_HASH_SIZE (1 << DN_SK_HASH_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define DN_SK_HASH_MASK (DN_SK_HASH_SIZE - 1)
^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) static const struct proto_ops dn_proto_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static DEFINE_RWLOCK(dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static struct hlist_head dn_wild_sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static atomic_long_t decnet_memory_allocated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int __dn_setsockopt(struct socket *sock, int level, int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) sockptr_t optval, unsigned int optlen, int flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static struct hlist_head *dn_find_list(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (scp->addr.sdn_flags & SDF_WILD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return hlist_empty(&dn_wild_sk) ? &dn_wild_sk : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return &dn_sk_hash[le16_to_cpu(scp->addrloc) & DN_SK_HASH_MASK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * Valid ports are those greater than zero and not already in use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int check_port(__le16 port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (port == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) sk_for_each(sk, &dn_sk_hash[le16_to_cpu(port) & DN_SK_HASH_MASK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (scp->addrloc == port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static unsigned short port_alloc(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static unsigned short port = 0x2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) unsigned short i_port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) while(check_port(cpu_to_le16(++port)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (port == i_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) scp->addrloc = cpu_to_le16(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^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) * Since this is only ever called from user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * level, we don't need a write_lock() version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * of this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int dn_hash_sock(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct hlist_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int rv = -EUSERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) BUG_ON(sk_hashed(sk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) write_lock_bh(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (!scp->addrloc && !port_alloc(sk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) rv = -EADDRINUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if ((list = dn_find_list(sk)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) sk_add_node(sk, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) rv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) write_unlock_bh(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static void dn_unhash_sock(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) write_lock(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) sk_del_node_init(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) write_unlock(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static void dn_unhash_sock_bh(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) write_lock_bh(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) sk_del_node_init(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) write_unlock_bh(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static struct hlist_head *listen_hash(struct sockaddr_dn *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) unsigned int hash = addr->sdn_objnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (hash == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) hash = addr->sdn_objnamel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) for(i = 0; i < le16_to_cpu(addr->sdn_objnamel); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) hash ^= addr->sdn_objname[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) hash ^= (hash << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^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) return &dn_sk_hash[hash & DN_SK_HASH_MASK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * Called to transform a socket from bound (i.e. with a local address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * into a listening socket (doesn't need a local port number) and rehashes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * based upon the object name/number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static void dn_rehash_sock(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct hlist_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (scp->addr.sdn_flags & SDF_WILD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) write_lock_bh(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) sk_del_node_init(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) DN_SK(sk)->addrloc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) list = listen_hash(&DN_SK(sk)->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) sk_add_node(sk, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) write_unlock_bh(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int dn_sockaddr2username(struct sockaddr_dn *sdn, unsigned char *buf, unsigned char type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *buf++ = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) *buf++ = sdn->sdn_objnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) *buf++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) *buf++ = le16_to_cpu(sdn->sdn_objnamel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) memcpy(buf, sdn->sdn_objname, le16_to_cpu(sdn->sdn_objnamel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) len = 3 + le16_to_cpu(sdn->sdn_objnamel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) memset(buf, 0, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) buf += 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) *buf++ = le16_to_cpu(sdn->sdn_objnamel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) memcpy(buf, sdn->sdn_objname, le16_to_cpu(sdn->sdn_objnamel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) len = 7 + le16_to_cpu(sdn->sdn_objnamel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * On reception of usernames, we handle types 1 and 0 for destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * addresses only. Types 2 and 4 are used for source addresses, but the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * UIC, GIC are ignored and they are both treated the same way. Type 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * is never used as I've no idea what its purpose might be or what its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * format is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) int dn_username2sockaddr(unsigned char *data, int len, struct sockaddr_dn *sdn, unsigned char *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) unsigned char type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) int size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int namel = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) sdn->sdn_objnum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) sdn->sdn_objnamel = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) memset(sdn->sdn_objname, 0, DN_MAXOBJL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (len < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) *fmt = *data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) type = *data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) switch (*fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) sdn->sdn_objnum = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) namel = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) len -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) data += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) len -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) data += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) len -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) sdn->sdn_objnamel = cpu_to_le16(*data++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) len -= le16_to_cpu(sdn->sdn_objnamel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if ((len < 0) || (le16_to_cpu(sdn->sdn_objnamel) > namel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) memcpy(sdn->sdn_objname, data, le16_to_cpu(sdn->sdn_objnamel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return size - len;
^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) struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct hlist_head *list = listen_hash(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) read_lock(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) sk_for_each(sk, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (sk->sk_state != TCP_LISTEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (scp->addr.sdn_objnum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (scp->addr.sdn_objnum != addr->sdn_objnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (addr->sdn_objnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (scp->addr.sdn_objnamel != addr->sdn_objnamel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (memcmp(scp->addr.sdn_objname, addr->sdn_objname, le16_to_cpu(addr->sdn_objnamel)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) read_unlock(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) sk = sk_head(&dn_wild_sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (sk->sk_state == TCP_LISTEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) sk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) read_unlock(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct sock *dn_find_by_skb(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct dn_skb_cb *cb = DN_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct dn_scp *scp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) read_lock(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) sk_for_each(sk, &dn_sk_hash[le16_to_cpu(cb->dst_port) & DN_SK_HASH_MASK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (cb->src != dn_saddr2dn(&scp->peer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (cb->dst_port != scp->addrloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (scp->addrrem && (cb->src_port != scp->addrrem))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) sk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) read_unlock(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static void dn_destruct(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) skb_queue_purge(&scp->data_xmit_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) skb_queue_purge(&scp->other_xmit_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) skb_queue_purge(&scp->other_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) dst_release(rcu_dereference_protected(sk->sk_dst_cache, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static unsigned long dn_memory_pressure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static void dn_enter_memory_pressure(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (!dn_memory_pressure) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) dn_memory_pressure = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static struct proto dn_proto = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .name = "NSP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .enter_memory_pressure = dn_enter_memory_pressure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .memory_pressure = &dn_memory_pressure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .memory_allocated = &decnet_memory_allocated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .sysctl_mem = sysctl_decnet_mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .sysctl_wmem = sysctl_decnet_wmem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .sysctl_rmem = sysctl_decnet_rmem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .max_header = DN_MAX_NSP_DATA_HEADER + 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .obj_size = sizeof(struct dn_sock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp, int kern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct dn_scp *scp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct sock *sk = sk_alloc(net, PF_DECnet, gfp, &dn_proto, kern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (!sk)
^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) if (sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) sock->ops = &dn_proto_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) sock_init_data(sock, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) sk->sk_backlog_rcv = dn_nsp_backlog_rcv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) sk->sk_destruct = dn_destruct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) sk->sk_no_check_tx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) sk->sk_family = PF_DECnet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) sk->sk_protocol = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) sk->sk_allocation = gfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) sk->sk_sndbuf = sysctl_decnet_wmem[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) sk->sk_rcvbuf = sysctl_decnet_rmem[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* Initialization of DECnet Session Control Port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) scp->state = DN_O; /* Open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) scp->numdat = 1; /* Next data seg to tx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) scp->numoth = 1; /* Next oth data to tx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) scp->ackxmt_dat = 0; /* Last data seg ack'ed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) scp->ackxmt_oth = 0; /* Last oth data ack'ed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) scp->ackrcv_dat = 0; /* Highest data ack recv*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) scp->ackrcv_oth = 0; /* Last oth data ack rec*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) scp->flowrem_sw = DN_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) scp->flowloc_sw = DN_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) scp->flowrem_dat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) scp->flowrem_oth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) scp->flowloc_dat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) scp->flowloc_oth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) scp->services_rem = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) scp->services_loc = 1 | NSP_FC_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) scp->info_rem = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) scp->info_loc = 0x03; /* NSP version 4.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) scp->segsize_rem = 230 - DN_MAX_NSP_DATA_HEADER; /* Default: Updated by remote segsize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) scp->nonagle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) scp->multi_ireq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) scp->accept_mode = ACC_IMMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) scp->addr.sdn_family = AF_DECnet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) scp->peer.sdn_family = AF_DECnet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) scp->accessdata.acc_accl = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) memcpy(scp->accessdata.acc_acc, "LINUX", 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) scp->max_window = NSP_MAX_WINDOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) scp->snd_window = NSP_MIN_WINDOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) scp->nsp_srtt = NSP_INITIAL_SRTT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) scp->nsp_rttvar = NSP_INITIAL_RTTVAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) scp->nsp_rxtshift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) skb_queue_head_init(&scp->data_xmit_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) skb_queue_head_init(&scp->other_xmit_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) skb_queue_head_init(&scp->other_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) scp->persist = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) scp->persist_fxn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) scp->keepalive = 10 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) scp->keepalive_fxn = dn_keepalive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) dn_start_slow_timer(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * Keepalive timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * FIXME: Should respond to SO_KEEPALIVE etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static void dn_keepalive(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * By checking the other_data transmit queue is empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * we are double checking that we are not sending too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * many of these keepalive frames.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (skb_queue_empty(&scp->other_xmit_queue))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) dn_nsp_send_link(sk, DN_NOCHANGE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * Timer for shutdown/destroyed sockets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * When socket is dead & no packets have been sent for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * certain amount of time, they are removed by this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * routine. Also takes care of sending out DI & DC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * frames at correct times.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) int dn_destroy_timer(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) scp->persist = dn_nsp_persist(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) switch (scp->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) case DN_DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) dn_nsp_send_disc(sk, NSP_DISCINIT, 0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (scp->nsp_rxtshift >= decnet_di_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) scp->state = DN_CN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) case DN_DR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) dn_nsp_send_disc(sk, NSP_DISCINIT, 0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (scp->nsp_rxtshift >= decnet_dr_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) scp->state = DN_DRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) case DN_DN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (scp->nsp_rxtshift < decnet_dn_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) /* printk(KERN_DEBUG "dn_destroy_timer: DN\n"); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) dn_nsp_send_disc(sk, NSP_DISCCONF, NSP_REASON_DC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) scp->persist = (HZ * decnet_time_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (sk->sk_socket)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (time_after_eq(jiffies, scp->stamp + HZ * decnet_time_wait)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) dn_unhash_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static void dn_destroy_sock(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) scp->nsp_rxtshift = 0; /* reset back off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (sk->sk_socket) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (sk->sk_socket->state != SS_UNCONNECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) sk->sk_socket->state = SS_DISCONNECTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) sk->sk_state = TCP_CLOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) switch (scp->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) case DN_DN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) dn_nsp_send_disc(sk, NSP_DISCCONF, NSP_REASON_DC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) sk->sk_allocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) scp->persist_fxn = dn_destroy_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) scp->persist = dn_nsp_persist(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) case DN_CR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) scp->state = DN_DR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) goto disc_reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) case DN_RUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) scp->state = DN_DI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) case DN_DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) case DN_DR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) disc_reject:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) dn_nsp_send_disc(sk, NSP_DISCINIT, 0, sk->sk_allocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) case DN_NC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) case DN_NR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) case DN_RJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case DN_DIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) case DN_CN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) case DN_DRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) case DN_CI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) case DN_CD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) scp->persist_fxn = dn_destroy_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) scp->persist = dn_nsp_persist(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) printk(KERN_DEBUG "DECnet: dn_destroy_sock passed socket in invalid state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) case DN_O:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) dn_stop_slow_timer(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dn_unhash_sock_bh(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) char *dn_addr2asc(__u16 addr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) unsigned short node, area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) node = addr & 0x03ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) area = addr >> 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) sprintf(buf, "%hd.%hd", area, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static int dn_create(struct net *net, struct socket *sock, int protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) int kern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (protocol < 0 || protocol > U8_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (!net_eq(net, &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return -EAFNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) switch (sock->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) case SOCK_SEQPACKET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (protocol != DNPROTO_NSP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) case SOCK_STREAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return -ESOCKTNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if ((sk = dn_alloc_sock(net, sock, GFP_KERNEL, kern)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) sk->sk_protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return 0;
^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) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) dn_release(struct socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) sock_orphan(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) dn_destroy_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct sockaddr_dn *saddr = (struct sockaddr_dn *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) struct net_device *dev, *ldev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (addr_len != sizeof(struct sockaddr_dn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (saddr->sdn_family != AF_DECnet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (le16_to_cpu(saddr->sdn_nodeaddrl) && (le16_to_cpu(saddr->sdn_nodeaddrl) != 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (le16_to_cpu(saddr->sdn_objnamel) > DN_MAXOBJL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (saddr->sdn_flags & ~SDF_WILD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (!capable(CAP_NET_BIND_SERVICE) && (saddr->sdn_objnum ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) (saddr->sdn_flags & SDF_WILD)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (!(saddr->sdn_flags & SDF_WILD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (le16_to_cpu(saddr->sdn_nodeaddrl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) ldev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) for_each_netdev_rcu(&init_net, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (!dev->dn_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) ldev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (ldev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) rv = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (sock_flag(sk, SOCK_ZAPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) memcpy(&scp->addr, saddr, addr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) sock_reset_flag(sk, SOCK_ZAPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) rv = dn_hash_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) sock_set_flag(sk, SOCK_ZAPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static int dn_auto_bind(struct socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) sock_reset_flag(sk, SOCK_ZAPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) scp->addr.sdn_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) scp->addr.sdn_objnum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * This stuff is to keep compatibility with Eduardo's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * patch. I hope I can dispense with it shortly...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if ((scp->accessdata.acc_accl != 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) (scp->accessdata.acc_accl <= 12)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) scp->addr.sdn_objnamel = cpu_to_le16(scp->accessdata.acc_accl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) memcpy(scp->addr.sdn_objname, scp->accessdata.acc_acc, le16_to_cpu(scp->addr.sdn_objnamel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) scp->accessdata.acc_accl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) memset(scp->accessdata.acc_acc, 0, 40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /* End of compatibility stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) scp->addr.sdn_add.a_len = cpu_to_le16(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) rv = dn_dev_bind_default((__le16 *)scp->addr.sdn_add.a_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (rv == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) rv = dn_hash_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) sock_set_flag(sk, SOCK_ZAPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) DEFINE_WAIT_FUNC(wait, woken_wake_function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (scp->state != DN_CR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) scp->state = DN_CC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) scp->segsize_loc = dst_metric_advmss(__sk_dst_get(sk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) dn_send_conn_conf(sk, allocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) add_wait_queue(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) for(;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (scp->state == DN_CC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) *timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (scp->state == DN_RUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) err = sock_error(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) err = sock_intr_errno(*timeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) err = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (!*timeo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) remove_wait_queue(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) sk->sk_socket->state = SS_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) } else if (scp->state != DN_CC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) sk->sk_socket->state = SS_UNCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) static int dn_wait_run(struct sock *sk, long *timeo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) DEFINE_WAIT_FUNC(wait, woken_wake_function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (scp->state == DN_RUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (!*timeo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) add_wait_queue(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) for(;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (scp->state == DN_CI || scp->state == DN_CC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) *timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (scp->state == DN_RUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) err = sock_error(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) err = sock_intr_errno(*timeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) err = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (!*timeo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) remove_wait_queue(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) sk->sk_socket->state = SS_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) } else if (scp->state != DN_CI && scp->state != DN_CC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) sk->sk_socket->state = SS_UNCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static int __dn_connect(struct sock *sk, struct sockaddr_dn *addr, int addrlen, long *timeo, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct socket *sock = sk->sk_socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) int err = -EISCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) struct flowidn fld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) struct dst_entry *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (sock->state == SS_CONNECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (sock->state == SS_CONNECTING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (scp->state == DN_RUN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) sock->state = SS_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) err = -ECONNREFUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (scp->state != DN_CI && scp->state != DN_CC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) sock->state = SS_UNCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return dn_wait_run(sk, timeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (scp->state != DN_O)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (addr == NULL || addrlen != sizeof(struct sockaddr_dn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (addr->sdn_family != AF_DECnet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (addr->sdn_flags & SDF_WILD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (sock_flag(sk, SOCK_ZAPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) err = dn_auto_bind(sk->sk_socket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) memcpy(&scp->peer, addr, sizeof(struct sockaddr_dn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) err = -EHOSTUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) memset(&fld, 0, sizeof(fld));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) fld.flowidn_oif = sk->sk_bound_dev_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) fld.daddr = dn_saddr2dn(&scp->peer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) fld.saddr = dn_saddr2dn(&scp->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) dn_sk_ports_copy(&fld, scp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) fld.flowidn_proto = DNPROTO_NSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (dn_route_output_sock(&sk->sk_dst_cache, &fld, sk, flags) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) dst = __sk_dst_get(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) sk->sk_route_caps = dst->dev->features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) sock->state = SS_CONNECTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) scp->state = DN_CI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) scp->segsize_loc = dst_metric_advmss(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) dn_nsp_send_conninit(sk, NSP_CI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) err = -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (*timeo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) err = dn_wait_run(sk, timeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) static int dn_connect(struct socket *sock, struct sockaddr *uaddr, int addrlen, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct sockaddr_dn *addr = (struct sockaddr_dn *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) err = __dn_connect(sk, addr, addrlen, &timeo, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) static inline int dn_check_state(struct sock *sk, struct sockaddr_dn *addr, int addrlen, long *timeo, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) switch (scp->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) case DN_RUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) case DN_CR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return dn_confirm_accept(sk, timeo, sk->sk_allocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) case DN_CI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) case DN_CC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return dn_wait_run(sk, timeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) case DN_O:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return __dn_connect(sk, addr, addrlen, timeo, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static void dn_access_copy(struct sk_buff *skb, struct accessdata_dn *acc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) unsigned char *ptr = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) acc->acc_userl = *ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) memcpy(&acc->acc_user, ptr, acc->acc_userl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) ptr += acc->acc_userl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) acc->acc_passl = *ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) memcpy(&acc->acc_pass, ptr, acc->acc_passl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) ptr += acc->acc_passl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) acc->acc_accl = *ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) memcpy(&acc->acc_acc, ptr, acc->acc_accl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) skb_pull(skb, acc->acc_accl + acc->acc_passl + acc->acc_userl + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) unsigned char *ptr = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) u16 len = *ptr++; /* yes, it's 8bit on the wire */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) BUG_ON(len > 16); /* we've checked the contents earlier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) opt->opt_optl = cpu_to_le16(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) opt->opt_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) memcpy(opt->opt_data, ptr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) skb_pull(skb, len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) DEFINE_WAIT_FUNC(wait, woken_wake_function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) struct sk_buff *skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) add_wait_queue(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) for(;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) skb = skb_dequeue(&sk->sk_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) *timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) skb = skb_dequeue(&sk->sk_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if (skb != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (sk->sk_state != TCP_LISTEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) err = sock_intr_errno(*timeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) err = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (!*timeo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) remove_wait_queue(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return skb == NULL ? ERR_PTR(err) : skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static int dn_accept(struct socket *sock, struct socket *newsock, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) bool kern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct sock *sk = sock->sk, *newsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) struct sk_buff *skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) struct dn_skb_cb *cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) unsigned char menuver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) unsigned char type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) struct dst_entry *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (sk->sk_state != TCP_LISTEN || DN_SK(sk)->state != DN_O) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) skb = skb_dequeue(&sk->sk_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) skb = dn_wait_for_connect(sk, &timeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (IS_ERR(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) return PTR_ERR(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) cb = DN_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) sk_acceptq_removed(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) newsk = dn_alloc_sock(sock_net(sk), newsock, sk->sk_allocation, kern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (newsk == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) dst = skb_dst(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) sk_dst_set(newsk, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) skb_dst_set(skb, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) DN_SK(newsk)->state = DN_CR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) DN_SK(newsk)->addrrem = cb->src_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) DN_SK(newsk)->services_rem = cb->services;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) DN_SK(newsk)->info_rem = cb->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) DN_SK(newsk)->segsize_rem = cb->segsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) DN_SK(newsk)->accept_mode = DN_SK(sk)->accept_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (DN_SK(newsk)->segsize_rem < 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) DN_SK(newsk)->segsize_rem = 230;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if ((DN_SK(newsk)->services_rem & NSP_FC_MASK) == NSP_FC_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) DN_SK(newsk)->max_window = decnet_no_fc_max_cwnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) newsk->sk_state = TCP_LISTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) memcpy(&(DN_SK(newsk)->addr), &(DN_SK(sk)->addr), sizeof(struct sockaddr_dn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * If we are listening on a wild socket, we don't want
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * the newly created socket on the wrong hash queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) DN_SK(newsk)->addr.sdn_flags &= ~SDF_WILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &(DN_SK(newsk)->addr), &type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &(DN_SK(newsk)->peer), &type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) *(__le16 *)(DN_SK(newsk)->peer.sdn_add.a_addr) = cb->src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) *(__le16 *)(DN_SK(newsk)->addr.sdn_add.a_addr) = cb->dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) menuver = *skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) skb_pull(skb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (menuver & DN_MENUVER_ACC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) dn_access_copy(skb, &(DN_SK(newsk)->accessdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (menuver & DN_MENUVER_USR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) dn_user_copy(skb, &(DN_SK(newsk)->conndata_in));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (menuver & DN_MENUVER_PRX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) DN_SK(newsk)->peer.sdn_flags |= SDF_PROXY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (menuver & DN_MENUVER_UIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) DN_SK(newsk)->peer.sdn_flags |= SDF_UICPROXY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) memcpy(&(DN_SK(newsk)->conndata_out), &(DN_SK(sk)->conndata_out),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) sizeof(struct optdata_dn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) memcpy(&(DN_SK(newsk)->discdata_out), &(DN_SK(sk)->discdata_out),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) sizeof(struct optdata_dn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) lock_sock(newsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) err = dn_hash_sock(newsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) sock_reset_flag(newsk, SOCK_ZAPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) dn_send_conn_ack(newsk);
^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) * Here we use sk->sk_allocation since although the conn conf is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) * for the newsk, the context is the old socket.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (DN_SK(newsk)->accept_mode == ACC_IMMED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) err = dn_confirm_accept(newsk, &timeo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) sk->sk_allocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) release_sock(newsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) struct sockaddr_dn *sa = (struct sockaddr_dn *)uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (peer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if ((sock->state != SS_CONNECTED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) sock->state != SS_CONNECTING) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) scp->accept_mode == ACC_IMMED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) memcpy(sa, &scp->peer, sizeof(struct sockaddr_dn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) memcpy(sa, &scp->addr, sizeof(struct sockaddr_dn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) return sizeof(struct sockaddr_dn);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) static __poll_t dn_poll(struct file *file, struct socket *sock, poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) __poll_t mask = datagram_poll(file, sock, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (!skb_queue_empty_lockless(&scp->other_receive_queue))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) mask |= EPOLLRDBAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) int err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) long amount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) switch(cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) case SIOCGIFADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) case SIOCSIFADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return dn_dev_ioctl(cmd, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) case SIOCATMARK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) val = !skb_queue_empty(&scp->other_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (scp->state != DN_RUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) val = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) case TIOCOUTQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) if (amount < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) amount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) err = put_user(amount, (int __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) case TIOCINQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) skb = skb_peek(&scp->other_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) amount = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) skb_queue_walk(&sk->sk_receive_queue, skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) amount += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) err = put_user(amount, (int __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) err = -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) static int dn_listen(struct socket *sock, int backlog)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (sock_flag(sk, SOCK_ZAPPED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) if ((DN_SK(sk)->state != DN_O) || (sk->sk_state == TCP_LISTEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) sk->sk_max_ack_backlog = backlog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) sk->sk_ack_backlog = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) sk->sk_state = TCP_LISTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) dn_rehash_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) static int dn_shutdown(struct socket *sock, int how)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) int err = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (sock->state == SS_UNCONNECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (sock->state == SS_DISCONNECTING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) if (scp->state == DN_O)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (how != SHUT_RDWR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) sk->sk_shutdown = SHUTDOWN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) dn_destroy_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) static int dn_setsockopt(struct socket *sock, int level, int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) sockptr_t optval, unsigned int optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) err = __dn_setsockopt(sock, level, optname, optval, optlen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) #ifdef CONFIG_NETFILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) /* we need to exclude all possible ENOPROTOOPTs except default case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) if (err == -ENOPROTOOPT && optname != DSO_LINKINFO &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) optname != DSO_STREAM && optname != DSO_SEQPACKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) err = nf_setsockopt(sk, PF_DECnet, optname, optval, optlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) static int __dn_setsockopt(struct socket *sock, int level, int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) sockptr_t optval, unsigned int optlen, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) long timeo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) struct optdata_dn opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) struct accessdata_dn acc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) unsigned long win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) unsigned char services;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) unsigned char info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) } u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (optlen && sockptr_is_null(optval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (optlen > sizeof(u))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if (copy_from_sockptr(&u, optval, optlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) switch (optname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) case DSO_CONDATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (sock->state == SS_CONNECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) return -EISCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if ((scp->state != DN_O) && (scp->state != DN_CR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) if (optlen != sizeof(struct optdata_dn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (le16_to_cpu(u.opt.opt_optl) > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) memcpy(&scp->conndata_out, &u.opt, optlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) case DSO_DISDATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (sock->state != SS_CONNECTED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) scp->accept_mode == ACC_IMMED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (optlen != sizeof(struct optdata_dn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if (le16_to_cpu(u.opt.opt_optl) > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) memcpy(&scp->discdata_out, &u.opt, optlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) case DSO_CONACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (sock->state == SS_CONNECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) return -EISCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) if (scp->state != DN_O)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (optlen != sizeof(struct accessdata_dn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if ((u.acc.acc_accl > DN_MAXACCL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) (u.acc.acc_passl > DN_MAXACCL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) (u.acc.acc_userl > DN_MAXACCL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) memcpy(&scp->accessdata, &u.acc, optlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) case DSO_ACCEPTMODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (sock->state == SS_CONNECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) return -EISCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) if (scp->state != DN_O)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) if (optlen != sizeof(int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if ((u.mode != ACC_IMMED) && (u.mode != ACC_DEFER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) scp->accept_mode = (unsigned char)u.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) case DSO_CONACCEPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (scp->state != DN_CR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) timeo = sock_rcvtimeo(sk, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) err = dn_confirm_accept(sk, &timeo, sk->sk_allocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) case DSO_CONREJECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) if (scp->state != DN_CR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) scp->state = DN_DR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) sk->sk_shutdown = SHUTDOWN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) dn_nsp_send_disc(sk, 0x38, 0, sk->sk_allocation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) case DSO_MAXWINDOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (optlen != sizeof(unsigned long))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) if (u.win > NSP_MAX_WINDOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) u.win = NSP_MAX_WINDOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if (u.win == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) scp->max_window = u.win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if (scp->snd_window > u.win)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) scp->snd_window = u.win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) case DSO_NODELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (optlen != sizeof(int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (scp->nonagle == TCP_NAGLE_CORK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) scp->nonagle = (u.val == 0) ? 0 : TCP_NAGLE_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) /* if (scp->nonagle == 1) { Push pending frames } */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) case DSO_CORK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (optlen != sizeof(int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) if (scp->nonagle == TCP_NAGLE_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) scp->nonagle = (u.val == 0) ? 0 : TCP_NAGLE_CORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) /* if (scp->nonagle == 0) { Push pending frames } */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) case DSO_SERVICES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) if (optlen != sizeof(unsigned char))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if ((u.services & ~NSP_FC_MASK) != 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) if ((u.services & NSP_FC_MASK) == NSP_FC_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) scp->services_loc = u.services;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) case DSO_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) if (optlen != sizeof(unsigned char))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) if (u.info & 0xfc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) scp->info_loc = u.info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) case DSO_LINKINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) case DSO_STREAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) case DSO_SEQPACKET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) return -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) static int dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) err = __dn_getsockopt(sock, level, optname, optval, optlen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) #ifdef CONFIG_NETFILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) if (err == -ENOPROTOOPT && optname != DSO_STREAM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) optname != DSO_SEQPACKET && optname != DSO_CONACCEPT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) optname != DSO_CONREJECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (get_user(len, optlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) err = nf_getsockopt(sk, PF_DECnet, optname, optval, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) err = put_user(len, optlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) static int __dn_getsockopt(struct socket *sock, int level,int optname, char __user *optval,int __user *optlen, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) struct linkinfo_dn link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) unsigned int r_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) void *r_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) if(get_user(r_len , optlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) switch (optname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) case DSO_CONDATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) if (r_len > sizeof(struct optdata_dn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) r_len = sizeof(struct optdata_dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) r_data = &scp->conndata_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) case DSO_DISDATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) if (r_len > sizeof(struct optdata_dn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) r_len = sizeof(struct optdata_dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) r_data = &scp->discdata_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) case DSO_CONACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) if (r_len > sizeof(struct accessdata_dn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) r_len = sizeof(struct accessdata_dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) r_data = &scp->accessdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) case DSO_ACCEPTMODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if (r_len > sizeof(unsigned char))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) r_len = sizeof(unsigned char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) r_data = &scp->accept_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) case DSO_LINKINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (r_len > sizeof(struct linkinfo_dn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) r_len = sizeof(struct linkinfo_dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) memset(&link, 0, sizeof(link));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) switch (sock->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) case SS_CONNECTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) link.idn_linkstate = LL_CONNECTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) case SS_DISCONNECTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) link.idn_linkstate = LL_DISCONNECTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) case SS_CONNECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) link.idn_linkstate = LL_RUNNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) link.idn_linkstate = LL_INACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) link.idn_segsize = scp->segsize_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) r_data = &link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) case DSO_MAXWINDOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) if (r_len > sizeof(unsigned long))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) r_len = sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) r_data = &scp->max_window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) case DSO_NODELAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if (r_len > sizeof(int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) r_len = sizeof(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) val = (scp->nonagle == TCP_NAGLE_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) r_data = &val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) case DSO_CORK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) if (r_len > sizeof(int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) r_len = sizeof(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) val = (scp->nonagle == TCP_NAGLE_CORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) r_data = &val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) case DSO_SERVICES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (r_len > sizeof(unsigned char))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) r_len = sizeof(unsigned char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) r_data = &scp->services_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) case DSO_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (r_len > sizeof(unsigned char))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) r_len = sizeof(unsigned char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) r_data = &scp->info_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) case DSO_STREAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) case DSO_SEQPACKET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) case DSO_CONACCEPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) case DSO_CONREJECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) return -ENOPROTOOPT;
^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) if (r_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) if (copy_to_user(optval, r_data, r_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) if (put_user(r_len, optlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, int target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (flags & MSG_OOB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) return !skb_queue_empty(q) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) skb_queue_walk(q, skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) struct dn_skb_cb *cb = DN_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) len += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) if (cb->nsp_flags & 0x40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) /* SOCK_SEQPACKET reads to EOM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (sk->sk_type == SOCK_SEQPACKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) /* so does SOCK_STREAM unless WAITALL is specified */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) if (!(flags & MSG_WAITALL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) /* minimum data length for read exceeded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (len >= target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^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) static int dn_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) struct sk_buff_head *queue = &sk->sk_receive_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) size_t target = size > 1 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) size_t copied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) int rv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) struct sk_buff *skb, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) struct dn_skb_cb *cb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) unsigned char eor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) long timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) if (sock_flag(sk, SOCK_ZAPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) rv = -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) if (sk->sk_shutdown & RCV_SHUTDOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) rv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) rv = dn_check_state(sk, NULL, 0, &timeo, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) if (flags & ~(MSG_CMSG_COMPAT|MSG_PEEK|MSG_OOB|MSG_WAITALL|MSG_DONTWAIT|MSG_NOSIGNAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) rv = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) if (flags & MSG_OOB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) queue = &scp->other_receive_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) if (flags & MSG_WAITALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) target = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) * See if there is data ready to read, sleep if there isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) for(;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) DEFINE_WAIT_FUNC(wait, woken_wake_function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) if (sk->sk_err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) if (!skb_queue_empty(&scp->other_receive_queue)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) if (!(flags & MSG_OOB)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) msg->msg_flags |= MSG_OOB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) if (!scp->other_report) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) scp->other_report = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (scp->state != DN_RUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) rv = sock_intr_errno(timeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) if (dn_data_ready(sk, queue, flags, target))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) if (flags & MSG_DONTWAIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) rv = -EWOULDBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) add_wait_queue(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) sk_wait_event(sk, &timeo, dn_data_ready(sk, queue, flags, target), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) remove_wait_queue(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) skb_queue_walk_safe(queue, skb, n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) unsigned int chunk = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) cb = DN_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) if ((chunk + copied) > size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) chunk = size - copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) if (memcpy_to_msg(msg, skb->data, chunk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) rv = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) copied += chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (!(flags & MSG_PEEK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) skb_pull(skb, chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) eor = cb->nsp_flags & 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) if (skb->len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) skb_unlink(skb, queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) * N.B. Don't refer to skb or cb after this point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) * in loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) if ((scp->flowloc_sw == DN_DONTSEND) && !dn_congested(sk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) scp->flowloc_sw = DN_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) dn_nsp_send_link(sk, DN_SEND, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) if (eor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (sk->sk_type == SOCK_SEQPACKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) if (!(flags & MSG_WAITALL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) if (flags & MSG_OOB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) if (copied >= target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) rv = copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) if (eor && (sk->sk_type == SOCK_SEQPACKET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) msg->msg_flags |= MSG_EOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (rv == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) rv = (flags & MSG_PEEK) ? -sk->sk_err : sock_error(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) if ((rv >= 0) && msg->msg_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) __sockaddr_check_size(sizeof(struct sockaddr_dn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) memcpy(msg->msg_name, &scp->peer, sizeof(struct sockaddr_dn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) msg->msg_namelen = sizeof(struct sockaddr_dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) static inline int dn_queue_too_long(struct dn_scp *scp, struct sk_buff_head *queue, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) unsigned char fctype = scp->services_rem & NSP_FC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) if (skb_queue_len(queue) >= scp->snd_window)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) if (fctype != NSP_FC_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) if (flags & MSG_OOB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) if (scp->flowrem_oth == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) if (scp->flowrem_dat == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) * The DECnet spec requires that the "routing layer" accepts packets which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) * are at least 230 bytes in size. This excludes any headers which the NSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) * layer might add, so we always assume that we'll be using the maximal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) * length header on data packets. The variation in length is due to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) * inclusion (or not) of the two 16 bit acknowledgement fields so it doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) * make much practical difference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) unsigned int dn_mss_from_pmtu(struct net_device *dev, int mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) unsigned int mss = 230 - DN_MAX_NSP_DATA_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) if (dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) mtu -= LL_RESERVED_SPACE(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) if (dn_db->use_long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) mtu -= 21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) mtu -= 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) mtu -= DN_MAX_NSP_DATA_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) * 21 = long header, 16 = guess at MAC header length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) mtu -= (21 + DN_MAX_NSP_DATA_HEADER + 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (mtu > mss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) mss = mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) return mss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) static inline unsigned int dn_current_mss(struct sock *sk, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) struct dst_entry *dst = __sk_dst_get(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) int mss_now = min_t(int, scp->segsize_loc, scp->segsize_rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) /* Other data messages are limited to 16 bytes per packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) if (flags & MSG_OOB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) return 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) /* This works out the maximum size of segment we can send out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) if (dst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) u32 mtu = dst_mtu(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) mss_now = min_t(int, dn_mss_from_pmtu(dst->dev, mtu), mss_now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) return mss_now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) * N.B. We get the timeout wrong here, but then we always did get it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) * wrong before and this is another step along the road to correcting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) * it. It ought to get updated each time we pass through the routine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) * but in practise it probably doesn't matter too much for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) static inline struct sk_buff *dn_alloc_send_pskb(struct sock *sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) unsigned long datalen, int noblock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) int *errcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) struct sk_buff *skb = sock_alloc_send_skb(sk, datalen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) noblock, errcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) skb->protocol = htons(ETH_P_DNA_RT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) skb->pkt_type = PACKET_OUTGOING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) static int dn_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) size_t mss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) struct sk_buff_head *queue = &scp->data_xmit_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) int flags = msg->msg_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) size_t sent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) int addr_len = msg->msg_namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) DECLARE_SOCKADDR(struct sockaddr_dn *, addr, msg->msg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) struct sk_buff *skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) struct dn_skb_cb *cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) unsigned char fctype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) long timeo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE|MSG_CMSG_COMPAT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) if (addr_len && (addr_len != sizeof(struct sockaddr_dn)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) * The only difference between stream sockets and sequenced packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) * sockets is that the stream sockets always behave as if MSG_EOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) * has been set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) if (sock->type == SOCK_STREAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) if (flags & MSG_EOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) flags |= MSG_EOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) err = dn_check_state(sk, addr, addr_len, &timeo, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) if (sk->sk_shutdown & SEND_SHUTDOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) err = -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) if (!(flags & MSG_NOSIGNAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) send_sig(SIGPIPE, current, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) if ((flags & MSG_TRYHARD) && sk->sk_dst_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) dst_negative_advice(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) mss = scp->segsize_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) fctype = scp->services_rem & NSP_FC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) mss = dn_current_mss(sk, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) if (flags & MSG_OOB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) queue = &scp->other_xmit_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) if (size > mss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) scp->persist_fxn = dn_nsp_xmit_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) while(sent < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) err = sock_error(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) err = sock_intr_errno(timeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) * Calculate size that we wish to send.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) len = size - sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) if (len > mss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) len = mss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) * Wait for queue size to go down below the window
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) * size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) if (dn_queue_too_long(scp, queue, flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) DEFINE_WAIT_FUNC(wait, woken_wake_function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) if (flags & MSG_DONTWAIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) err = -EWOULDBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) add_wait_queue(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) sk_wait_event(sk, &timeo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) !dn_queue_too_long(scp, queue, flags), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) remove_wait_queue(sk_sleep(sk), &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) * Get a suitably sized skb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) * 64 is a bit of a hack really, but its larger than any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) * link-layer headers and has served us well as a good
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) * guess as to their real length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) skb = dn_alloc_send_pskb(sk, len + 64 + DN_MAX_NSP_DATA_HEADER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) flags & MSG_DONTWAIT, &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) cb = DN_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) skb_reserve(skb, 64 + DN_MAX_NSP_DATA_HEADER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) if (flags & MSG_OOB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) cb->nsp_flags = 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) if (fctype != NSP_FC_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) scp->flowrem_oth--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) cb->nsp_flags = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) if (scp->seg_total == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) cb->nsp_flags |= 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) scp->seg_total += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) if (((sent + len) == size) && (flags & MSG_EOR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) cb->nsp_flags |= 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) scp->seg_total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) if (fctype == NSP_FC_SCMC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) scp->flowrem_dat--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) if (fctype == NSP_FC_SRC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) scp->flowrem_dat--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) sent += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) dn_nsp_queue_xmit(sk, skb, sk->sk_allocation, flags & MSG_OOB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) scp->persist = dn_nsp_persist(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) return sent ? sent : err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) err = sk_stream_error(sk, flags, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) static int dn_device_event(struct notifier_block *this, unsigned long event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) struct net_device *dev = netdev_notifier_info_to_dev(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) if (!net_eq(dev_net(dev), &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) case NETDEV_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) dn_dev_up(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) case NETDEV_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) dn_dev_down(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) static struct notifier_block dn_dev_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) .notifier_call = dn_device_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) static struct packet_type dn_dix_packet_type __read_mostly = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) .type = cpu_to_be16(ETH_P_DNA_RT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) .func = dn_route_rcv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) struct dn_iter_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) int bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) static struct sock *dn_socket_get_first(struct seq_file *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) struct dn_iter_state *state = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) struct sock *n = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) for(state->bucket = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) state->bucket < DN_SK_HASH_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) ++state->bucket) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) n = sk_head(&dn_sk_hash[state->bucket]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) if (n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) static struct sock *dn_socket_get_next(struct seq_file *seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) struct sock *n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) struct dn_iter_state *state = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) n = sk_next(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) while (!n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) if (++state->bucket >= DN_SK_HASH_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) n = sk_head(&dn_sk_hash[state->bucket]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) static struct sock *socket_get_idx(struct seq_file *seq, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) struct sock *sk = dn_socket_get_first(seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) if (sk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) while(*pos && (sk = dn_socket_get_next(seq, sk)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) --*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) return *pos ? NULL : sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) static void *dn_socket_get_idx(struct seq_file *seq, loff_t pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) void *rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) read_lock_bh(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) rc = socket_get_idx(seq, &pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) read_unlock_bh(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) static void *dn_socket_seq_start(struct seq_file *seq, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) return *pos ? dn_socket_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) static void *dn_socket_seq_next(struct seq_file *seq, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) void *rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) if (v == SEQ_START_TOKEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) rc = dn_socket_get_idx(seq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) rc = dn_socket_get_next(seq, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) read_unlock_bh(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) static void dn_socket_seq_stop(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) if (v && v != SEQ_START_TOKEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) read_unlock_bh(&dn_hash_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) #define IS_NOT_PRINTABLE(x) ((x) < 32 || (x) > 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) static void dn_printable_object(struct sockaddr_dn *dn, unsigned char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) switch (le16_to_cpu(dn->sdn_objnamel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) sprintf(buf, "%d", dn->sdn_objnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) for (i = 0; i < le16_to_cpu(dn->sdn_objnamel); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) buf[i] = dn->sdn_objname[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) if (IS_NOT_PRINTABLE(buf[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) buf[i] = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) buf[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) static char *dn_state2asc(unsigned char state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) case DN_O:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) return "OPEN";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) case DN_CR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) return " CR";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) case DN_DR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) return " DR";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) case DN_DRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) return " DRC";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) case DN_CC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) return " CC";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) case DN_CI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) return " CI";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) case DN_NR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) return " NR";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) case DN_NC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) return " NC";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) case DN_CD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) return " CD";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) case DN_RJ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) return " RJ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) case DN_RUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) return " RUN";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) case DN_DI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) return " DI";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) case DN_DIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) return " DIC";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) case DN_DN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) return " DN";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) case DN_CL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) return " CL";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) case DN_CN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) return " CN";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) return "????";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) static inline void dn_socket_format_entry(struct seq_file *seq, struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) struct dn_scp *scp = DN_SK(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) char buf1[DN_ASCBUF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) char buf2[DN_ASCBUF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) char local_object[DN_MAXOBJL+3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) char remote_object[DN_MAXOBJL+3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) dn_printable_object(&scp->addr, local_object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) dn_printable_object(&scp->peer, remote_object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) "%6s/%04X %04d:%04d %04d:%04d %01d %-16s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) "%6s/%04X %04d:%04d %04d:%04d %01d %-16s %4s %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) dn_addr2asc(le16_to_cpu(dn_saddr2dn(&scp->addr)), buf1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) scp->addrloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) scp->numdat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) scp->numoth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) scp->ackxmt_dat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) scp->ackxmt_oth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) scp->flowloc_sw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) local_object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) dn_addr2asc(le16_to_cpu(dn_saddr2dn(&scp->peer)), buf2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) scp->addrrem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) scp->numdat_rcv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) scp->numoth_rcv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) scp->ackrcv_dat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) scp->ackrcv_oth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) scp->flowrem_sw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) remote_object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) dn_state2asc(scp->state),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) ((scp->accept_mode == ACC_IMMED) ? "IMMED" : "DEFER"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) static int dn_socket_seq_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) if (v == SEQ_START_TOKEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) seq_puts(seq, "Local Remote\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) dn_socket_format_entry(seq, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) static const struct seq_operations dn_socket_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) .start = dn_socket_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) .next = dn_socket_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) .stop = dn_socket_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) .show = dn_socket_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) static const struct net_proto_family dn_family_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) .family = AF_DECnet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) .create = dn_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) static const struct proto_ops dn_proto_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) .family = AF_DECnet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) .release = dn_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) .bind = dn_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) .connect = dn_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) .socketpair = sock_no_socketpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) .accept = dn_accept,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) .getname = dn_getname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) .poll = dn_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) .ioctl = dn_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) .listen = dn_listen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) .shutdown = dn_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) .setsockopt = dn_setsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) .getsockopt = dn_getsockopt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) .sendmsg = dn_sendmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) .recvmsg = dn_recvmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) .mmap = sock_no_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) .sendpage = sock_no_sendpage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) MODULE_DESCRIPTION("The Linux DECnet Network Protocol");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) MODULE_AUTHOR("Linux DECnet Project Team");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) MODULE_ALIAS_NETPROTO(PF_DECnet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) static const char banner[] __initconst = KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) "NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) static int __init decnet_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) printk(banner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) rc = proto_register(&dn_proto, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) dn_neigh_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) dn_dev_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) dn_route_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) dn_fib_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) sock_register(&dn_family_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) dev_add_pack(&dn_dix_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) register_netdevice_notifier(&dn_dev_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) proc_create_seq_private("decnet", 0444, init_net.proc_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) &dn_socket_seq_ops, sizeof(struct dn_iter_state),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) dn_register_sysctl();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) module_init(decnet_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) * Prevent DECnet module unloading until its fixed properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) * Requires an audit of the code to check for memory leaks and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) * initialisation problems etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) static void __exit decnet_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) sock_unregister(AF_DECnet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) rtnl_unregister_all(PF_DECnet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) dev_remove_pack(&dn_dix_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) dn_unregister_sysctl();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) unregister_netdevice_notifier(&dn_dev_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) dn_route_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) dn_dev_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) dn_neigh_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) dn_fib_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) remove_proc_entry("decnet", init_net.proc_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) proto_unregister(&dn_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) rcu_barrier(); /* Wait for completion of call_rcu()'s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) module_exit(decnet_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) #endif