Orange Pi5 kernel

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

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * llc_if.c - Defines LLC interface to upper layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (c) 1997 by Procom Technology, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * 		 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * This program can be redistributed or modified under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * GNU General Public License as published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * This program is distributed without any warranty or implied warranty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * of merchantability or fitness for a particular purpose.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * See the GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <net/llc_if.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <net/llc_sap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <net/llc_s_ev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <net/llc_conn.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <net/llc_c_ev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <net/llc_c_ac.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <net/llc_c_st.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <net/tcp_states.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *	llc_build_and_send_pkt - Connection data sending for upper layers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *	@sk: connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *	@skb: packet to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *	This function is called when upper layer wants to send data using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *	connection oriented communication mode. During sending data, connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *	will be locked and received frames and expired timers will be queued.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *	Returns 0 for success, -ECONNABORTED when the connection already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  *	closed and -EBUSY when sending data is not permitted in this state or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *	LLC has send an I pdu with p bit set to 1 and is waiting for it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *	response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *	This function always consumes a reference to the skb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	struct llc_conn_state_ev *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	int rc = -ECONNABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	struct llc_sock *llc = llc_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	if (unlikely(llc->state == LLC_CONN_STATE_ADM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	rc = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	if (unlikely(llc_data_accept_state(llc->state) || /* data_conn_refuse */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		     llc->p_flag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		llc->failed_data_req = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	ev = llc_conn_ev(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	ev->type      = LLC_CONN_EV_TYPE_PRIM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	ev->prim      = LLC_DATA_PRIM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	ev->prim_type = LLC_PRIM_TYPE_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	skb->dev      = llc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	return llc_conn_state_process(sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  *	llc_establish_connection - Called by upper layer to establish a conn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  *	@sk: connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  *	@lmac: local mac address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  *	@dmac: destination mac address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  *	@dsap: destination sap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  *	Upper layer calls this to establish an LLC connection with a remote
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  *	machine. This function packages a proper event and sends it connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  *	component state machine. Success or failure of connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  *	establishment will inform to upper layer via calling it's confirm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  *	function and passing proper information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	int rc = -EISCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	struct llc_addr laddr, daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	struct llc_sock *llc = llc_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	struct sock *existing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	laddr.lsap = llc->sap->laddr.lsap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	daddr.lsap = dsap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	memcpy(daddr.mac, dmac, sizeof(daddr.mac));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	memcpy(laddr.mac, lmac, sizeof(laddr.mac));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	existing = llc_lookup_established(llc->sap, &daddr, &laddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (existing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		if (existing->sk_state == TCP_ESTABLISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			sk = existing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			sock_put(existing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	skb = alloc_skb(0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		struct llc_conn_state_ev *ev = llc_conn_ev(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		ev->type      = LLC_CONN_EV_TYPE_PRIM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		ev->prim      = LLC_CONN_PRIM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		ev->prim_type = LLC_PRIM_TYPE_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		skb_set_owner_w(skb, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		rc = llc_conn_state_process(sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  *	llc_send_disc - Called by upper layer to close a connection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  *	@sk: connection to be closed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  *	Upper layer calls this when it wants to close an established LLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  *	connection with a remote machine. This function packages a proper event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  *	and sends it to connection component state machine. Returns 0 for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  *	success, 1 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int llc_send_disc(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	u16 rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	struct llc_conn_state_ev *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	if (sk->sk_type != SOCK_STREAM || sk->sk_state != TCP_ESTABLISHED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	    llc_sk(sk)->state == LLC_CONN_STATE_ADM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	    llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	 * Postpone unassigning the connection from its SAP and returning the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	 * connection until all ACTIONs have been completely executed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	skb = alloc_skb(0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	skb_set_owner_w(skb, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	sk->sk_state  = TCP_CLOSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	ev	      = llc_conn_ev(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	ev->type      = LLC_CONN_EV_TYPE_PRIM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	ev->prim      = LLC_DISC_PRIM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	ev->prim_type = LLC_PRIM_TYPE_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	rc = llc_conn_state_process(sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }