diff options
| -rw-r--r-- | include/net/llc_mac.h | 1 | ||||
| -rw-r--r-- | net/llc/Makefile | 2 | ||||
| -rw-r--r-- | net/llc/llc_actn.c | 23 | ||||
| -rw-r--r-- | net/llc/llc_c_ac.c | 400 | ||||
| -rw-r--r-- | net/llc/llc_mac.c | 55 | ||||
| -rw-r--r-- | net/llc/llc_output.c | 75 | ||||
| -rw-r--r-- | net/llc/llc_output.h | 20 | ||||
| -rw-r--r-- | net/llc/llc_s_ac.c | 10 |
8 files changed, 378 insertions, 208 deletions
diff --git a/include/net/llc_mac.h b/include/net/llc_mac.h index 8281a66c0b64..6064d6b909b1 100644 --- a/include/net/llc_mac.h +++ b/include/net/llc_mac.h @@ -18,7 +18,6 @@ extern int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt); -extern u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da); struct llc_sap; struct sk_buff; diff --git a/net/llc/Makefile b/net/llc/Makefile index df53f82b2a6a..7a47ade2c428 100644 --- a/net/llc/Makefile +++ b/net/llc/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_LLC_CORE) += llc_core.o llc_core-y := llc_mac.o llc_sap.o llc_s_st.o llc_s_ac.o llc_s_ev.o llc_main.o \ - llc_actn.o llc_stat.o llc_evnt.o + llc_actn.o llc_stat.o llc_evnt.o llc_output.o obj-$(CONFIG_LLC2) += llc2.o diff --git a/net/llc/llc_actn.c b/net/llc/llc_actn.c index b17943a5c222..db252bead811 100644 --- a/net/llc/llc_actn.c +++ b/net/llc/llc_actn.c @@ -23,6 +23,7 @@ #include <net/llc_evnt.h> #include <net/llc_pdu.h> #include <net/llc_mac.h> +#include "llc_output.h" int llc_station_ac_start_ack_timer(struct llc_station *station, struct sk_buff *skb) @@ -67,13 +68,17 @@ int llc_station_ac_send_null_dsap_xid_c(struct llc_station *station, if (!nskb) goto out; - rc = 0; llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD); llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127); - lan_hdrs_init(nskb, station->mac_sa, station->mac_sa); + rc = llc_mac_hdr_init(nskb, station->mac_sa, station->mac_sa); + if (rc) + goto free; llc_station_send_pdu(station, nskb); out: return rc; +free: + kfree_skb(skb); + goto out; } int llc_station_ac_send_xid_r(struct llc_station *station, @@ -91,10 +96,15 @@ int llc_station_ac_send_xid_r(struct llc_station *station, llc_pdu_decode_ssap(skb, &dsap); llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP); llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127); - lan_hdrs_init(nskb, station->mac_sa, mac_da); + rc = llc_mac_hdr_init(nskb, station->mac_sa, mac_da); + if (rc) + goto free; llc_station_send_pdu(station, nskb); out: return rc; +free: + kfree_skb(skb); + goto out; } int llc_station_ac_send_test_r(struct llc_station *station, @@ -112,10 +122,15 @@ int llc_station_ac_send_test_r(struct llc_station *station, llc_pdu_decode_ssap(skb, &dsap); llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP); llc_pdu_init_as_test_rsp(nskb, skb); - lan_hdrs_init(nskb, station->mac_sa, mac_da); + rc = llc_mac_hdr_init(nskb, station->mac_sa, mac_da); + if (rc) + goto free; llc_station_send_pdu(station, nskb); out: return rc; +free: + kfree_skb(skb); + goto out; } int llc_station_ac_report_status(struct llc_station *station, diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index d7f35bf275a7..c0acd7084eba 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c @@ -28,6 +28,8 @@ #include <net/llc_pdu.h> #include <net/llc_mac.h> +#include "llc_output.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); @@ -52,7 +54,7 @@ int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb) int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOTCONN; u8 dsap; struct llc_sap *sap; @@ -97,28 +99,24 @@ 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 = 1; + 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) { + LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM) reason = LLC_DISC_REASON_RX_DM_RSP_PDU; - rc = 0; - } else if (LLC_PDU_IS_CMD(pdu) && + else if (LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) && - LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC) { + LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC) reason = LLC_DISC_REASON_RX_DISC_CMD_PDU; - rc = 0; - } - } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR) { + } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR) reason = LLC_DISC_REASON_ACK_TMR_EXP; - rc = 0; - } else { + else { reason = 0; - rc = 1; + rc = -EINVAL; } if (!rc) { ev->reason = reason; @@ -217,29 +215,33 @@ int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk, int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { - u8 p_bit = 1; struct llc_opt *llc = llc_sk(sk); struct llc_sap *sap = llc->sap; nskb->dev = llc->dev; 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, p_bit); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + llc_pdu_init_as_disc_cmd(nskb, 1); + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); + llc_conn_ac_set_p_flag_1(sk, skb); } - 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 = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { @@ -252,16 +254,21 @@ int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) 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); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (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 = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { @@ -273,16 +280,21 @@ int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) 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); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (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_f_flag(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { @@ -294,17 +306,22 @@ int llc_conn_ac_send_dm_rsp_f_set_f_flag(struct sock *sk, struct sk_buff *skb) 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); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (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 = 1; + int rc = -ENOBUFS; struct sk_buff *nskb; struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); struct llc_opt *llc = llc_sk(sk); @@ -323,16 +340,21 @@ int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb) llc->daddr.lsap, LLC_PDU_RSP); llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS, llc->vR, INCORRECT); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (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 = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { @@ -346,17 +368,22 @@ int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb) llc->daddr.lsap, LLC_PDU_RSP); llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS, llc->vR, INCORRECT); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (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 = 1; + int rc = -ENOBUFS; struct sk_buff *nskb; llc_pdu_decode_pf_bit(skb, &f_bit); @@ -371,41 +398,50 @@ int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) llc->daddr.lsap, LLC_PDU_RSP); llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS, llc->vR, INCORRECT); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (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) { - u8 p_bit = 1; + int rc; struct llc_opt *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, p_bit, llc->vS, llc->vR); - lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); - llc_conn_send_pdu(sk, skb); - llc_conn_ac_inc_vs_by_1(sk, skb); - return 0; + 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 (!rc) { + llc_conn_send_pdu(sk, skb); + llc_conn_ac_inc_vs_by_1(sk, skb); + } + return rc; } int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb) { - u8 p_bit = 0; + int rc; struct llc_opt *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, p_bit, llc->vS, llc->vR); - lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); - llc_conn_send_pdu(sk, skb); - llc_conn_ac_inc_vs_by_1(sk, skb); - return 0; + 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 (!rc) { + llc_conn_send_pdu(sk, skb); + llc_conn_ac_inc_vs_by_1(sk, skb); + } + return rc; } int llc_conn_ac_resend_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) @@ -431,16 +467,18 @@ int llc_conn_ac_resend_i_cmd_p_set_1_or_send_rr(struct sock *sk, int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) { - u8 p_bit = 0; + int rc; struct llc_opt *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, p_bit, llc->vS, llc->vR); - lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); - llc_conn_send_pdu(sk, skb); - llc_conn_ac_inc_vs_by_1(sk, skb); + 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 (!rc) { + llc_conn_send_pdu(sk, skb); + llc_conn_ac_inc_vs_by_1(sk, skb); + } return 0; } @@ -457,9 +495,8 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk, struct sk_buff *skb) { u8 nr; - u8 f_bit = 0; struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { @@ -469,15 +506,17 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk, nskb->dev = llc->dev; 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, f_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; - llc_conn_send_pdu(sk, nskb); + llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR); + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (!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, f_bit); + llc_conn_resend_i_pdu_as_cmd(sk, nr, 0); } return rc; } @@ -493,28 +532,32 @@ int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { struct llc_opt *llc = llc_sk(sk); struct llc_sap *sap = llc->sap; - u8 p_bit = 1; nskb->dev = llc->dev; 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, p_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR); + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { @@ -526,16 +569,21 @@ int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { @@ -547,37 +595,46 @@ int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { struct llc_opt *llc = llc_sk(sk); struct llc_sap *sap = llc->sap; - u8 p_bit = 1; nskb->dev = llc->dev; llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_CMD); - llc_pdu_init_as_rnr_cmd(nskb, p_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR); + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { @@ -589,16 +646,21 @@ int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { @@ -610,11 +672,16 @@ int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb) @@ -631,70 +698,82 @@ int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb) int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { struct llc_opt *llc = llc_sk(sk); struct llc_sap *sap = llc->sap; - u8 f_bit = 0; nskb->dev = llc->dev; llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); - llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR); + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { - u8 p_bit = 1; struct llc_opt *llc = llc_sk(sk); struct llc_sap *sap = llc->sap; nskb->dev = llc->dev; llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_CMD); - llc_pdu_init_as_rr_cmd(nskb, p_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR); + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_ack_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { - u8 p_bit = 1; struct llc_opt *llc = llc_sk(sk); struct llc_sap *sap = llc->sap; nskb->dev = llc->dev; llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_CMD); - llc_pdu_init_as_rr_cmd(nskb, p_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR); + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { @@ -706,16 +785,21 @@ int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { @@ -727,53 +811,66 @@ int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { struct llc_opt *llc = llc_sk(sk); struct llc_sap *sap = llc->sap; - u8 f_bit = 0; nskb->dev = llc->dev; llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); - llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR); + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { struct llc_opt *llc = llc_sk(sk); struct llc_sap *sap = llc->sap; - u8 f_bit = 0; nskb->dev = llc->dev; llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); - llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR); + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } void llc_conn_set_p_flag(struct sock *sk, u8 value) @@ -788,10 +885,9 @@ void llc_conn_set_p_flag(struct sock *sk, u8 value) int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); struct llc_opt *llc = llc_sk(sk); - u8 p_bit = 1; if (nskb) { struct llc_sap *sap = llc->sap; @@ -802,41 +898,49 @@ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) nskb->dev = llc->dev; llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_CMD); - llc_pdu_init_as_sabme_cmd(nskb, p_bit); - lan_hdrs_init(nskb, llc->dev->dev_addr, dmac); - rc = 0; + llc_pdu_init_as_sabme_cmd(nskb, 1); + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); + llc_conn_set_p_flag(sk, 1); } - llc_conn_set_p_flag(sk, p_bit); - +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_ua_rsp_f_set_f_flag(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { struct llc_opt *llc = llc_sk(sk); struct llc_sap *sap = llc->sap; - u8 f_bit = llc->f_flag; nskb->dev = llc->dev; llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); - llc_pdu_init_as_ua_rsp(nskb, f_bit); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + llc_pdu_init_as_ua_rsp(nskb, llc->f_flag); + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) { u8 f_bit; - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); llc_pdu_decode_pf_bit(skb, &f_bit); @@ -848,11 +952,16 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); llc_pdu_init_as_ua_rsp(nskb, f_bit); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb) @@ -935,17 +1044,19 @@ int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb) */ int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk, struct sk_buff *skb) { + int rc; struct llc_opt *llc = llc_sk(sk); - u8 p_bit = llc->ack_pf; struct llc_sap *sap = llc->sap; llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); - llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR); - lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac); - llc_conn_send_pdu(sk, skb); - llc_conn_ac_inc_vs_by_1(sk, skb); - return 0; + llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR); + rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); + if (!rc) { + llc_conn_send_pdu(sk, skb); + llc_conn_ac_inc_vs_by_1(sk, skb); + } + return rc; } /** @@ -983,23 +1094,27 @@ int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb) */ int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk, struct sk_buff *skb) { - int rc = 1; + int rc = -ENOBUFS; struct sk_buff *nskb = llc_alloc_frame(); if (nskb) { struct llc_opt *llc = llc_sk(sk); struct llc_sap *sap = llc->sap; - u8 f_bit = llc->ack_pf; nskb->dev = llc->dev; llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, llc->daddr.lsap, LLC_PDU_RSP); - llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR); - lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac); - rc = 0; + llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR); + rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); + if (rc) + goto free; llc_conn_send_pdu(sk, nskb); } +out: return rc; +free: + kfree_skb(nskb); + goto out; } /** @@ -1193,7 +1308,6 @@ int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb) { int acked; u16 unacked = 0; - u8 fbit; struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); struct llc_opt *llc = llc_sk(sk); @@ -1215,8 +1329,10 @@ int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb) mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire * HZ); } else if (llc->failed_data_req) { - llc_pdu_decode_pf_bit(skb, &fbit); - if (fbit == 1) { + u8 f_bit; + + llc_pdu_decode_pf_bit(skb, &f_bit); + if (f_bit == 1) { llc->failed_data_req = 0; llc_conn_ac_data_confirm(sk, skb); } diff --git a/net/llc/llc_mac.c b/net/llc/llc_mac.c index 03d1cad47ce6..0330488e7bf2 100644 --- a/net/llc/llc_mac.c +++ b/net/llc/llc_mac.c @@ -192,60 +192,5 @@ static void llc_station_rcv(struct sk_buff *skb) llc_station_state_process(&llc_main_station, skb); } -/** - * lan_hdrs_init - fills MAC header fields - * @skb: Address of the frame to initialize its MAC header - * @sa: The MAC source address - * @da: The MAC destination address - * - * Fills MAC header fields, depending on MAC type. Returns 0, If MAC type - * is a valid type and initialization completes correctly 1, otherwise. - */ -u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da) -{ - u16 rc = 0; - - switch (skb->dev->type) { -#ifdef CONFIG_TR - case ARPHRD_IEEE802_TR: { - struct trh_hdr *trh; - struct net_device *dev = skb->dev; - - trh = (struct trh_hdr *)skb_push(skb, sizeof(*trh)); - trh->ac = AC; - trh->fc = LLC_FRAME; - if (sa) - memcpy(trh->saddr, sa, dev->addr_len); - else - memset(trh->saddr, 0, dev->addr_len); - if (da) { - memcpy(trh->daddr, da, dev->addr_len); - tr_source_route(skb, trh, dev); - } - skb->mac.raw = skb->data; - break; - } -#endif - case ARPHRD_ETHER: - case ARPHRD_LOOPBACK: { - unsigned short len = skb->len; - struct ethhdr *eth; - - skb->mac.raw = skb_push(skb, sizeof(*eth)); - eth = (struct ethhdr *)skb->mac.raw; - eth->h_proto = htons(len); - memcpy(eth->h_dest, da, ETH_ALEN); - memcpy(eth->h_source, sa, ETH_ALEN); - break; - } - default: - printk(KERN_WARNING "Unknown DEVICE type : %d\n", - skb->dev->type); - rc = 1; - } - return rc; -} - EXPORT_SYMBOL(llc_add_pack); EXPORT_SYMBOL(llc_remove_pack); -EXPORT_SYMBOL(lan_hdrs_init); diff --git a/net/llc/llc_output.c b/net/llc/llc_output.c new file mode 100644 index 000000000000..71aa64ea2a39 --- /dev/null +++ b/net/llc/llc_output.c @@ -0,0 +1,75 @@ +/* + * llc_output.c - LLC output path + * + * 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 version 2 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 version 2 for more details. + */ + +#include <linux/if_arp.h> +#include <linux/if_tr.h> +#include <linux/netdevice.h> +#include <linux/skbuff.h> + +/** + * llc_mac_hdr_init - fills MAC header fields + * @skb: Address of the frame to initialize its MAC header + * @sa: The MAC source address + * @da: The MAC destination address + * + * Fills MAC header fields, depending on MAC type. Returns 0, If MAC type + * is a valid type and initialization completes correctly 1, otherwise. + */ +int llc_mac_hdr_init(struct sk_buff *skb, unsigned char *sa, unsigned char *da) +{ + int rc = 0; + + switch (skb->dev->type) { +#ifdef CONFIG_TR + case ARPHRD_IEEE802_TR: { + struct net_device *dev = skb->dev; + struct trh_hdr *trh; + + trh = (struct trh_hdr *)skb_push(skb, sizeof(*trh)); + trh->ac = AC; + trh->fc = LLC_FRAME; + if (sa) + memcpy(trh->saddr, sa, dev->addr_len); + else + memset(trh->saddr, 0, dev->addr_len); + if (da) { + memcpy(trh->daddr, da, dev->addr_len); + tr_source_route(skb, trh, dev); + } + skb->mac.raw = skb->data; + break; + } +#endif + case ARPHRD_ETHER: + case ARPHRD_LOOPBACK: { + unsigned short len = skb->len; + struct ethhdr *eth; + + skb->mac.raw = skb_push(skb, sizeof(*eth)); + eth = (struct ethhdr *)skb->mac.raw; + eth->h_proto = htons(len); + memcpy(eth->h_dest, da, ETH_ALEN); + memcpy(eth->h_source, sa, ETH_ALEN); + break; + } + default: + printk(KERN_WARNING "device type not supported: %d\n", + skb->dev->type); + rc = -EINVAL; + } + return rc; +} + +EXPORT_SYMBOL(llc_mac_hdr_init); diff --git a/net/llc/llc_output.h b/net/llc/llc_output.h new file mode 100644 index 000000000000..179edf753f00 --- /dev/null +++ b/net/llc/llc_output.h @@ -0,0 +1,20 @@ +#ifndef LLC_OUTPUT_H +#define LLC_OUTPUT_H +/* + * 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 version 2 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 version 2 for more details. + */ + +struct sk_buff; + +int llc_mac_hdr_init(struct sk_buff *skb, unsigned char *sa, unsigned char *da); + +#endif /* LLC_OUTPUT_H */ diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c index 1a67f2ef1a56..ffc6634f2b61 100644 --- a/net/llc/llc_s_ac.c +++ b/net/llc/llc_s_ac.c @@ -56,7 +56,7 @@ int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb) llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap, ev->daddr.lsap, LLC_PDU_CMD); llc_pdu_init_as_ui_cmd(skb); - rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac); + rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); if (!rc) rc = dev_queue_xmit(skb); return rc; @@ -79,7 +79,7 @@ int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb) llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap, ev->daddr.lsap, LLC_PDU_CMD); llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0); - rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac); + rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); if (!rc) rc = dev_queue_xmit(skb); return rc; @@ -109,7 +109,7 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb) llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, LLC_PDU_RSP); llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0); - rc = lan_hdrs_init(nskb, mac_sa, mac_da); + rc = llc_mac_hdr_init(nskb, mac_sa, mac_da); if (!rc) rc = dev_queue_xmit(nskb); out: @@ -133,7 +133,7 @@ int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb) llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap, ev->daddr.lsap, LLC_PDU_CMD); llc_pdu_init_as_test_cmd(skb); - rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac); + rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); if (!rc) rc = dev_queue_xmit(skb); return rc; @@ -155,7 +155,7 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb) llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, LLC_PDU_RSP); llc_pdu_init_as_test_rsp(nskb, skb); - rc = lan_hdrs_init(nskb, mac_sa, mac_da); + rc = llc_mac_hdr_init(nskb, mac_sa, mac_da); if (!rc) rc = dev_queue_xmit(nskb); out: |
