xref: /kernel/linux/linux-5.10/net/ax25/ax25_in.c (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
58c2ecf20Sopenharmony_ci * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
68c2ecf20Sopenharmony_ci * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
78c2ecf20Sopenharmony_ci * Copyright (C) Hans-Joachim Hetscher DD8NE (dd8ne@bnv-bamberg.de)
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci#include <linux/errno.h>
108c2ecf20Sopenharmony_ci#include <linux/types.h>
118c2ecf20Sopenharmony_ci#include <linux/socket.h>
128c2ecf20Sopenharmony_ci#include <linux/in.h>
138c2ecf20Sopenharmony_ci#include <linux/kernel.h>
148c2ecf20Sopenharmony_ci#include <linux/timer.h>
158c2ecf20Sopenharmony_ci#include <linux/string.h>
168c2ecf20Sopenharmony_ci#include <linux/sockios.h>
178c2ecf20Sopenharmony_ci#include <linux/net.h>
188c2ecf20Sopenharmony_ci#include <linux/slab.h>
198c2ecf20Sopenharmony_ci#include <net/ax25.h>
208c2ecf20Sopenharmony_ci#include <linux/inet.h>
218c2ecf20Sopenharmony_ci#include <linux/netdevice.h>
228c2ecf20Sopenharmony_ci#include <linux/skbuff.h>
238c2ecf20Sopenharmony_ci#include <net/sock.h>
248c2ecf20Sopenharmony_ci#include <net/tcp_states.h>
258c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
268c2ecf20Sopenharmony_ci#include <linux/fcntl.h>
278c2ecf20Sopenharmony_ci#include <linux/mm.h>
288c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/*
318c2ecf20Sopenharmony_ci *	Given a fragment, queue it on the fragment queue and if the fragment
328c2ecf20Sopenharmony_ci *	is complete, send it back to ax25_rx_iframe.
338c2ecf20Sopenharmony_ci */
348c2ecf20Sopenharmony_cistatic int ax25_rx_fragment(ax25_cb *ax25, struct sk_buff *skb)
358c2ecf20Sopenharmony_ci{
368c2ecf20Sopenharmony_ci	struct sk_buff *skbn, *skbo;
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci	if (ax25->fragno != 0) {
398c2ecf20Sopenharmony_ci		if (!(*skb->data & AX25_SEG_FIRST)) {
408c2ecf20Sopenharmony_ci			if ((ax25->fragno - 1) == (*skb->data & AX25_SEG_REM)) {
418c2ecf20Sopenharmony_ci				/* Enqueue fragment */
428c2ecf20Sopenharmony_ci				ax25->fragno = *skb->data & AX25_SEG_REM;
438c2ecf20Sopenharmony_ci				skb_pull(skb, 1);	/* skip fragno */
448c2ecf20Sopenharmony_ci				ax25->fraglen += skb->len;
458c2ecf20Sopenharmony_ci				skb_queue_tail(&ax25->frag_queue, skb);
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci				/* Last fragment received ? */
488c2ecf20Sopenharmony_ci				if (ax25->fragno == 0) {
498c2ecf20Sopenharmony_ci					skbn = alloc_skb(AX25_MAX_HEADER_LEN +
508c2ecf20Sopenharmony_ci							 ax25->fraglen,
518c2ecf20Sopenharmony_ci							 GFP_ATOMIC);
528c2ecf20Sopenharmony_ci					if (!skbn) {
538c2ecf20Sopenharmony_ci						skb_queue_purge(&ax25->frag_queue);
548c2ecf20Sopenharmony_ci						return 1;
558c2ecf20Sopenharmony_ci					}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci					skb_reserve(skbn, AX25_MAX_HEADER_LEN);
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci					skbn->dev   = ax25->ax25_dev->dev;
608c2ecf20Sopenharmony_ci					skb_reset_network_header(skbn);
618c2ecf20Sopenharmony_ci					skb_reset_transport_header(skbn);
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci					/* Copy data from the fragments */
648c2ecf20Sopenharmony_ci					while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL) {
658c2ecf20Sopenharmony_ci						skb_copy_from_linear_data(skbo,
668c2ecf20Sopenharmony_ci							  skb_put(skbn, skbo->len),
678c2ecf20Sopenharmony_ci									  skbo->len);
688c2ecf20Sopenharmony_ci						kfree_skb(skbo);
698c2ecf20Sopenharmony_ci					}
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci					ax25->fraglen = 0;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci					if (ax25_rx_iframe(ax25, skbn) == 0)
748c2ecf20Sopenharmony_ci						kfree_skb(skbn);
758c2ecf20Sopenharmony_ci				}
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci				return 1;
788c2ecf20Sopenharmony_ci			}
798c2ecf20Sopenharmony_ci		}
808c2ecf20Sopenharmony_ci	} else {
818c2ecf20Sopenharmony_ci		/* First fragment received */
828c2ecf20Sopenharmony_ci		if (*skb->data & AX25_SEG_FIRST) {
838c2ecf20Sopenharmony_ci			skb_queue_purge(&ax25->frag_queue);
848c2ecf20Sopenharmony_ci			ax25->fragno = *skb->data & AX25_SEG_REM;
858c2ecf20Sopenharmony_ci			skb_pull(skb, 1);		/* skip fragno */
868c2ecf20Sopenharmony_ci			ax25->fraglen = skb->len;
878c2ecf20Sopenharmony_ci			skb_queue_tail(&ax25->frag_queue, skb);
888c2ecf20Sopenharmony_ci			return 1;
898c2ecf20Sopenharmony_ci		}
908c2ecf20Sopenharmony_ci	}
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	return 0;
938c2ecf20Sopenharmony_ci}
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci/*
968c2ecf20Sopenharmony_ci *	This is where all valid I frames are sent to, to be dispatched to
978c2ecf20Sopenharmony_ci *	whichever protocol requires them.
988c2ecf20Sopenharmony_ci */
998c2ecf20Sopenharmony_ciint ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb)
1008c2ecf20Sopenharmony_ci{
1018c2ecf20Sopenharmony_ci	int (*func)(struct sk_buff *, ax25_cb *);
1028c2ecf20Sopenharmony_ci	unsigned char pid;
1038c2ecf20Sopenharmony_ci	int queued = 0;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	if (skb == NULL) return 0;
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	ax25_start_idletimer(ax25);
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	pid = *skb->data;
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	if (pid == AX25_P_IP) {
1128c2ecf20Sopenharmony_ci		/* working around a TCP bug to keep additional listeners
1138c2ecf20Sopenharmony_ci		 * happy. TCP re-uses the buffer and destroys the original
1148c2ecf20Sopenharmony_ci		 * content.
1158c2ecf20Sopenharmony_ci		 */
1168c2ecf20Sopenharmony_ci		struct sk_buff *skbn = skb_copy(skb, GFP_ATOMIC);
1178c2ecf20Sopenharmony_ci		if (skbn != NULL) {
1188c2ecf20Sopenharmony_ci			kfree_skb(skb);
1198c2ecf20Sopenharmony_ci			skb = skbn;
1208c2ecf20Sopenharmony_ci		}
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci		skb_pull(skb, 1);	/* Remove PID */
1238c2ecf20Sopenharmony_ci		skb->mac_header = skb->network_header;
1248c2ecf20Sopenharmony_ci		skb_reset_network_header(skb);
1258c2ecf20Sopenharmony_ci		skb->dev      = ax25->ax25_dev->dev;
1268c2ecf20Sopenharmony_ci		skb->pkt_type = PACKET_HOST;
1278c2ecf20Sopenharmony_ci		skb->protocol = htons(ETH_P_IP);
1288c2ecf20Sopenharmony_ci		netif_rx(skb);
1298c2ecf20Sopenharmony_ci		return 1;
1308c2ecf20Sopenharmony_ci	}
1318c2ecf20Sopenharmony_ci	if (pid == AX25_P_SEGMENT) {
1328c2ecf20Sopenharmony_ci		skb_pull(skb, 1);	/* Remove PID */
1338c2ecf20Sopenharmony_ci		return ax25_rx_fragment(ax25, skb);
1348c2ecf20Sopenharmony_ci	}
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci	if ((func = ax25_protocol_function(pid)) != NULL) {
1378c2ecf20Sopenharmony_ci		skb_pull(skb, 1);	/* Remove PID */
1388c2ecf20Sopenharmony_ci		return (*func)(skb, ax25);
1398c2ecf20Sopenharmony_ci	}
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci	if (ax25->sk != NULL && ax25->ax25_dev->values[AX25_VALUES_CONMODE] == 2) {
1428c2ecf20Sopenharmony_ci		if ((!ax25->pidincl && ax25->sk->sk_protocol == pid) ||
1438c2ecf20Sopenharmony_ci		    ax25->pidincl) {
1448c2ecf20Sopenharmony_ci			if (sock_queue_rcv_skb(ax25->sk, skb) == 0)
1458c2ecf20Sopenharmony_ci				queued = 1;
1468c2ecf20Sopenharmony_ci			else
1478c2ecf20Sopenharmony_ci				ax25->condition |= AX25_COND_OWN_RX_BUSY;
1488c2ecf20Sopenharmony_ci		}
1498c2ecf20Sopenharmony_ci	}
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	return queued;
1528c2ecf20Sopenharmony_ci}
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci/*
1558c2ecf20Sopenharmony_ci *	Higher level upcall for a LAPB frame
1568c2ecf20Sopenharmony_ci */
1578c2ecf20Sopenharmony_cistatic int ax25_process_rx_frame(ax25_cb *ax25, struct sk_buff *skb, int type, int dama)
1588c2ecf20Sopenharmony_ci{
1598c2ecf20Sopenharmony_ci	int queued = 0;
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	if (ax25->state == AX25_STATE_0)
1628c2ecf20Sopenharmony_ci		return 0;
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
1658c2ecf20Sopenharmony_ci	case AX25_PROTO_STD_SIMPLEX:
1668c2ecf20Sopenharmony_ci	case AX25_PROTO_STD_DUPLEX:
1678c2ecf20Sopenharmony_ci		queued = ax25_std_frame_in(ax25, skb, type);
1688c2ecf20Sopenharmony_ci		break;
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci#ifdef CONFIG_AX25_DAMA_SLAVE
1718c2ecf20Sopenharmony_ci	case AX25_PROTO_DAMA_SLAVE:
1728c2ecf20Sopenharmony_ci		if (dama || ax25->ax25_dev->dama.slave)
1738c2ecf20Sopenharmony_ci			queued = ax25_ds_frame_in(ax25, skb, type);
1748c2ecf20Sopenharmony_ci		else
1758c2ecf20Sopenharmony_ci			queued = ax25_std_frame_in(ax25, skb, type);
1768c2ecf20Sopenharmony_ci		break;
1778c2ecf20Sopenharmony_ci#endif
1788c2ecf20Sopenharmony_ci	}
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	return queued;
1818c2ecf20Sopenharmony_ci}
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_cistatic int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
1848c2ecf20Sopenharmony_ci	ax25_address *dev_addr, struct packet_type *ptype)
1858c2ecf20Sopenharmony_ci{
1868c2ecf20Sopenharmony_ci	ax25_address src, dest, *next_digi = NULL;
1878c2ecf20Sopenharmony_ci	int type = 0, mine = 0, dama;
1888c2ecf20Sopenharmony_ci	struct sock *make, *sk;
1898c2ecf20Sopenharmony_ci	ax25_digi dp, reverse_dp;
1908c2ecf20Sopenharmony_ci	ax25_cb *ax25;
1918c2ecf20Sopenharmony_ci	ax25_dev *ax25_dev;
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci	/*
1948c2ecf20Sopenharmony_ci	 *	Process the AX.25/LAPB frame.
1958c2ecf20Sopenharmony_ci	 */
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci	skb_reset_transport_header(skb);
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
2008c2ecf20Sopenharmony_ci		goto free;
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	/*
2038c2ecf20Sopenharmony_ci	 *	Parse the address header.
2048c2ecf20Sopenharmony_ci	 */
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci	if (ax25_addr_parse(skb->data, skb->len, &src, &dest, &dp, &type, &dama) == NULL)
2078c2ecf20Sopenharmony_ci		goto free;
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci	/*
2108c2ecf20Sopenharmony_ci	 *	Ours perhaps ?
2118c2ecf20Sopenharmony_ci	 */
2128c2ecf20Sopenharmony_ci	if (dp.lastrepeat + 1 < dp.ndigi)		/* Not yet digipeated completely */
2138c2ecf20Sopenharmony_ci		next_digi = &dp.calls[dp.lastrepeat + 1];
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	/*
2168c2ecf20Sopenharmony_ci	 *	Pull of the AX.25 headers leaving the CTRL/PID bytes
2178c2ecf20Sopenharmony_ci	 */
2188c2ecf20Sopenharmony_ci	skb_pull(skb, ax25_addr_size(&dp));
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci	/* For our port addresses ? */
2218c2ecf20Sopenharmony_ci	if (ax25cmp(&dest, dev_addr) == 0 && dp.lastrepeat + 1 == dp.ndigi)
2228c2ecf20Sopenharmony_ci		mine = 1;
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci	/* Also match on any registered callsign from L3/4 */
2258c2ecf20Sopenharmony_ci	if (!mine && ax25_listen_mine(&dest, dev) && dp.lastrepeat + 1 == dp.ndigi)
2268c2ecf20Sopenharmony_ci		mine = 1;
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci	/* UI frame - bypass LAPB processing */
2298c2ecf20Sopenharmony_ci	if ((*skb->data & ~0x10) == AX25_UI && dp.lastrepeat + 1 == dp.ndigi) {
2308c2ecf20Sopenharmony_ci		skb_set_transport_header(skb, 2); /* skip control and pid */
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci		ax25_send_to_raw(&dest, skb, skb->data[1]);
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci		if (!mine && ax25cmp(&dest, (ax25_address *)dev->broadcast) != 0)
2358c2ecf20Sopenharmony_ci			goto free;
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci		/* Now we are pointing at the pid byte */
2388c2ecf20Sopenharmony_ci		switch (skb->data[1]) {
2398c2ecf20Sopenharmony_ci		case AX25_P_IP:
2408c2ecf20Sopenharmony_ci			skb_pull(skb,2);		/* drop PID/CTRL */
2418c2ecf20Sopenharmony_ci			skb_reset_transport_header(skb);
2428c2ecf20Sopenharmony_ci			skb_reset_network_header(skb);
2438c2ecf20Sopenharmony_ci			skb->dev      = dev;
2448c2ecf20Sopenharmony_ci			skb->pkt_type = PACKET_HOST;
2458c2ecf20Sopenharmony_ci			skb->protocol = htons(ETH_P_IP);
2468c2ecf20Sopenharmony_ci			netif_rx(skb);
2478c2ecf20Sopenharmony_ci			break;
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci		case AX25_P_ARP:
2508c2ecf20Sopenharmony_ci			skb_pull(skb,2);
2518c2ecf20Sopenharmony_ci			skb_reset_transport_header(skb);
2528c2ecf20Sopenharmony_ci			skb_reset_network_header(skb);
2538c2ecf20Sopenharmony_ci			skb->dev      = dev;
2548c2ecf20Sopenharmony_ci			skb->pkt_type = PACKET_HOST;
2558c2ecf20Sopenharmony_ci			skb->protocol = htons(ETH_P_ARP);
2568c2ecf20Sopenharmony_ci			netif_rx(skb);
2578c2ecf20Sopenharmony_ci			break;
2588c2ecf20Sopenharmony_ci		case AX25_P_TEXT:
2598c2ecf20Sopenharmony_ci			/* Now find a suitable dgram socket */
2608c2ecf20Sopenharmony_ci			sk = ax25_get_socket(&dest, &src, SOCK_DGRAM);
2618c2ecf20Sopenharmony_ci			if (sk != NULL) {
2628c2ecf20Sopenharmony_ci				bh_lock_sock(sk);
2638c2ecf20Sopenharmony_ci				if (atomic_read(&sk->sk_rmem_alloc) >=
2648c2ecf20Sopenharmony_ci				    sk->sk_rcvbuf) {
2658c2ecf20Sopenharmony_ci					kfree_skb(skb);
2668c2ecf20Sopenharmony_ci				} else {
2678c2ecf20Sopenharmony_ci					/*
2688c2ecf20Sopenharmony_ci					 *	Remove the control and PID.
2698c2ecf20Sopenharmony_ci					 */
2708c2ecf20Sopenharmony_ci					skb_pull(skb, 2);
2718c2ecf20Sopenharmony_ci					if (sock_queue_rcv_skb(sk, skb) != 0)
2728c2ecf20Sopenharmony_ci						kfree_skb(skb);
2738c2ecf20Sopenharmony_ci				}
2748c2ecf20Sopenharmony_ci				bh_unlock_sock(sk);
2758c2ecf20Sopenharmony_ci				sock_put(sk);
2768c2ecf20Sopenharmony_ci			} else {
2778c2ecf20Sopenharmony_ci				kfree_skb(skb);
2788c2ecf20Sopenharmony_ci			}
2798c2ecf20Sopenharmony_ci			break;
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci		default:
2828c2ecf20Sopenharmony_ci			kfree_skb(skb);	/* Will scan SOCK_AX25 RAW sockets */
2838c2ecf20Sopenharmony_ci			break;
2848c2ecf20Sopenharmony_ci		}
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci		return 0;
2878c2ecf20Sopenharmony_ci	}
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci	/*
2908c2ecf20Sopenharmony_ci	 *	Is connected mode supported on this device ?
2918c2ecf20Sopenharmony_ci	 *	If not, should we DM the incoming frame (except DMs) or
2928c2ecf20Sopenharmony_ci	 *	silently ignore them. For now we stay quiet.
2938c2ecf20Sopenharmony_ci	 */
2948c2ecf20Sopenharmony_ci	if (ax25_dev->values[AX25_VALUES_CONMODE] == 0)
2958c2ecf20Sopenharmony_ci		goto free;
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ci	/* LAPB */
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci	/* AX.25 state 1-4 */
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci	ax25_digi_invert(&dp, &reverse_dp);
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	if ((ax25 = ax25_find_cb(&dest, &src, &reverse_dp, dev)) != NULL) {
3048c2ecf20Sopenharmony_ci		/*
3058c2ecf20Sopenharmony_ci		 *	Process the frame. If it is queued up internally it
3068c2ecf20Sopenharmony_ci		 *	returns one otherwise we free it immediately. This
3078c2ecf20Sopenharmony_ci		 *	routine itself wakes the user context layers so we do
3088c2ecf20Sopenharmony_ci		 *	no further work
3098c2ecf20Sopenharmony_ci		 */
3108c2ecf20Sopenharmony_ci		if (ax25_process_rx_frame(ax25, skb, type, dama) == 0)
3118c2ecf20Sopenharmony_ci			kfree_skb(skb);
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci		ax25_cb_put(ax25);
3148c2ecf20Sopenharmony_ci		return 0;
3158c2ecf20Sopenharmony_ci	}
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci	/* AX.25 state 0 (disconnected) */
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci	/* a) received not a SABM(E) */
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci	if ((*skb->data & ~AX25_PF) != AX25_SABM &&
3228c2ecf20Sopenharmony_ci	    (*skb->data & ~AX25_PF) != AX25_SABME) {
3238c2ecf20Sopenharmony_ci		/*
3248c2ecf20Sopenharmony_ci		 *	Never reply to a DM. Also ignore any connects for
3258c2ecf20Sopenharmony_ci		 *	addresses that are not our interfaces and not a socket.
3268c2ecf20Sopenharmony_ci		 */
3278c2ecf20Sopenharmony_ci		if ((*skb->data & ~AX25_PF) != AX25_DM && mine)
3288c2ecf20Sopenharmony_ci			ax25_return_dm(dev, &src, &dest, &dp);
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci		goto free;
3318c2ecf20Sopenharmony_ci	}
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci	/* b) received SABM(E) */
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci	if (dp.lastrepeat + 1 == dp.ndigi)
3368c2ecf20Sopenharmony_ci		sk = ax25_find_listener(&dest, 0, dev, SOCK_SEQPACKET);
3378c2ecf20Sopenharmony_ci	else
3388c2ecf20Sopenharmony_ci		sk = ax25_find_listener(next_digi, 1, dev, SOCK_SEQPACKET);
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci	if (sk != NULL) {
3418c2ecf20Sopenharmony_ci		bh_lock_sock(sk);
3428c2ecf20Sopenharmony_ci		if (sk_acceptq_is_full(sk) ||
3438c2ecf20Sopenharmony_ci		    (make = ax25_make_new(sk, ax25_dev)) == NULL) {
3448c2ecf20Sopenharmony_ci			if (mine)
3458c2ecf20Sopenharmony_ci				ax25_return_dm(dev, &src, &dest, &dp);
3468c2ecf20Sopenharmony_ci			kfree_skb(skb);
3478c2ecf20Sopenharmony_ci			bh_unlock_sock(sk);
3488c2ecf20Sopenharmony_ci			sock_put(sk);
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci			return 0;
3518c2ecf20Sopenharmony_ci		}
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci		ax25 = sk_to_ax25(make);
3548c2ecf20Sopenharmony_ci		skb_set_owner_r(skb, make);
3558c2ecf20Sopenharmony_ci		skb_queue_head(&sk->sk_receive_queue, skb);
3568c2ecf20Sopenharmony_ci
3578c2ecf20Sopenharmony_ci		make->sk_state = TCP_ESTABLISHED;
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci		sk_acceptq_added(sk);
3608c2ecf20Sopenharmony_ci		bh_unlock_sock(sk);
3618c2ecf20Sopenharmony_ci	} else {
3628c2ecf20Sopenharmony_ci		if (!mine)
3638c2ecf20Sopenharmony_ci			goto free;
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci		if ((ax25 = ax25_create_cb()) == NULL) {
3668c2ecf20Sopenharmony_ci			ax25_return_dm(dev, &src, &dest, &dp);
3678c2ecf20Sopenharmony_ci			goto free;
3688c2ecf20Sopenharmony_ci		}
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci		ax25_fillin_cb(ax25, ax25_dev);
3718c2ecf20Sopenharmony_ci	}
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci	ax25->source_addr = dest;
3748c2ecf20Sopenharmony_ci	ax25->dest_addr   = src;
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci	/*
3778c2ecf20Sopenharmony_ci	 *	Sort out any digipeated paths.
3788c2ecf20Sopenharmony_ci	 */
3798c2ecf20Sopenharmony_ci	if (dp.ndigi && !ax25->digipeat &&
3808c2ecf20Sopenharmony_ci	    (ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
3818c2ecf20Sopenharmony_ci		kfree_skb(skb);
3828c2ecf20Sopenharmony_ci		ax25_destroy_socket(ax25);
3838c2ecf20Sopenharmony_ci		if (sk)
3848c2ecf20Sopenharmony_ci			sock_put(sk);
3858c2ecf20Sopenharmony_ci		return 0;
3868c2ecf20Sopenharmony_ci	}
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci	if (dp.ndigi == 0) {
3898c2ecf20Sopenharmony_ci		kfree(ax25->digipeat);
3908c2ecf20Sopenharmony_ci		ax25->digipeat = NULL;
3918c2ecf20Sopenharmony_ci	} else {
3928c2ecf20Sopenharmony_ci		/* Reverse the source SABM's path */
3938c2ecf20Sopenharmony_ci		memcpy(ax25->digipeat, &reverse_dp, sizeof(ax25_digi));
3948c2ecf20Sopenharmony_ci	}
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_ci	if ((*skb->data & ~AX25_PF) == AX25_SABME) {
3978c2ecf20Sopenharmony_ci		ax25->modulus = AX25_EMODULUS;
3988c2ecf20Sopenharmony_ci		ax25->window  = ax25_dev->values[AX25_VALUES_EWINDOW];
3998c2ecf20Sopenharmony_ci	} else {
4008c2ecf20Sopenharmony_ci		ax25->modulus = AX25_MODULUS;
4018c2ecf20Sopenharmony_ci		ax25->window  = ax25_dev->values[AX25_VALUES_WINDOW];
4028c2ecf20Sopenharmony_ci	}
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	ax25_send_control(ax25, AX25_UA, AX25_POLLON, AX25_RESPONSE);
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci#ifdef CONFIG_AX25_DAMA_SLAVE
4078c2ecf20Sopenharmony_ci	if (dama && ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_DAMA_SLAVE)
4088c2ecf20Sopenharmony_ci		ax25_dama_on(ax25);
4098c2ecf20Sopenharmony_ci#endif
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci	ax25->state = AX25_STATE_3;
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_ci	ax25_cb_add(ax25);
4148c2ecf20Sopenharmony_ci
4158c2ecf20Sopenharmony_ci	ax25_start_heartbeat(ax25);
4168c2ecf20Sopenharmony_ci	ax25_start_t3timer(ax25);
4178c2ecf20Sopenharmony_ci	ax25_start_idletimer(ax25);
4188c2ecf20Sopenharmony_ci
4198c2ecf20Sopenharmony_ci	if (sk) {
4208c2ecf20Sopenharmony_ci		if (!sock_flag(sk, SOCK_DEAD))
4218c2ecf20Sopenharmony_ci			sk->sk_data_ready(sk);
4228c2ecf20Sopenharmony_ci		sock_put(sk);
4238c2ecf20Sopenharmony_ci	} else {
4248c2ecf20Sopenharmony_cifree:
4258c2ecf20Sopenharmony_ci		kfree_skb(skb);
4268c2ecf20Sopenharmony_ci	}
4278c2ecf20Sopenharmony_ci	return 0;
4288c2ecf20Sopenharmony_ci}
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_ci/*
4318c2ecf20Sopenharmony_ci *	Receive an AX.25 frame via a SLIP interface.
4328c2ecf20Sopenharmony_ci */
4338c2ecf20Sopenharmony_ciint ax25_kiss_rcv(struct sk_buff *skb, struct net_device *dev,
4348c2ecf20Sopenharmony_ci		  struct packet_type *ptype, struct net_device *orig_dev)
4358c2ecf20Sopenharmony_ci{
4368c2ecf20Sopenharmony_ci	skb_orphan(skb);
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_ci	if (!net_eq(dev_net(dev), &init_net)) {
4398c2ecf20Sopenharmony_ci		kfree_skb(skb);
4408c2ecf20Sopenharmony_ci		return 0;
4418c2ecf20Sopenharmony_ci	}
4428c2ecf20Sopenharmony_ci
4438c2ecf20Sopenharmony_ci	if ((*skb->data & 0x0F) != 0) {
4448c2ecf20Sopenharmony_ci		kfree_skb(skb);	/* Not a KISS data frame */
4458c2ecf20Sopenharmony_ci		return 0;
4468c2ecf20Sopenharmony_ci	}
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci	skb_pull(skb, AX25_KISS_HEADER_LEN);	/* Remove the KISS byte */
4498c2ecf20Sopenharmony_ci
4508c2ecf20Sopenharmony_ci	return ax25_rcv(skb, dev, (ax25_address *)dev->dev_addr, ptype);
4518c2ecf20Sopenharmony_ci}
452