0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <linux/netdevice.h>
0022 #include <net/llc.h>
0023 #include <net/llc_pdu.h>
0024 #include <net/llc_s_ac.h>
0025 #include <net/llc_s_ev.h>
0026 #include <net/llc_sap.h>
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb)
0038 {
0039 llc_sap_rtn_pdu(sap, skb);
0040 return 0;
0041 }
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)
0053 {
0054 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
0055 int rc;
0056
0057 llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
0058 ev->daddr.lsap, LLC_PDU_CMD);
0059 llc_pdu_init_as_ui_cmd(skb);
0060 rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
0061 if (likely(!rc)) {
0062 skb_get(skb);
0063 rc = dev_queue_xmit(skb);
0064 }
0065 return rc;
0066 }
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb)
0078 {
0079 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
0080 int rc;
0081
0082 llc_pdu_header_init(skb, LLC_PDU_TYPE_U_XID, ev->saddr.lsap,
0083 ev->daddr.lsap, LLC_PDU_CMD);
0084 llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
0085 rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
0086 if (likely(!rc)) {
0087 skb_get(skb);
0088 rc = dev_queue_xmit(skb);
0089 }
0090 return rc;
0091 }
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
0102 {
0103 u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
0104 int rc = 1;
0105 struct sk_buff *nskb;
0106
0107 llc_pdu_decode_sa(skb, mac_da);
0108 llc_pdu_decode_da(skb, mac_sa);
0109 llc_pdu_decode_ssap(skb, &dsap);
0110 nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
0111 sizeof(struct llc_xid_info));
0112 if (!nskb)
0113 goto out;
0114 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
0115 LLC_PDU_RSP);
0116 llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0);
0117 rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
0118 if (likely(!rc))
0119 rc = dev_queue_xmit(nskb);
0120 out:
0121 return rc;
0122 }
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb)
0134 {
0135 struct llc_sap_state_ev *ev = llc_sap_ev(skb);
0136 int rc;
0137
0138 llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
0139 ev->daddr.lsap, LLC_PDU_CMD);
0140 llc_pdu_init_as_test_cmd(skb);
0141 rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
0142 if (likely(!rc)) {
0143 skb_get(skb);
0144 rc = dev_queue_xmit(skb);
0145 }
0146 return rc;
0147 }
0148
0149 int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
0150 {
0151 u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
0152 struct sk_buff *nskb;
0153 int rc = 1;
0154 u32 data_size;
0155
0156 llc_pdu_decode_sa(skb, mac_da);
0157 llc_pdu_decode_da(skb, mac_sa);
0158 llc_pdu_decode_ssap(skb, &dsap);
0159
0160
0161 data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
0162 nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
0163 if (!nskb)
0164 goto out;
0165 llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
0166 LLC_PDU_RSP);
0167 llc_pdu_init_as_test_rsp(nskb, skb);
0168 rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
0169 if (likely(!rc))
0170 rc = dev_queue_xmit(nskb);
0171 out:
0172 return rc;
0173 }
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 int llc_sap_action_report_status(struct llc_sap *sap, struct sk_buff *skb)
0184 {
0185 return 0;
0186 }
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb)
0197 {
0198 llc_sap_rtn_pdu(sap, skb);
0199 return 0;
0200 }
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb)
0211 {
0212 llc_sap_rtn_pdu(sap, skb);
0213 return 0;
0214 }