162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
562306a36Sopenharmony_ci * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
662306a36Sopenharmony_ci * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
762306a36Sopenharmony_ci * Copyright (C) Hans-Joachim Hetscher DD8NE (dd8ne@bnv-bamberg.de)
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci#include <linux/errno.h>
1062306a36Sopenharmony_ci#include <linux/types.h>
1162306a36Sopenharmony_ci#include <linux/socket.h>
1262306a36Sopenharmony_ci#include <linux/in.h>
1362306a36Sopenharmony_ci#include <linux/kernel.h>
1462306a36Sopenharmony_ci#include <linux/timer.h>
1562306a36Sopenharmony_ci#include <linux/string.h>
1662306a36Sopenharmony_ci#include <linux/sockios.h>
1762306a36Sopenharmony_ci#include <linux/net.h>
1862306a36Sopenharmony_ci#include <linux/slab.h>
1962306a36Sopenharmony_ci#include <net/ax25.h>
2062306a36Sopenharmony_ci#include <linux/inet.h>
2162306a36Sopenharmony_ci#include <linux/netdevice.h>
2262306a36Sopenharmony_ci#include <linux/skbuff.h>
2362306a36Sopenharmony_ci#include <net/sock.h>
2462306a36Sopenharmony_ci#include <net/tcp_states.h>
2562306a36Sopenharmony_ci#include <linux/uaccess.h>
2662306a36Sopenharmony_ci#include <linux/fcntl.h>
2762306a36Sopenharmony_ci#include <linux/mm.h>
2862306a36Sopenharmony_ci#include <linux/interrupt.h>
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci/*
3162306a36Sopenharmony_ci *	Given a fragment, queue it on the fragment queue and if the fragment
3262306a36Sopenharmony_ci *	is complete, send it back to ax25_rx_iframe.
3362306a36Sopenharmony_ci */
3462306a36Sopenharmony_cistatic int ax25_rx_fragment(ax25_cb *ax25, struct sk_buff *skb)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	struct sk_buff *skbn, *skbo;
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	if (ax25->fragno != 0) {
3962306a36Sopenharmony_ci		if (!(*skb->data & AX25_SEG_FIRST)) {
4062306a36Sopenharmony_ci			if ((ax25->fragno - 1) == (*skb->data & AX25_SEG_REM)) {
4162306a36Sopenharmony_ci				/* Enqueue fragment */
4262306a36Sopenharmony_ci				ax25->fragno = *skb->data & AX25_SEG_REM;
4362306a36Sopenharmony_ci				skb_pull(skb, 1);	/* skip fragno */
4462306a36Sopenharmony_ci				ax25->fraglen += skb->len;
4562306a36Sopenharmony_ci				skb_queue_tail(&ax25->frag_queue, skb);
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci				/* Last fragment received ? */
4862306a36Sopenharmony_ci				if (ax25->fragno == 0) {
4962306a36Sopenharmony_ci					skbn = alloc_skb(AX25_MAX_HEADER_LEN +
5062306a36Sopenharmony_ci							 ax25->fraglen,
5162306a36Sopenharmony_ci							 GFP_ATOMIC);
5262306a36Sopenharmony_ci					if (!skbn) {
5362306a36Sopenharmony_ci						skb_queue_purge(&ax25->frag_queue);
5462306a36Sopenharmony_ci						return 1;
5562306a36Sopenharmony_ci					}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci					skb_reserve(skbn, AX25_MAX_HEADER_LEN);
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci					skbn->dev   = ax25->ax25_dev->dev;
6062306a36Sopenharmony_ci					skb_reset_network_header(skbn);
6162306a36Sopenharmony_ci					skb_reset_transport_header(skbn);
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci					/* Copy data from the fragments */
6462306a36Sopenharmony_ci					while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL) {
6562306a36Sopenharmony_ci						skb_copy_from_linear_data(skbo,
6662306a36Sopenharmony_ci							  skb_put(skbn, skbo->len),
6762306a36Sopenharmony_ci									  skbo->len);
6862306a36Sopenharmony_ci						kfree_skb(skbo);
6962306a36Sopenharmony_ci					}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci					ax25->fraglen = 0;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci					if (ax25_rx_iframe(ax25, skbn) == 0)
7462306a36Sopenharmony_ci						kfree_skb(skbn);
7562306a36Sopenharmony_ci				}
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci				return 1;
7862306a36Sopenharmony_ci			}
7962306a36Sopenharmony_ci		}
8062306a36Sopenharmony_ci	} else {
8162306a36Sopenharmony_ci		/* First fragment received */
8262306a36Sopenharmony_ci		if (*skb->data & AX25_SEG_FIRST) {
8362306a36Sopenharmony_ci			skb_queue_purge(&ax25->frag_queue);
8462306a36Sopenharmony_ci			ax25->fragno = *skb->data & AX25_SEG_REM;
8562306a36Sopenharmony_ci			skb_pull(skb, 1);		/* skip fragno */
8662306a36Sopenharmony_ci			ax25->fraglen = skb->len;
8762306a36Sopenharmony_ci			skb_queue_tail(&ax25->frag_queue, skb);
8862306a36Sopenharmony_ci			return 1;
8962306a36Sopenharmony_ci		}
9062306a36Sopenharmony_ci	}
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	return 0;
9362306a36Sopenharmony_ci}
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci/*
9662306a36Sopenharmony_ci *	This is where all valid I frames are sent to, to be dispatched to
9762306a36Sopenharmony_ci *	whichever protocol requires them.
9862306a36Sopenharmony_ci */
9962306a36Sopenharmony_ciint ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb)
10062306a36Sopenharmony_ci{
10162306a36Sopenharmony_ci	int (*func)(struct sk_buff *, ax25_cb *);
10262306a36Sopenharmony_ci	unsigned char pid;
10362306a36Sopenharmony_ci	int queued = 0;
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	if (skb == NULL) return 0;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	ax25_start_idletimer(ax25);
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	pid = *skb->data;
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	if (pid == AX25_P_IP) {
11262306a36Sopenharmony_ci		/* working around a TCP bug to keep additional listeners
11362306a36Sopenharmony_ci		 * happy. TCP re-uses the buffer and destroys the original
11462306a36Sopenharmony_ci		 * content.
11562306a36Sopenharmony_ci		 */
11662306a36Sopenharmony_ci		struct sk_buff *skbn = skb_copy(skb, GFP_ATOMIC);
11762306a36Sopenharmony_ci		if (skbn != NULL) {
11862306a36Sopenharmony_ci			kfree_skb(skb);
11962306a36Sopenharmony_ci			skb = skbn;
12062306a36Sopenharmony_ci		}
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci		skb_pull(skb, 1);	/* Remove PID */
12362306a36Sopenharmony_ci		skb->mac_header = skb->network_header;
12462306a36Sopenharmony_ci		skb_reset_network_header(skb);
12562306a36Sopenharmony_ci		skb->dev      = ax25->ax25_dev->dev;
12662306a36Sopenharmony_ci		skb->pkt_type = PACKET_HOST;
12762306a36Sopenharmony_ci		skb->protocol = htons(ETH_P_IP);
12862306a36Sopenharmony_ci		netif_rx(skb);
12962306a36Sopenharmony_ci		return 1;
13062306a36Sopenharmony_ci	}
13162306a36Sopenharmony_ci	if (pid == AX25_P_SEGMENT) {
13262306a36Sopenharmony_ci		skb_pull(skb, 1);	/* Remove PID */
13362306a36Sopenharmony_ci		return ax25_rx_fragment(ax25, skb);
13462306a36Sopenharmony_ci	}
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	if ((func = ax25_protocol_function(pid)) != NULL) {
13762306a36Sopenharmony_ci		skb_pull(skb, 1);	/* Remove PID */
13862306a36Sopenharmony_ci		return (*func)(skb, ax25);
13962306a36Sopenharmony_ci	}
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	if (ax25->sk != NULL && ax25->ax25_dev->values[AX25_VALUES_CONMODE] == 2) {
14262306a36Sopenharmony_ci		if ((!ax25->pidincl && ax25->sk->sk_protocol == pid) ||
14362306a36Sopenharmony_ci		    ax25->pidincl) {
14462306a36Sopenharmony_ci			if (sock_queue_rcv_skb(ax25->sk, skb) == 0)
14562306a36Sopenharmony_ci				queued = 1;
14662306a36Sopenharmony_ci			else
14762306a36Sopenharmony_ci				ax25->condition |= AX25_COND_OWN_RX_BUSY;
14862306a36Sopenharmony_ci		}
14962306a36Sopenharmony_ci	}
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	return queued;
15262306a36Sopenharmony_ci}
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci/*
15562306a36Sopenharmony_ci *	Higher level upcall for a LAPB frame
15662306a36Sopenharmony_ci */
15762306a36Sopenharmony_cistatic int ax25_process_rx_frame(ax25_cb *ax25, struct sk_buff *skb, int type, int dama)
15862306a36Sopenharmony_ci{
15962306a36Sopenharmony_ci	int queued = 0;
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	if (ax25->state == AX25_STATE_0)
16262306a36Sopenharmony_ci		return 0;
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
16562306a36Sopenharmony_ci	case AX25_PROTO_STD_SIMPLEX:
16662306a36Sopenharmony_ci	case AX25_PROTO_STD_DUPLEX:
16762306a36Sopenharmony_ci		queued = ax25_std_frame_in(ax25, skb, type);
16862306a36Sopenharmony_ci		break;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci#ifdef CONFIG_AX25_DAMA_SLAVE
17162306a36Sopenharmony_ci	case AX25_PROTO_DAMA_SLAVE:
17262306a36Sopenharmony_ci		if (dama || ax25->ax25_dev->dama.slave)
17362306a36Sopenharmony_ci			queued = ax25_ds_frame_in(ax25, skb, type);
17462306a36Sopenharmony_ci		else
17562306a36Sopenharmony_ci			queued = ax25_std_frame_in(ax25, skb, type);
17662306a36Sopenharmony_ci		break;
17762306a36Sopenharmony_ci#endif
17862306a36Sopenharmony_ci	}
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	return queued;
18162306a36Sopenharmony_ci}
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_cistatic int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
18462306a36Sopenharmony_ci		    const ax25_address *dev_addr, struct packet_type *ptype)
18562306a36Sopenharmony_ci{
18662306a36Sopenharmony_ci	ax25_address src, dest, *next_digi = NULL;
18762306a36Sopenharmony_ci	int type = 0, mine = 0, dama;
18862306a36Sopenharmony_ci	struct sock *make, *sk;
18962306a36Sopenharmony_ci	ax25_digi dp, reverse_dp;
19062306a36Sopenharmony_ci	ax25_cb *ax25;
19162306a36Sopenharmony_ci	ax25_dev *ax25_dev;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	/*
19462306a36Sopenharmony_ci	 *	Process the AX.25/LAPB frame.
19562306a36Sopenharmony_ci	 */
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	skb_reset_transport_header(skb);
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
20062306a36Sopenharmony_ci		goto free;
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci	/*
20362306a36Sopenharmony_ci	 *	Parse the address header.
20462306a36Sopenharmony_ci	 */
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	if (ax25_addr_parse(skb->data, skb->len, &src, &dest, &dp, &type, &dama) == NULL)
20762306a36Sopenharmony_ci		goto free;
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	/*
21062306a36Sopenharmony_ci	 *	Ours perhaps ?
21162306a36Sopenharmony_ci	 */
21262306a36Sopenharmony_ci	if (dp.lastrepeat + 1 < dp.ndigi)		/* Not yet digipeated completely */
21362306a36Sopenharmony_ci		next_digi = &dp.calls[dp.lastrepeat + 1];
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	/*
21662306a36Sopenharmony_ci	 *	Pull of the AX.25 headers leaving the CTRL/PID bytes
21762306a36Sopenharmony_ci	 */
21862306a36Sopenharmony_ci	skb_pull(skb, ax25_addr_size(&dp));
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	/* For our port addresses ? */
22162306a36Sopenharmony_ci	if (ax25cmp(&dest, dev_addr) == 0 && dp.lastrepeat + 1 == dp.ndigi)
22262306a36Sopenharmony_ci		mine = 1;
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	/* Also match on any registered callsign from L3/4 */
22562306a36Sopenharmony_ci	if (!mine && ax25_listen_mine(&dest, dev) && dp.lastrepeat + 1 == dp.ndigi)
22662306a36Sopenharmony_ci		mine = 1;
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	/* UI frame - bypass LAPB processing */
22962306a36Sopenharmony_ci	if ((*skb->data & ~0x10) == AX25_UI && dp.lastrepeat + 1 == dp.ndigi) {
23062306a36Sopenharmony_ci		skb_set_transport_header(skb, 2); /* skip control and pid */
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci		ax25_send_to_raw(&dest, skb, skb->data[1]);
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci		if (!mine && ax25cmp(&dest, (ax25_address *)dev->broadcast) != 0)
23562306a36Sopenharmony_ci			goto free;
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci		/* Now we are pointing at the pid byte */
23862306a36Sopenharmony_ci		switch (skb->data[1]) {
23962306a36Sopenharmony_ci		case AX25_P_IP:
24062306a36Sopenharmony_ci			skb_pull(skb,2);		/* drop PID/CTRL */
24162306a36Sopenharmony_ci			skb_reset_transport_header(skb);
24262306a36Sopenharmony_ci			skb_reset_network_header(skb);
24362306a36Sopenharmony_ci			skb->dev      = dev;
24462306a36Sopenharmony_ci			skb->pkt_type = PACKET_HOST;
24562306a36Sopenharmony_ci			skb->protocol = htons(ETH_P_IP);
24662306a36Sopenharmony_ci			netif_rx(skb);
24762306a36Sopenharmony_ci			break;
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci		case AX25_P_ARP:
25062306a36Sopenharmony_ci			skb_pull(skb,2);
25162306a36Sopenharmony_ci			skb_reset_transport_header(skb);
25262306a36Sopenharmony_ci			skb_reset_network_header(skb);
25362306a36Sopenharmony_ci			skb->dev      = dev;
25462306a36Sopenharmony_ci			skb->pkt_type = PACKET_HOST;
25562306a36Sopenharmony_ci			skb->protocol = htons(ETH_P_ARP);
25662306a36Sopenharmony_ci			netif_rx(skb);
25762306a36Sopenharmony_ci			break;
25862306a36Sopenharmony_ci		case AX25_P_TEXT:
25962306a36Sopenharmony_ci			/* Now find a suitable dgram socket */
26062306a36Sopenharmony_ci			sk = ax25_get_socket(&dest, &src, SOCK_DGRAM);
26162306a36Sopenharmony_ci			if (sk != NULL) {
26262306a36Sopenharmony_ci				bh_lock_sock(sk);
26362306a36Sopenharmony_ci				if (atomic_read(&sk->sk_rmem_alloc) >=
26462306a36Sopenharmony_ci				    sk->sk_rcvbuf) {
26562306a36Sopenharmony_ci					kfree_skb(skb);
26662306a36Sopenharmony_ci				} else {
26762306a36Sopenharmony_ci					/*
26862306a36Sopenharmony_ci					 *	Remove the control and PID.
26962306a36Sopenharmony_ci					 */
27062306a36Sopenharmony_ci					skb_pull(skb, 2);
27162306a36Sopenharmony_ci					if (sock_queue_rcv_skb(sk, skb) != 0)
27262306a36Sopenharmony_ci						kfree_skb(skb);
27362306a36Sopenharmony_ci				}
27462306a36Sopenharmony_ci				bh_unlock_sock(sk);
27562306a36Sopenharmony_ci				sock_put(sk);
27662306a36Sopenharmony_ci			} else {
27762306a36Sopenharmony_ci				kfree_skb(skb);
27862306a36Sopenharmony_ci			}
27962306a36Sopenharmony_ci			break;
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci		default:
28262306a36Sopenharmony_ci			kfree_skb(skb);	/* Will scan SOCK_AX25 RAW sockets */
28362306a36Sopenharmony_ci			break;
28462306a36Sopenharmony_ci		}
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci		return 0;
28762306a36Sopenharmony_ci	}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	/*
29062306a36Sopenharmony_ci	 *	Is connected mode supported on this device ?
29162306a36Sopenharmony_ci	 *	If not, should we DM the incoming frame (except DMs) or
29262306a36Sopenharmony_ci	 *	silently ignore them. For now we stay quiet.
29362306a36Sopenharmony_ci	 */
29462306a36Sopenharmony_ci	if (ax25_dev->values[AX25_VALUES_CONMODE] == 0)
29562306a36Sopenharmony_ci		goto free;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	/* LAPB */
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	/* AX.25 state 1-4 */
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	ax25_digi_invert(&dp, &reverse_dp);
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	if ((ax25 = ax25_find_cb(&dest, &src, &reverse_dp, dev)) != NULL) {
30462306a36Sopenharmony_ci		/*
30562306a36Sopenharmony_ci		 *	Process the frame. If it is queued up internally it
30662306a36Sopenharmony_ci		 *	returns one otherwise we free it immediately. This
30762306a36Sopenharmony_ci		 *	routine itself wakes the user context layers so we do
30862306a36Sopenharmony_ci		 *	no further work
30962306a36Sopenharmony_ci		 */
31062306a36Sopenharmony_ci		if (ax25_process_rx_frame(ax25, skb, type, dama) == 0)
31162306a36Sopenharmony_ci			kfree_skb(skb);
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci		ax25_cb_put(ax25);
31462306a36Sopenharmony_ci		return 0;
31562306a36Sopenharmony_ci	}
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	/* AX.25 state 0 (disconnected) */
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci	/* a) received not a SABM(E) */
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	if ((*skb->data & ~AX25_PF) != AX25_SABM &&
32262306a36Sopenharmony_ci	    (*skb->data & ~AX25_PF) != AX25_SABME) {
32362306a36Sopenharmony_ci		/*
32462306a36Sopenharmony_ci		 *	Never reply to a DM. Also ignore any connects for
32562306a36Sopenharmony_ci		 *	addresses that are not our interfaces and not a socket.
32662306a36Sopenharmony_ci		 */
32762306a36Sopenharmony_ci		if ((*skb->data & ~AX25_PF) != AX25_DM && mine)
32862306a36Sopenharmony_ci			ax25_return_dm(dev, &src, &dest, &dp);
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci		goto free;
33162306a36Sopenharmony_ci	}
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	/* b) received SABM(E) */
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	if (dp.lastrepeat + 1 == dp.ndigi)
33662306a36Sopenharmony_ci		sk = ax25_find_listener(&dest, 0, dev, SOCK_SEQPACKET);
33762306a36Sopenharmony_ci	else
33862306a36Sopenharmony_ci		sk = ax25_find_listener(next_digi, 1, dev, SOCK_SEQPACKET);
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	if (sk != NULL) {
34162306a36Sopenharmony_ci		bh_lock_sock(sk);
34262306a36Sopenharmony_ci		if (sk_acceptq_is_full(sk) ||
34362306a36Sopenharmony_ci		    (make = ax25_make_new(sk, ax25_dev)) == NULL) {
34462306a36Sopenharmony_ci			if (mine)
34562306a36Sopenharmony_ci				ax25_return_dm(dev, &src, &dest, &dp);
34662306a36Sopenharmony_ci			kfree_skb(skb);
34762306a36Sopenharmony_ci			bh_unlock_sock(sk);
34862306a36Sopenharmony_ci			sock_put(sk);
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci			return 0;
35162306a36Sopenharmony_ci		}
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci		ax25 = sk_to_ax25(make);
35462306a36Sopenharmony_ci		skb_set_owner_r(skb, make);
35562306a36Sopenharmony_ci		skb_queue_head(&sk->sk_receive_queue, skb);
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci		make->sk_state = TCP_ESTABLISHED;
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci		sk_acceptq_added(sk);
36062306a36Sopenharmony_ci		bh_unlock_sock(sk);
36162306a36Sopenharmony_ci	} else {
36262306a36Sopenharmony_ci		if (!mine)
36362306a36Sopenharmony_ci			goto free;
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci		if ((ax25 = ax25_create_cb()) == NULL) {
36662306a36Sopenharmony_ci			ax25_return_dm(dev, &src, &dest, &dp);
36762306a36Sopenharmony_ci			goto free;
36862306a36Sopenharmony_ci		}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci		ax25_fillin_cb(ax25, ax25_dev);
37162306a36Sopenharmony_ci	}
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	ax25->source_addr = dest;
37462306a36Sopenharmony_ci	ax25->dest_addr   = src;
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci	/*
37762306a36Sopenharmony_ci	 *	Sort out any digipeated paths.
37862306a36Sopenharmony_ci	 */
37962306a36Sopenharmony_ci	if (dp.ndigi && !ax25->digipeat &&
38062306a36Sopenharmony_ci	    (ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
38162306a36Sopenharmony_ci		kfree_skb(skb);
38262306a36Sopenharmony_ci		ax25_destroy_socket(ax25);
38362306a36Sopenharmony_ci		if (sk)
38462306a36Sopenharmony_ci			sock_put(sk);
38562306a36Sopenharmony_ci		return 0;
38662306a36Sopenharmony_ci	}
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	if (dp.ndigi == 0) {
38962306a36Sopenharmony_ci		kfree(ax25->digipeat);
39062306a36Sopenharmony_ci		ax25->digipeat = NULL;
39162306a36Sopenharmony_ci	} else {
39262306a36Sopenharmony_ci		/* Reverse the source SABM's path */
39362306a36Sopenharmony_ci		memcpy(ax25->digipeat, &reverse_dp, sizeof(ax25_digi));
39462306a36Sopenharmony_ci	}
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	if ((*skb->data & ~AX25_PF) == AX25_SABME) {
39762306a36Sopenharmony_ci		ax25->modulus = AX25_EMODULUS;
39862306a36Sopenharmony_ci		ax25->window  = ax25_dev->values[AX25_VALUES_EWINDOW];
39962306a36Sopenharmony_ci	} else {
40062306a36Sopenharmony_ci		ax25->modulus = AX25_MODULUS;
40162306a36Sopenharmony_ci		ax25->window  = ax25_dev->values[AX25_VALUES_WINDOW];
40262306a36Sopenharmony_ci	}
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci	ax25_send_control(ax25, AX25_UA, AX25_POLLON, AX25_RESPONSE);
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci#ifdef CONFIG_AX25_DAMA_SLAVE
40762306a36Sopenharmony_ci	if (dama && ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_DAMA_SLAVE)
40862306a36Sopenharmony_ci		ax25_dama_on(ax25);
40962306a36Sopenharmony_ci#endif
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	ax25->state = AX25_STATE_3;
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci	ax25_cb_add(ax25);
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	ax25_start_heartbeat(ax25);
41662306a36Sopenharmony_ci	ax25_start_t3timer(ax25);
41762306a36Sopenharmony_ci	ax25_start_idletimer(ax25);
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci	if (sk) {
42062306a36Sopenharmony_ci		if (!sock_flag(sk, SOCK_DEAD))
42162306a36Sopenharmony_ci			sk->sk_data_ready(sk);
42262306a36Sopenharmony_ci		sock_put(sk);
42362306a36Sopenharmony_ci	} else {
42462306a36Sopenharmony_cifree:
42562306a36Sopenharmony_ci		kfree_skb(skb);
42662306a36Sopenharmony_ci	}
42762306a36Sopenharmony_ci	return 0;
42862306a36Sopenharmony_ci}
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci/*
43162306a36Sopenharmony_ci *	Receive an AX.25 frame via a SLIP interface.
43262306a36Sopenharmony_ci */
43362306a36Sopenharmony_ciint ax25_kiss_rcv(struct sk_buff *skb, struct net_device *dev,
43462306a36Sopenharmony_ci		  struct packet_type *ptype, struct net_device *orig_dev)
43562306a36Sopenharmony_ci{
43662306a36Sopenharmony_ci	skb_orphan(skb);
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci	if (!net_eq(dev_net(dev), &init_net)) {
43962306a36Sopenharmony_ci		kfree_skb(skb);
44062306a36Sopenharmony_ci		return 0;
44162306a36Sopenharmony_ci	}
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci	if ((*skb->data & 0x0F) != 0) {
44462306a36Sopenharmony_ci		kfree_skb(skb);	/* Not a KISS data frame */
44562306a36Sopenharmony_ci		return 0;
44662306a36Sopenharmony_ci	}
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	skb_pull(skb, AX25_KISS_HEADER_LEN);	/* Remove the KISS byte */
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci	return ax25_rcv(skb, dev, (const ax25_address *)dev->dev_addr, ptype);
45162306a36Sopenharmony_ci}
452