/*1* llc_s_ac.c - actions performed during sap state transition.2*3* Description :4* Functions in this module are implementation of sap component actions.5* Details of actions can be found in IEEE-802.2 standard document.6* All functions have one sap and one event as input argument. All of7* them return 0 On success and 1 otherwise.8*9* Copyright (c) 1997 by Procom Technology, Inc.10* 2001-2003 by Arnaldo Carvalho de Melo <[email protected]>11*12* This program can be redistributed or modified under the terms of the13* GNU General Public License as published by the Free Software Foundation.14* This program is distributed without any warranty or implied warranty15* of merchantability or fitness for a particular purpose.16*17* See the GNU General Public License for more details.18*/1920#include <linux/netdevice.h>21#include <net/llc.h>22#include <net/llc_pdu.h>23#include <net/llc_s_ac.h>24#include <net/llc_s_ev.h>25#include <net/llc_sap.h>26#include <net/sock.h>2728/**29* llc_sap_action_unitdata_ind - forward UI PDU to network layer30* @sap: SAP31* @skb: the event to forward32*33* Received a UI PDU from MAC layer; forward to network layer as a34* UNITDATA INDICATION; verify our event is the kind we expect35*/36int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb)37{38llc_sap_rtn_pdu(sap, skb);39return 0;40}4142static int llc_prepare_and_xmit(struct sk_buff *skb)43{44struct llc_sap_state_ev *ev = llc_sap_ev(skb);45struct sk_buff *nskb;46int rc;4748rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);49if (rc)50return rc;5152nskb = skb_clone(skb, GFP_ATOMIC);53if (!nskb)54return -ENOMEM;5556if (skb->sk)57skb_set_owner_w(nskb, skb->sk);5859return dev_queue_xmit(nskb);60}6162/**63* llc_sap_action_send_ui - sends UI PDU resp to UNITDATA REQ to MAC layer64* @sap: SAP65* @skb: the event to send66*67* Sends a UI PDU to the MAC layer in response to a UNITDATA REQUEST68* primitive from the network layer. Verifies event is a primitive type of69* event. Verify the primitive is a UNITDATA REQUEST.70*/71int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)72{73struct llc_sap_state_ev *ev = llc_sap_ev(skb);7475llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,76ev->daddr.lsap, LLC_PDU_CMD);77llc_pdu_init_as_ui_cmd(skb);7879return llc_prepare_and_xmit(skb);80}8182/**83* llc_sap_action_send_xid_c - send XID PDU as response to XID REQ84* @sap: SAP85* @skb: the event to send86*87* Send a XID command PDU to MAC layer in response to a XID REQUEST88* primitive from the network layer. Verify event is a primitive type89* event. Verify the primitive is a XID REQUEST.90*/91int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb)92{93struct llc_sap_state_ev *ev = llc_sap_ev(skb);9495llc_pdu_header_init(skb, LLC_PDU_TYPE_U_XID, ev->saddr.lsap,96ev->daddr.lsap, LLC_PDU_CMD);97llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);9899return llc_prepare_and_xmit(skb);100}101102/**103* llc_sap_action_send_xid_r - send XID PDU resp to MAC for received XID104* @sap: SAP105* @skb: the event to send106*107* Send XID response PDU to MAC in response to an earlier received XID108* command PDU. Verify event is a PDU type event109*/110int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)111{112u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;113int rc = 1;114struct sk_buff *nskb;115116llc_pdu_decode_sa(skb, mac_da);117llc_pdu_decode_da(skb, mac_sa);118llc_pdu_decode_ssap(skb, &dsap);119nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,120sizeof(struct llc_xid_info));121if (!nskb)122goto out;123llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,124LLC_PDU_RSP);125llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0);126rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);127if (likely(!rc))128rc = dev_queue_xmit(nskb);129out:130return rc;131}132133/**134* llc_sap_action_send_test_c - send TEST PDU to MAC in resp to TEST REQ135* @sap: SAP136* @skb: the event to send137*138* Send a TEST command PDU to the MAC layer in response to a TEST REQUEST139* primitive from the network layer. Verify event is a primitive type140* event; verify the primitive is a TEST REQUEST.141*/142int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb)143{144struct llc_sap_state_ev *ev = llc_sap_ev(skb);145146llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,147ev->daddr.lsap, LLC_PDU_CMD);148llc_pdu_init_as_test_cmd(skb);149150return llc_prepare_and_xmit(skb);151}152153int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)154{155u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;156struct sk_buff *nskb;157int rc = 1;158u32 data_size;159160if (skb->mac_len < ETH_HLEN)161return 1;162163llc_pdu_decode_sa(skb, mac_da);164llc_pdu_decode_da(skb, mac_sa);165llc_pdu_decode_ssap(skb, &dsap);166167/* The test request command is type U (llc_len = 3) */168data_size = ntohs(eth_hdr(skb)->h_proto) - 3;169nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);170if (!nskb)171goto out;172llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,173LLC_PDU_RSP);174llc_pdu_init_as_test_rsp(nskb, skb);175rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);176if (likely(!rc))177rc = dev_queue_xmit(nskb);178out:179return rc;180}181182/**183* llc_sap_action_report_status - report data link status to layer mgmt184* @sap: SAP185* @skb: the event to send186*187* Report data link status to layer management. Verify our event is the188* kind we expect.189*/190int llc_sap_action_report_status(struct llc_sap *sap, struct sk_buff *skb)191{192return 0;193}194195/**196* llc_sap_action_xid_ind - send XID PDU resp to net layer via XID IND197* @sap: SAP198* @skb: the event to send199*200* Send a XID response PDU to the network layer via a XID INDICATION201* primitive.202*/203int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb)204{205llc_sap_rtn_pdu(sap, skb);206return 0;207}208209/**210* llc_sap_action_test_ind - send TEST PDU to net layer via TEST IND211* @sap: SAP212* @skb: the event to send213*214* Send a TEST response PDU to the network layer via a TEST INDICATION215* primitive. Verify our event is a PDU type event.216*/217int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb)218{219llc_sap_rtn_pdu(sap, skb);220return 0;221}222223224