⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 llc_c_ac.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * llc_c_ac.c - actions performed during connection state transition. * * Description: *   Functions in this module are implementation of connection component actions *   Details of actions can be found in IEEE-802.2 standard document. *   All functions have one connection and one event as input argument. All of *   them return 0 On success and 1 otherwise. * * Copyright (c) 1997 by Procom Technology, Inc. * 		 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br> * * This program can be redistributed or modified under the terms of the * GNU General Public License as published by the Free Software Foundation. * This program is distributed without any warranty or implied warranty * of merchantability or fitness for a particular purpose. * * See the GNU General Public License for more details. */#include <linux/netdevice.h>#include <net/llc_conn.h>#include <net/llc_sap.h>#include <net/sock.h>#include <net/llc_c_ev.h>#include <net/llc_c_ac.h>#include <net/llc_c_st.h>#include <net/llc_pdu.h>#include <net/llc.h>static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb);static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb);static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *ev);static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb);static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,					       struct sk_buff *skb);static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb);#define INCORRECT 0int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb){	struct llc_sock *llc = llc_sk(sk);	if (llc->remote_busy_flag) {		u8 nr;		struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);		llc->remote_busy_flag = 0;		del_timer(&llc->busy_state_timer.timer);		nr = LLC_I_GET_NR(pdu);		llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);	}	return 0;}int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb){	struct llc_conn_state_ev *ev = llc_conn_ev(skb);	ev->ind_prim = LLC_CONN_PRIM;	return 0;}int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb){	struct llc_conn_state_ev *ev = llc_conn_ev(skb);	ev->cfm_prim = LLC_CONN_PRIM;	return 0;}static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *skb){	struct llc_conn_state_ev *ev = llc_conn_ev(skb);	ev->cfm_prim = LLC_DATA_PRIM;	return 0;}int llc_conn_ac_data_ind(struct sock *sk, struct sk_buff *skb){	llc_conn_rtn_pdu(sk, skb);	return 0;}int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb){	struct llc_conn_state_ev *ev = llc_conn_ev(skb);	u8 reason = 0;	int rc = 0;	if (ev->type == LLC_CONN_EV_TYPE_PDU) {		struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);		if (LLC_PDU_IS_RSP(pdu) &&		    LLC_PDU_TYPE_IS_U(pdu) &&		    LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM)			reason = LLC_DISC_REASON_RX_DM_RSP_PDU;		else if (LLC_PDU_IS_CMD(pdu) &&			   LLC_PDU_TYPE_IS_U(pdu) &&			   LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC)			reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;	} else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR)		reason = LLC_DISC_REASON_ACK_TMR_EXP;	else		rc = -EINVAL;	if (!rc) {		ev->reason   = reason;		ev->ind_prim = LLC_DISC_PRIM;	}	return rc;}int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb){	struct llc_conn_state_ev *ev = llc_conn_ev(skb);	ev->reason   = ev->status;	ev->cfm_prim = LLC_DISC_PRIM;	return 0;}int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb){	u8 reason = 0;	int rc = 1;	struct llc_conn_state_ev *ev = llc_conn_ev(skb);	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);	struct llc_sock *llc = llc_sk(sk);	switch (ev->type) {	case LLC_CONN_EV_TYPE_PDU:		if (LLC_PDU_IS_RSP(pdu) &&		    LLC_PDU_TYPE_IS_U(pdu) &&		    LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR) {			reason = LLC_RESET_REASON_LOCAL;			rc = 0;		} else if (LLC_PDU_IS_CMD(pdu) &&			   LLC_PDU_TYPE_IS_U(pdu) &&			   LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME) {			reason = LLC_RESET_REASON_REMOTE;			rc = 0;		}		break;	case LLC_CONN_EV_TYPE_ACK_TMR:	case LLC_CONN_EV_TYPE_P_TMR:	case LLC_CONN_EV_TYPE_REJ_TMR:	case LLC_CONN_EV_TYPE_BUSY_TMR:		if (llc->retry_count > llc->n2) {			reason = LLC_RESET_REASON_LOCAL;			rc = 0;		}		break;	}	if (!rc) {		ev->reason   = reason;		ev->ind_prim = LLC_RESET_PRIM;	}	return rc;}int llc_conn_ac_rst_confirm(struct sock *sk, struct sk_buff *skb){	struct llc_conn_state_ev *ev = llc_conn_ev(skb);	ev->reason   = 0;	ev->cfm_prim = LLC_RESET_PRIM;	return 0;}int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk,					    struct sk_buff *skb){	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);	if (LLC_PDU_IS_RSP(pdu) &&	    LLC_PDU_TYPE_IS_I(pdu) &&	    LLC_I_PF_IS_1(pdu) && llc_sk(sk)->ack_pf)		llc_conn_ac_clear_remote_busy(sk, skb);	return 0;}int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk,					       struct sk_buff *skb){	struct llc_sock *llc = llc_sk(sk);	if (llc->data_flag == 2)		del_timer(&llc->rej_sent_timer.timer);	return 0;}int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb){	int rc = -ENOBUFS;	struct llc_sock *llc = llc_sk(sk);	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);	if (nskb) {		struct llc_sap *sap = llc->sap;		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,				    llc->daddr.lsap, LLC_PDU_CMD);		llc_pdu_init_as_disc_cmd(nskb, 1);		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);		if (unlikely(rc))			goto free;		llc_conn_send_pdu(sk, nskb);		llc_conn_ac_set_p_flag_1(sk, skb);	}out:	return rc;free:	kfree_skb(nskb);	goto out;}int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb){	int rc = -ENOBUFS;	struct llc_sock *llc = llc_sk(sk);	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);	if (nskb) {		struct llc_sap *sap = llc->sap;		u8 f_bit;		llc_pdu_decode_pf_bit(skb, &f_bit);		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,				    llc->daddr.lsap, LLC_PDU_RSP);		llc_pdu_init_as_dm_rsp(nskb, f_bit);		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);		if (unlikely(rc))			goto free;		llc_conn_send_pdu(sk, nskb);	}out:	return rc;free:	kfree_skb(nskb);	goto out;}int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb){	int rc = -ENOBUFS;	struct llc_sock *llc = llc_sk(sk);	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);	if (nskb) {		struct llc_sap *sap = llc->sap;		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,				    llc->daddr.lsap, LLC_PDU_RSP);		llc_pdu_init_as_dm_rsp(nskb, 1);		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);		if (unlikely(rc))			goto free;		llc_conn_send_pdu(sk, nskb);	}out:	return rc;free:	kfree_skb(nskb);	goto out;}int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb){	u8 f_bit;	int rc = -ENOBUFS;	struct sk_buff *nskb;	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);	struct llc_sock *llc = llc_sk(sk);	llc->rx_pdu_hdr = *((u32 *)pdu);	if (LLC_PDU_IS_CMD(pdu))		llc_pdu_decode_pf_bit(skb, &f_bit);	else		f_bit = 0;	nskb = llc_alloc_frame(sk, llc->dev);	if (nskb) {		struct llc_sap *sap = llc->sap;		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,				    llc->daddr.lsap, LLC_PDU_RSP);		llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,					 llc->vR, INCORRECT);		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);		if (unlikely(rc))			goto free;		llc_conn_send_pdu(sk, nskb);	}out:	return rc;free:	kfree_skb(nskb);	goto out;}int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb){	int rc = -ENOBUFS;	struct llc_sock *llc = llc_sk(sk);	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);	if (nskb) {		struct llc_sap *sap = llc->sap;		struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr;		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,				    llc->daddr.lsap, LLC_PDU_RSP);		llc_pdu_init_as_frmr_rsp(nskb, pdu, 0, llc->vS,					 llc->vR, INCORRECT);		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);		if (unlikely(rc))			goto free;		llc_conn_send_pdu(sk, nskb);	}out:	return rc;free:	kfree_skb(nskb);	goto out;}int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb){	u8 f_bit;	int rc = -ENOBUFS;	struct sk_buff *nskb;	struct llc_sock *llc = llc_sk(sk);	llc_pdu_decode_pf_bit(skb, &f_bit);	nskb = llc_alloc_frame(sk, llc->dev);	if (nskb) {		struct llc_sap *sap = llc->sap;		struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,				    llc->daddr.lsap, LLC_PDU_RSP);		llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,					 llc->vR, INCORRECT);		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);		if (unlikely(rc))			goto free;		llc_conn_send_pdu(sk, nskb);	}out:	return rc;free:	kfree_skb(nskb);	goto out;}int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb){	int rc;	struct llc_sock *llc = llc_sk(sk);	struct llc_sap *sap = llc->sap;	llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,			    llc->daddr.lsap, LLC_PDU_CMD);	llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR);	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);	if (likely(!rc)) {		llc_conn_send_pdu(sk, skb);		llc_conn_ac_inc_vs_by_1(sk, skb);	}	return rc;}static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb){	int rc;	struct llc_sock *llc = llc_sk(sk);	struct llc_sap *sap = llc->sap;	llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,			    llc->daddr.lsap, LLC_PDU_CMD);	llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);	if (likely(!rc)) {		llc_conn_send_pdu(sk, skb);		llc_conn_ac_inc_vs_by_1(sk, skb);	}	return rc;}int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb){	int rc;	struct llc_sock *llc = llc_sk(sk);	struct llc_sap *sap = llc->sap;	llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,			    llc->daddr.lsap, LLC_PDU_CMD);	llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);	if (likely(!rc)) {		llc_conn_send_pdu(sk, skb);		llc_conn_ac_inc_vs_by_1(sk, skb);	}	return 0;}int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb){	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);	u8 nr = LLC_I_GET_NR(pdu);	llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);	return 0;}int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,						struct sk_buff *skb){	u8 nr;	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);	int rc = -ENOBUFS;	struct llc_sock *llc = llc_sk(sk);	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);	if (nskb) {		struct llc_sap *sap = llc->sap;		llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,				    llc->daddr.lsap, LLC_PDU_RSP);		llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);		if (likely(!rc))			llc_conn_send_pdu(sk, nskb);		else			kfree_skb(skb);	}	if (rc) {		nr = LLC_I_GET_NR(pdu);		rc = 0;		llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);	}	return rc;}int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb){	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);	u8 nr = LLC_I_GET_NR(pdu);	llc_conn_resend_i_pdu_as_rsp(sk, nr, 1);	return 0;}int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb){	int rc = -ENOBUFS;	struct llc_sock *llc = llc_sk(sk);	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);	if (nskb) {		struct llc_sap *sap = llc->sap;		llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,				    llc->daddr.lsap, LLC_PDU_CMD);		llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR);		rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);		if (unlikely(rc))			goto free;		llc_conn_send_pdu(sk, nskb);	}out:	return rc;free:	kfree_skb(nskb);	goto out;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -