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