xref: /linux/net/llc/llc_s_ac.c (revision 90e63d5354951d37fa2b3b91e6f17b95d2bf9bee)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * llc_s_ac.c - actions performed during sap state transition.
4  *
5  * Description :
6  *   Functions in this module are implementation of sap component actions.
7  *   Details of actions can be found in IEEE-802.2 standard document.
8  *   All functions have one sap and one event as input argument. All of
9  *   them return 0 On success and 1 otherwise.
10  *
11  * Copyright (c) 1997 by Procom Technology, Inc.
12  *		 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
13  */
14 
15 #include <linux/netdevice.h>
16 #include <net/llc.h>
17 #include <net/llc_pdu.h>
18 #include <net/llc_s_ac.h>
19 #include <net/llc_s_ev.h>
20 #include <net/llc_sap.h>
21 #include <net/sock.h>
22 
23 /**
24  *	llc_sap_action_unitdata_ind - forward UI PDU to network layer
25  *	@sap: SAP
26  *	@skb: the event to forward
27  *
28  *	Received a UI PDU from MAC layer; forward to network layer as a
29  *	UNITDATA INDICATION; verify our event is the kind we expect
30  */
31 int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb)
32 {
33 	llc_sap_rtn_pdu(sap, skb);
34 	return 0;
35 }
36 
37 static int llc_prepare_and_xmit(struct sk_buff *skb)
38 {
39 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
40 	struct sk_buff *nskb;
41 	int rc;
42 
43 	rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
44 	if (rc)
45 		return rc;
46 
47 	nskb = skb_clone(skb, GFP_ATOMIC);
48 	if (!nskb)
49 		return -ENOMEM;
50 
51 	if (skb->sk)
52 		skb_set_owner_w(nskb, skb->sk);
53 
54 	return dev_queue_xmit(nskb);
55 }
56 
57 /**
58  *	llc_sap_action_send_ui - sends UI PDU resp to UNITDATA REQ to MAC layer
59  *	@sap: SAP
60  *	@skb: the event to send
61  *
62  *	Sends a UI PDU to the MAC layer in response to a UNITDATA REQUEST
63  *	primitive from the network layer. Verifies event is a primitive type of
64  *	event. Verify the primitive is a UNITDATA REQUEST.
65  */
66 int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)
67 {
68 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
69 
70 	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
71 			    ev->daddr.lsap, LLC_PDU_CMD);
72 	llc_pdu_init_as_ui_cmd(skb);
73 
74 	return llc_prepare_and_xmit(skb);
75 }
76 
77 /**
78  *	llc_sap_action_send_xid_c - send XID PDU as response to XID REQ
79  *	@sap: SAP
80  *	@skb: the event to send
81  *
82  *	Send a XID command PDU to MAC layer in response to a XID REQUEST
83  *	primitive from the network layer. Verify event is a primitive type
84  *	event. Verify the primitive is a XID REQUEST.
85  */
86 int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb)
87 {
88 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
89 
90 	llc_pdu_header_init(skb, LLC_PDU_TYPE_U_XID, ev->saddr.lsap,
91 			    ev->daddr.lsap, LLC_PDU_CMD);
92 	llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
93 
94 	return llc_prepare_and_xmit(skb);
95 }
96 
97 /**
98  *	llc_sap_action_send_xid_r - send XID PDU resp to MAC for received XID
99  *	@sap: SAP
100  *	@skb: the event to send
101  *
102  *	Send XID response PDU to MAC in response to an earlier received XID
103  *	command PDU. Verify event is a PDU type event
104  */
105 int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
106 {
107 	u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
108 	int rc = 1;
109 	struct sk_buff *nskb;
110 
111 	llc_pdu_decode_sa(skb, mac_da);
112 	llc_pdu_decode_da(skb, mac_sa);
113 	llc_pdu_decode_ssap(skb, &dsap);
114 	nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
115 			       sizeof(struct llc_xid_info));
116 	if (!nskb)
117 		goto out;
118 	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
119 			    LLC_PDU_RSP);
120 	llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0);
121 	rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
122 	if (likely(!rc))
123 		rc = dev_queue_xmit(nskb);
124 out:
125 	return rc;
126 }
127 
128 /**
129  *	llc_sap_action_send_test_c - send TEST PDU to MAC in resp to TEST REQ
130  *	@sap: SAP
131  *	@skb: the event to send
132  *
133  *	Send a TEST command PDU to the MAC layer in response to a TEST REQUEST
134  *	primitive from the network layer. Verify event is a primitive type
135  *	event; verify the primitive is a TEST REQUEST.
136  */
137 int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb)
138 {
139 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
140 
141 	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
142 			    ev->daddr.lsap, LLC_PDU_CMD);
143 	llc_pdu_init_as_test_cmd(skb);
144 
145 	return llc_prepare_and_xmit(skb);
146 }
147 
148 int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
149 {
150 	u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
151 	struct sk_buff *nskb;
152 	int rc = 1;
153 	u32 data_size;
154 
155 	if (skb->mac_len < ETH_HLEN)
156 		return 1;
157 
158 	llc_pdu_decode_sa(skb, mac_da);
159 	llc_pdu_decode_da(skb, mac_sa);
160 	llc_pdu_decode_ssap(skb, &dsap);
161 
162 	/* The test request command is type U (llc_len = 3) */
163 	data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
164 	nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
165 	if (!nskb)
166 		goto out;
167 	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
168 			    LLC_PDU_RSP);
169 	llc_pdu_init_as_test_rsp(nskb, skb);
170 	rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
171 	if (likely(!rc))
172 		rc = dev_queue_xmit(nskb);
173 out:
174 	return rc;
175 }
176 
177 /**
178  *	llc_sap_action_report_status - report data link status to layer mgmt
179  *	@sap: SAP
180  *	@skb: the event to send
181  *
182  *	Report data link status to layer management. Verify our event is the
183  *	kind we expect.
184  */
185 int llc_sap_action_report_status(struct llc_sap *sap, struct sk_buff *skb)
186 {
187 	return 0;
188 }
189 
190 /**
191  *	llc_sap_action_xid_ind - send XID PDU resp to net layer via XID IND
192  *	@sap: SAP
193  *	@skb: the event to send
194  *
195  *	Send a XID response PDU to the network layer via a XID INDICATION
196  *	primitive.
197  */
198 int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb)
199 {
200 	llc_sap_rtn_pdu(sap, skb);
201 	return 0;
202 }
203 
204 /**
205  *	llc_sap_action_test_ind - send TEST PDU to net layer via TEST IND
206  *	@sap: SAP
207  *	@skb: the event to send
208  *
209  *	Send a TEST response PDU to the network layer via a TEST INDICATION
210  *	primitive. Verify our event is a PDU type event.
211  */
212 int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb)
213 {
214 	llc_sap_rtn_pdu(sap, skb);
215 	return 0;
216 }
217