mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
llc: move the type 2 sockets out of tree
802.2 LLC is only used in tree by protocols which need the connectionless type 1 subset: STP, which carries the bridge's BPDUs, GARP, which sends its own UI PDUs, and SNAP. The llc2 module on top of the core - the type 2 connection state machine, the type 1 SAP state machine, the station component and the PF_LLC socket family - has no in-kernel users and nobody who can test it; what we get instead is a slow trickle of drive-by fixes. There was a recent patch from Ernestas Kulik indicating potential real life use, but it was new/experimental and that person is not responding to off-list pings. Let LLC2 follow AX.25, hamradio and AppleTalk out of the Linux tree. We will maintain the code at: github.com/linux-netdev/mod-orphan for anyone interested in playing with it. PF_LLC goes in full, both the class two SOCK_STREAM and the class one SOCK_DGRAM half, and so do /proc/net/llc/ and /proc/sys/net/llc/. Note that the kernel also stops answering XID and TEST commands, addressed to a SAP or to the station - those are type 1, but they lived in the module, and they got answered whether or not any socket was open. Nothing in tree asks for them; what the core keeps is SAP registration and the UI path the in-tree users need. Retain the uAPI for now, like we did for AppleTalk. Only the socket ABI half of it is vestigial: STP, GARP, the bridge and openvswitch use the SAP numbers it defines. Cleaning up what the core no longer needs follows in the next patch. Signed-off-by: Jakub Kicinski <kuba@kernel.org> Link: https://patch.msgid.link/20260928190800.2521749-2-kuba@kernel.org Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
1b8a3f9052
commit
003f21868b
|
|
@ -321,7 +321,6 @@ CONFIG_BRIDGE=m
|
|||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_VLAN_8021Q_GVRP=y
|
||||
CONFIG_VLAN_8021Q_MVRP=y
|
||||
CONFIG_LLC2=m
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_HTB=m
|
||||
CONFIG_NET_SCH_PRIO=m
|
||||
|
|
|
|||
|
|
@ -337,7 +337,6 @@ CONFIG_BRIDGE=m
|
|||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_VLAN_8021Q_GVRP=y
|
||||
CONFIG_VLAN_8021Q_MVRP=y
|
||||
CONFIG_LLC2=m
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_HTB=m
|
||||
CONFIG_NET_SCH_PRIO=m
|
||||
|
|
|
|||
|
|
@ -90,7 +90,6 @@ CONFIG_ATM=y
|
|||
CONFIG_ATM_BR2684=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_LLC2=m
|
||||
CONFIG_DEV_APPLETALK=m
|
||||
CONFIG_IPDDP=m
|
||||
CONFIG_IPDDP_ENCAP=y
|
||||
|
|
|
|||
|
|
@ -135,7 +135,6 @@ CONFIG_ATM=y
|
|||
CONFIG_ATM_BR2684=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_LLC2=m
|
||||
CONFIG_DEV_APPLETALK=m
|
||||
CONFIG_IPDDP=m
|
||||
CONFIG_IPDDP_ENCAP=y
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@ CONFIG_IP_NF_MANGLE=y
|
|||
CONFIG_IP_NF_RAW=m
|
||||
CONFIG_BRIDGE=y
|
||||
CONFIG_VLAN_8021Q=y
|
||||
CONFIG_LLC2=m
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_CBQ=m
|
||||
CONFIG_NET_SCH_PRIO=m
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ CONFIG_INET=y
|
|||
CONFIG_INET_AH=m
|
||||
CONFIG_INET_ESP=m
|
||||
CONFIG_INET_DIAG=m
|
||||
CONFIG_LLC2=m
|
||||
# CONFIG_WIRELESS is not set
|
||||
CONFIG_EISA=y
|
||||
CONFIG_PCI=y
|
||||
|
|
|
|||
|
|
@ -9,9 +9,4 @@
|
|||
|
||||
#include <uapi/linux/llc.h>
|
||||
|
||||
#define LLC_SAP_DYN_START 0xC0
|
||||
#define LLC_SAP_DYN_STOP 0xDE
|
||||
#define LLC_SAP_DYN_TRIES 4
|
||||
|
||||
#define llc_ui_skb_cb(__skb) ((struct sockaddr_llc *)&((__skb)->cb[0]))
|
||||
#endif /* __LINUX_LLC_H */
|
||||
|
|
|
|||
|
|
@ -130,30 +130,4 @@ struct llc_sap *llc_sap_find(unsigned char sap_value);
|
|||
|
||||
int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
|
||||
const unsigned char *dmac, unsigned char dsap);
|
||||
|
||||
void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
|
||||
void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
|
||||
|
||||
void llc_station_init(void);
|
||||
void llc_station_exit(void);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
int llc_proc_init(void);
|
||||
void llc_proc_exit(void);
|
||||
#else
|
||||
#define llc_proc_init() (0)
|
||||
#define llc_proc_exit() do { } while(0)
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
#ifdef CONFIG_SYSCTL
|
||||
int llc_sysctl_init(void);
|
||||
void llc_sysctl_exit(void);
|
||||
|
||||
extern int sysctl_llc2_ack_timeout;
|
||||
extern int sysctl_llc2_busy_timeout;
|
||||
extern int sysctl_llc2_p_timeout;
|
||||
extern int sysctl_llc2_rej_timeout;
|
||||
#else
|
||||
#define llc_sysctl_init() (0)
|
||||
#define llc_sysctl_exit() do { } while(0)
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
#endif /* LLC_H */
|
||||
|
|
|
|||
|
|
@ -1,180 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef LLC_C_AC_H
|
||||
#define LLC_C_AC_H
|
||||
/*
|
||||
* Copyright (c) 1997 by Procom Technology,Inc.
|
||||
* 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
/* Connection component state transition actions */
|
||||
/*
|
||||
* Connection state transition actions
|
||||
* (Fb = F bit; Pb = P bit; Xb = X bit)
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct sk_buff;
|
||||
struct sock;
|
||||
struct timer_list;
|
||||
|
||||
#define LLC_CONN_AC_CLR_REMOTE_BUSY 1
|
||||
#define LLC_CONN_AC_CONN_IND 2
|
||||
#define LLC_CONN_AC_CONN_CONFIRM 3
|
||||
#define LLC_CONN_AC_DATA_IND 4
|
||||
#define LLC_CONN_AC_DISC_IND 5
|
||||
#define LLC_CONN_AC_RESET_IND 6
|
||||
#define LLC_CONN_AC_RESET_CONFIRM 7
|
||||
#define LLC_CONN_AC_REPORT_STATUS 8
|
||||
#define LLC_CONN_AC_CLR_REMOTE_BUSY_IF_Fb_EQ_1 9
|
||||
#define LLC_CONN_AC_STOP_REJ_TMR_IF_DATA_FLAG_EQ_2 10
|
||||
#define LLC_CONN_AC_SEND_DISC_CMD_Pb_SET_X 11
|
||||
#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_Pb 12
|
||||
#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_1 13
|
||||
#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_F_FLAG 14
|
||||
#define LLC_CONN_AC_SEND_FRMR_RSP_Fb_SET_X 15
|
||||
#define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_0 16
|
||||
#define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_Pb 17
|
||||
#define LLC_CONN_AC_SEND_I_CMD_Pb_SET_1 18
|
||||
#define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1 19
|
||||
#define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1_OR_SEND_RR 20
|
||||
#define LLC_CONN_AC_SEND_I_XXX_Xb_SET_0 21
|
||||
#define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0 22
|
||||
#define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0_OR_SEND_RR 23
|
||||
#define LLC_CONN_AC_RESEND_I_RSP_Fb_SET_1 24
|
||||
#define LLC_CONN_AC_SEND_REJ_CMD_Pb_SET_1 25
|
||||
#define LLC_CONN_AC_SEND_REJ_RSP_Fb_SET_1 26
|
||||
#define LLC_CONN_AC_SEND_REJ_XXX_Xb_SET_0 27
|
||||
#define LLC_CONN_AC_SEND_RNR_CMD_Pb_SET_1 28
|
||||
#define LLC_CONN_AC_SEND_RNR_RSP_Fb_SET_1 29
|
||||
#define LLC_CONN_AC_SEND_RNR_XXX_Xb_SET_0 30
|
||||
#define LLC_CONN_AC_SET_REMOTE_BUSY 31
|
||||
#define LLC_CONN_AC_OPTIONAL_SEND_RNR_XXX_Xb_SET_0 32
|
||||
#define LLC_CONN_AC_SEND_RR_CMD_Pb_SET_1 33
|
||||
#define LLC_CONN_AC_SEND_ACK_CMD_Pb_SET_1 34
|
||||
#define LLC_CONN_AC_SEND_RR_RSP_Fb_SET_1 35
|
||||
#define LLC_CONN_AC_SEND_ACK_RSP_Fb_SET_1 36
|
||||
#define LLC_CONN_AC_SEND_RR_XXX_Xb_SET_0 37
|
||||
#define LLC_CONN_AC_SEND_ACK_XXX_Xb_SET_0 38
|
||||
#define LLC_CONN_AC_SEND_SABME_CMD_Pb_SET_X 39
|
||||
#define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_Pb 40
|
||||
#define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_F_FLAG 41
|
||||
#define LLC_CONN_AC_S_FLAG_SET_0 42
|
||||
#define LLC_CONN_AC_S_FLAG_SET_1 43
|
||||
#define LLC_CONN_AC_START_P_TMR 44
|
||||
#define LLC_CONN_AC_START_ACK_TMR 45
|
||||
#define LLC_CONN_AC_START_REJ_TMR 46
|
||||
#define LLC_CONN_AC_START_ACK_TMR_IF_NOT_RUNNING 47
|
||||
#define LLC_CONN_AC_STOP_ACK_TMR 48
|
||||
#define LLC_CONN_AC_STOP_P_TMR 49
|
||||
#define LLC_CONN_AC_STOP_REJ_TMR 50
|
||||
#define LLC_CONN_AC_STOP_ALL_TMRS 51
|
||||
#define LLC_CONN_AC_STOP_OTHER_TMRS 52
|
||||
#define LLC_CONN_AC_UPDATE_Nr_RECEIVED 53
|
||||
#define LLC_CONN_AC_UPDATE_P_FLAG 54
|
||||
#define LLC_CONN_AC_DATA_FLAG_SET_2 55
|
||||
#define LLC_CONN_AC_DATA_FLAG_SET_0 56
|
||||
#define LLC_CONN_AC_DATA_FLAG_SET_1 57
|
||||
#define LLC_CONN_AC_DATA_FLAG_SET_1_IF_DATA_FLAG_EQ_0 58
|
||||
#define LLC_CONN_AC_P_FLAG_SET_0 59
|
||||
#define LLC_CONN_AC_P_FLAG_SET_P 60
|
||||
#define LLC_CONN_AC_REMOTE_BUSY_SET_0 61
|
||||
#define LLC_CONN_AC_RETRY_CNT_SET_0 62
|
||||
#define LLC_CONN_AC_RETRY_CNT_INC_BY_1 63
|
||||
#define LLC_CONN_AC_Vr_SET_0 64
|
||||
#define LLC_CONN_AC_Vr_INC_BY_1 65
|
||||
#define LLC_CONN_AC_Vs_SET_0 66
|
||||
#define LLC_CONN_AC_Vs_SET_Nr 67
|
||||
#define LLC_CONN_AC_F_FLAG_SET_P 68
|
||||
#define LLC_CONN_AC_STOP_SENDACK_TMR 70
|
||||
#define LLC_CONN_AC_START_SENDACK_TMR_IF_NOT_RUNNING 71
|
||||
|
||||
typedef int (*llc_conn_action_t)(struct sock *sk, struct sk_buff *skb);
|
||||
|
||||
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 llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_data_ind(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_rst_confirm(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
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 llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
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 llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_s_flag_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ac_stop_ack_timer(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_stop_p_timer(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_stop_rej_timer(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_stop_other_timers(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_upd_p_flag(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_data_flag_2(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_data_flag_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_data_flag_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ac_set_p_flag_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_remote_busy_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_retry_cnt_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_cause_flag_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_cause_flag_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_inc_retry_cnt_by_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_vr_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_inc_vr_by_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_vs_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_set_vs_nr(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_disc(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_reset(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb);
|
||||
u8 llc_circular_between(u8 a, u8 b, u8 c);
|
||||
int llc_conn_ac_send_ack_if_needed(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb);
|
||||
|
||||
void llc_conn_busy_tmr_cb(struct timer_list *t);
|
||||
void llc_conn_pf_cycle_tmr_cb(struct timer_list *t);
|
||||
void llc_conn_ack_tmr_cb(struct timer_list *t);
|
||||
void llc_conn_rej_tmr_cb(struct timer_list *t);
|
||||
|
||||
void llc_conn_set_p_flag(struct sock *sk, u8 value);
|
||||
#endif /* LLC_C_AC_H */
|
||||
|
|
@ -1,217 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef LLC_C_EV_H
|
||||
#define LLC_C_EV_H
|
||||
/*
|
||||
* Copyright (c) 1997 by Procom Technology,Inc.
|
||||
* 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
|
||||
#include <net/sock.h>
|
||||
|
||||
/* Connection component state transition event qualifiers */
|
||||
/* Types of events (possible values in 'ev->type') */
|
||||
#define LLC_CONN_EV_TYPE_SIMPLE 1
|
||||
#define LLC_CONN_EV_TYPE_CONDITION 2
|
||||
#define LLC_CONN_EV_TYPE_PRIM 3
|
||||
#define LLC_CONN_EV_TYPE_PDU 4 /* command/response PDU */
|
||||
#define LLC_CONN_EV_TYPE_ACK_TMR 5
|
||||
#define LLC_CONN_EV_TYPE_P_TMR 6
|
||||
#define LLC_CONN_EV_TYPE_REJ_TMR 7
|
||||
#define LLC_CONN_EV_TYPE_BUSY_TMR 8
|
||||
#define LLC_CONN_EV_TYPE_RPT_STATUS 9
|
||||
#define LLC_CONN_EV_TYPE_SENDACK_TMR 10
|
||||
|
||||
#define NBR_CONN_EV 5
|
||||
/* Connection events which cause state transitions when fully qualified */
|
||||
|
||||
#define LLC_CONN_EV_CONN_REQ 1
|
||||
#define LLC_CONN_EV_CONN_RESP 2
|
||||
#define LLC_CONN_EV_DATA_REQ 3
|
||||
#define LLC_CONN_EV_DISC_REQ 4
|
||||
#define LLC_CONN_EV_RESET_REQ 5
|
||||
#define LLC_CONN_EV_RESET_RESP 6
|
||||
#define LLC_CONN_EV_LOCAL_BUSY_DETECTED 7
|
||||
#define LLC_CONN_EV_LOCAL_BUSY_CLEARED 8
|
||||
#define LLC_CONN_EV_RX_BAD_PDU 9
|
||||
#define LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X 10
|
||||
#define LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X 11
|
||||
#define LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X 12
|
||||
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X 13
|
||||
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_UNEXPD_Ns 14
|
||||
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_INVAL_Ns 15
|
||||
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X 16
|
||||
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_UNEXPD_Ns 17
|
||||
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_INVAL_Ns 18
|
||||
#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_X 19
|
||||
#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X 20
|
||||
#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_X 21
|
||||
#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_X 22
|
||||
#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_X 23
|
||||
#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_X 24
|
||||
#define LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X 25
|
||||
#define LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X 26
|
||||
#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_X 27
|
||||
#define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_X 28
|
||||
#define LLC_CONN_EV_RX_XXX_YYY 29
|
||||
#define LLC_CONN_EV_RX_ZZZ_CMD_Pbit_SET_X_INVAL_Nr 30
|
||||
#define LLC_CONN_EV_RX_ZZZ_RSP_Fbit_SET_X_INVAL_Nr 31
|
||||
#define LLC_CONN_EV_P_TMR_EXP 32
|
||||
#define LLC_CONN_EV_ACK_TMR_EXP 33
|
||||
#define LLC_CONN_EV_REJ_TMR_EXP 34
|
||||
#define LLC_CONN_EV_BUSY_TMR_EXP 35
|
||||
#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_1 36
|
||||
#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_0 37
|
||||
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns 38
|
||||
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns 39
|
||||
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns 40
|
||||
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns 41
|
||||
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 42
|
||||
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 43
|
||||
#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 44
|
||||
#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 45
|
||||
#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 46
|
||||
#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 47
|
||||
#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 48
|
||||
#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 49
|
||||
#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 50
|
||||
#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 51
|
||||
#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 52
|
||||
#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 53
|
||||
#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 54
|
||||
#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 55
|
||||
#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 56
|
||||
#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 57
|
||||
#define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_1 58
|
||||
#define LLC_CONN_EV_TX_BUFF_FULL 59
|
||||
|
||||
#define LLC_CONN_EV_INIT_P_F_CYCLE 100
|
||||
/*
|
||||
* Connection event qualifiers; for some events a certain combination of
|
||||
* these qualifiers must be TRUE before event recognized valid for state;
|
||||
* these constants act as indexes into the Event Qualifier function
|
||||
* table
|
||||
*/
|
||||
#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_1 1
|
||||
#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_0 2
|
||||
#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_2 3
|
||||
#define LLC_CONN_EV_QFY_P_FLAG_EQ_1 4
|
||||
#define LLC_CONN_EV_QFY_P_FLAG_EQ_0 5
|
||||
#define LLC_CONN_EV_QFY_P_FLAG_EQ_Fbit 6
|
||||
#define LLC_CONN_EV_QFY_REMOTE_BUSY_EQ_0 7
|
||||
#define LLC_CONN_EV_QFY_RETRY_CNT_LT_N2 8
|
||||
#define LLC_CONN_EV_QFY_RETRY_CNT_GTE_N2 9
|
||||
#define LLC_CONN_EV_QFY_S_FLAG_EQ_1 10
|
||||
#define LLC_CONN_EV_QFY_S_FLAG_EQ_0 11
|
||||
#define LLC_CONN_EV_QFY_INIT_P_F_CYCLE 12
|
||||
|
||||
struct llc_conn_state_ev {
|
||||
u8 type;
|
||||
u8 prim;
|
||||
u8 prim_type;
|
||||
u8 reason;
|
||||
u8 status;
|
||||
u8 ind_prim;
|
||||
u8 cfm_prim;
|
||||
};
|
||||
|
||||
static __inline__ struct llc_conn_state_ev *llc_conn_ev(struct sk_buff *skb)
|
||||
{
|
||||
return (struct llc_conn_state_ev *)skb->cb;
|
||||
}
|
||||
|
||||
typedef int (*llc_conn_ev_t)(struct sock *sk, struct sk_buff *skb);
|
||||
typedef int (*llc_conn_ev_qfyr_t)(struct sock *sk, struct sk_buff *skb);
|
||||
|
||||
int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb);
|
||||
/* NOT_USED functions and their variations */
|
||||
int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb);
|
||||
|
||||
/* Available connection action qualifiers */
|
||||
int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
|
||||
struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb);
|
||||
|
||||
static __inline__ int llc_conn_space(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return atomic_read(&sk->sk_rmem_alloc) + skb->truesize <
|
||||
(unsigned int)sk->sk_rcvbuf;
|
||||
}
|
||||
#endif /* LLC_C_EV_H */
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef LLC_C_ST_H
|
||||
#define LLC_C_ST_H
|
||||
/*
|
||||
* Copyright (c) 1997 by Procom Technology,Inc.
|
||||
* 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
|
||||
#include <net/llc_c_ac.h>
|
||||
#include <net/llc_c_ev.h>
|
||||
|
||||
/* Connection component state management */
|
||||
/* connection states */
|
||||
#define LLC_CONN_OUT_OF_SVC 0 /* prior to allocation */
|
||||
|
||||
#define LLC_CONN_STATE_ADM 1 /* disc, initial state */
|
||||
#define LLC_CONN_STATE_SETUP 2 /* disconnected state */
|
||||
#define LLC_CONN_STATE_NORMAL 3 /* connected state */
|
||||
#define LLC_CONN_STATE_BUSY 4 /* connected state */
|
||||
#define LLC_CONN_STATE_REJ 5 /* connected state */
|
||||
#define LLC_CONN_STATE_AWAIT 6 /* connected state */
|
||||
#define LLC_CONN_STATE_AWAIT_BUSY 7 /* connected state */
|
||||
#define LLC_CONN_STATE_AWAIT_REJ 8 /* connected state */
|
||||
#define LLC_CONN_STATE_D_CONN 9 /* disconnected state */
|
||||
#define LLC_CONN_STATE_RESET 10 /* disconnected state */
|
||||
#define LLC_CONN_STATE_ERROR 11 /* disconnected state */
|
||||
#define LLC_CONN_STATE_TEMP 12 /* disconnected state */
|
||||
|
||||
#define NBR_CONN_STATES 12 /* size of state table */
|
||||
#define NO_STATE_CHANGE 100
|
||||
|
||||
/* Connection state table structure */
|
||||
struct llc_conn_state_trans {
|
||||
llc_conn_ev_t ev;
|
||||
u8 next_state;
|
||||
const llc_conn_ev_qfyr_t *ev_qualifiers;
|
||||
const llc_conn_action_t *ev_actions;
|
||||
};
|
||||
|
||||
struct llc_conn_state {
|
||||
u8 current_state;
|
||||
const struct llc_conn_state_trans **transitions;
|
||||
};
|
||||
|
||||
extern struct llc_conn_state llc_conn_state_table[];
|
||||
#endif /* LLC_C_ST_H */
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef LLC_CONN_H
|
||||
#define LLC_CONN_H
|
||||
/*
|
||||
* Copyright (c) 1997 by Procom Technology, Inc.
|
||||
* 2001, 2002 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
#include <linux/timer.h>
|
||||
#include <net/llc_if.h>
|
||||
#include <net/sock.h>
|
||||
#include <linux/llc.h>
|
||||
|
||||
#define LLC_EVENT 1
|
||||
#define LLC_PACKET 2
|
||||
|
||||
#define LLC2_P_TIME 2
|
||||
#define LLC2_ACK_TIME 1
|
||||
#define LLC2_REJ_TIME 3
|
||||
#define LLC2_BUSY_TIME 3
|
||||
|
||||
struct llc_timer {
|
||||
struct timer_list timer;
|
||||
unsigned long expire; /* timer expire time */
|
||||
};
|
||||
|
||||
struct llc_sock {
|
||||
/* struct sock must be the first member of llc_sock */
|
||||
struct sock sk;
|
||||
struct sockaddr_llc addr; /* address sock is bound to */
|
||||
u8 state; /* state of connection */
|
||||
struct llc_sap *sap; /* pointer to parent SAP */
|
||||
struct llc_addr laddr; /* lsap/mac pair */
|
||||
struct llc_addr daddr; /* dsap/mac pair */
|
||||
struct net_device *dev; /* device to send to remote */
|
||||
netdevice_tracker dev_tracker;
|
||||
u32 copied_seq; /* head of yet unread data */
|
||||
u8 retry_count; /* number of retries */
|
||||
u8 ack_must_be_send;
|
||||
u8 first_pdu_Ns;
|
||||
u8 npta;
|
||||
struct llc_timer ack_timer;
|
||||
struct llc_timer pf_cycle_timer;
|
||||
struct llc_timer rej_sent_timer;
|
||||
struct llc_timer busy_state_timer; /* ind busy clr at remote LLC */
|
||||
u8 vS; /* seq# next in-seq I-PDU tx'd*/
|
||||
u8 vR; /* seq# next in-seq I-PDU rx'd*/
|
||||
u32 n2; /* max nbr re-tx's for timeout*/
|
||||
u32 n1; /* max nbr octets in I PDU */
|
||||
u8 k; /* tx window size; max = 127 */
|
||||
u8 rw; /* rx window size; max = 127 */
|
||||
u8 p_flag; /* state flags */
|
||||
u8 f_flag;
|
||||
u8 s_flag;
|
||||
u8 data_flag;
|
||||
u8 remote_busy_flag;
|
||||
u8 cause_flag;
|
||||
struct sk_buff_head pdu_unack_q; /* PUDs sent/waiting ack */
|
||||
u16 link; /* network layer link number */
|
||||
u8 X; /* a temporary variable */
|
||||
u8 ack_pf; /* this flag indicates what is
|
||||
the P-bit of acknowledge */
|
||||
u8 failed_data_req; /* recognize that already exist a
|
||||
failed llc_data_req_handler
|
||||
(tx_buffer_full or unacceptable
|
||||
state */
|
||||
u8 dec_step;
|
||||
u8 inc_cntr;
|
||||
u8 dec_cntr;
|
||||
u8 connect_step;
|
||||
u8 last_nr; /* NR of last pdu received */
|
||||
u32 rx_pdu_hdr; /* used for saving header of last pdu
|
||||
received and caused sending FRMR.
|
||||
Used for resending FRMR */
|
||||
u32 cmsg_flags;
|
||||
struct hlist_node dev_hash_node;
|
||||
};
|
||||
|
||||
static inline struct llc_sock *llc_sk(const struct sock *sk)
|
||||
{
|
||||
return (struct llc_sock *)sk;
|
||||
}
|
||||
|
||||
static __inline__ void llc_set_backlog_type(struct sk_buff *skb, char type)
|
||||
{
|
||||
skb->cb[sizeof(skb->cb) - 1] = type;
|
||||
}
|
||||
|
||||
static __inline__ char llc_backlog_type(struct sk_buff *skb)
|
||||
{
|
||||
return skb->cb[sizeof(skb->cb) - 1];
|
||||
}
|
||||
|
||||
struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority,
|
||||
struct proto *prot, int kern);
|
||||
void llc_sk_stop_all_timers(struct sock *sk, bool sync);
|
||||
void llc_sk_free(struct sock *sk);
|
||||
|
||||
void llc_sk_reset(struct sock *sk);
|
||||
|
||||
/* Access to a connection */
|
||||
int llc_conn_state_process(struct sock *sk, struct sk_buff *skb);
|
||||
void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
|
||||
void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb);
|
||||
void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit);
|
||||
void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit);
|
||||
int llc_conn_remove_acked_pdus(struct sock *conn, u8 nr, u16 *how_many_unacked);
|
||||
struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr,
|
||||
struct llc_addr *laddr, const struct net *net);
|
||||
void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk);
|
||||
void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk);
|
||||
|
||||
u8 llc_data_accept_state(u8 state);
|
||||
void llc_build_offset_table(void);
|
||||
#endif /* LLC_CONN_H */
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef LLC_IF_H
|
||||
#define LLC_IF_H
|
||||
/*
|
||||
* Copyright (c) 1997 by Procom Technology,Inc.
|
||||
* 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
/* Defines LLC interface to network layer */
|
||||
/* Available primitives */
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/llc.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <net/llc.h>
|
||||
|
||||
#define LLC_DATAUNIT_PRIM 1
|
||||
#define LLC_CONN_PRIM 2
|
||||
#define LLC_DATA_PRIM 3
|
||||
#define LLC_DISC_PRIM 4
|
||||
#define LLC_RESET_PRIM 5
|
||||
#define LLC_FLOWCONTROL_PRIM 6 /* Not supported at this time */
|
||||
#define LLC_DISABLE_PRIM 7
|
||||
#define LLC_XID_PRIM 8
|
||||
#define LLC_TEST_PRIM 9
|
||||
#define LLC_SAP_ACTIVATION 10
|
||||
#define LLC_SAP_DEACTIVATION 11
|
||||
|
||||
#define LLC_NBR_PRIMITIVES 11
|
||||
|
||||
#define LLC_IND 1
|
||||
#define LLC_CONFIRM 2
|
||||
|
||||
/* Primitive type */
|
||||
#define LLC_PRIM_TYPE_REQ 1
|
||||
#define LLC_PRIM_TYPE_IND 2
|
||||
#define LLC_PRIM_TYPE_RESP 3
|
||||
#define LLC_PRIM_TYPE_CONFIRM 4
|
||||
|
||||
/* Reset reasons, remote entity or local LLC */
|
||||
#define LLC_RESET_REASON_REMOTE 1
|
||||
#define LLC_RESET_REASON_LOCAL 2
|
||||
|
||||
/* Disconnect reasons */
|
||||
#define LLC_DISC_REASON_RX_DM_RSP_PDU 0
|
||||
#define LLC_DISC_REASON_RX_DISC_CMD_PDU 1
|
||||
#define LLC_DISC_REASON_ACK_TMR_EXP 2
|
||||
|
||||
/* Confirm reasons */
|
||||
#define LLC_STATUS_CONN 0 /* connect confirm & reset confirm */
|
||||
#define LLC_STATUS_DISC 1 /* connect confirm & reset confirm */
|
||||
#define LLC_STATUS_FAILED 2 /* connect confirm & reset confirm */
|
||||
#define LLC_STATUS_IMPOSSIBLE 3 /* connect confirm */
|
||||
#define LLC_STATUS_RECEIVED 4 /* data conn */
|
||||
#define LLC_STATUS_REMOTE_BUSY 5 /* data conn */
|
||||
#define LLC_STATUS_REFUSE 6 /* data conn */
|
||||
#define LLC_STATUS_CONFLICT 7 /* disconnect conn */
|
||||
#define LLC_STATUS_RESET_DONE 8 /* */
|
||||
|
||||
int llc_establish_connection(struct sock *sk, const u8 *lmac, u8 *dmac,
|
||||
u8 dsap);
|
||||
int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb);
|
||||
int llc_send_disc(struct sock *sk);
|
||||
#endif /* LLC_IF_H */
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef LLC_S_AC_H
|
||||
#define LLC_S_AC_H
|
||||
/*
|
||||
* Copyright (c) 1997 by Procom Technology,Inc.
|
||||
* 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
|
||||
struct llc_sap;
|
||||
struct sk_buff;
|
||||
|
||||
/* SAP component actions */
|
||||
#define SAP_ACT_UNITDATA_IND 1
|
||||
#define SAP_ACT_SEND_UI 2
|
||||
#define SAP_ACT_SEND_XID_C 3
|
||||
#define SAP_ACT_SEND_XID_R 4
|
||||
#define SAP_ACT_SEND_TEST_C 5
|
||||
#define SAP_ACT_SEND_TEST_R 6
|
||||
#define SAP_ACT_REPORT_STATUS 7
|
||||
#define SAP_ACT_XID_IND 8
|
||||
#define SAP_ACT_TEST_IND 9
|
||||
|
||||
/* All action functions must look like this */
|
||||
typedef int (*llc_sap_action_t)(struct llc_sap *sap, struct sk_buff *skb);
|
||||
|
||||
int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_action_report_status(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb);
|
||||
#endif /* LLC_S_AC_H */
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef LLC_S_EV_H
|
||||
#define LLC_S_EV_H
|
||||
/*
|
||||
* Copyright (c) 1997 by Procom Technology,Inc.
|
||||
* 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/llc.h>
|
||||
|
||||
/* Defines SAP component events */
|
||||
/* Types of events (possible values in 'ev->type') */
|
||||
#define LLC_SAP_EV_TYPE_SIMPLE 1
|
||||
#define LLC_SAP_EV_TYPE_CONDITION 2
|
||||
#define LLC_SAP_EV_TYPE_PRIM 3
|
||||
#define LLC_SAP_EV_TYPE_PDU 4 /* command/response PDU */
|
||||
#define LLC_SAP_EV_TYPE_ACK_TMR 5
|
||||
#define LLC_SAP_EV_TYPE_RPT_STATUS 6
|
||||
|
||||
#define LLC_SAP_EV_ACTIVATION_REQ 1
|
||||
#define LLC_SAP_EV_RX_UI 2
|
||||
#define LLC_SAP_EV_UNITDATA_REQ 3
|
||||
#define LLC_SAP_EV_XID_REQ 4
|
||||
#define LLC_SAP_EV_RX_XID_C 5
|
||||
#define LLC_SAP_EV_RX_XID_R 6
|
||||
#define LLC_SAP_EV_TEST_REQ 7
|
||||
#define LLC_SAP_EV_RX_TEST_C 8
|
||||
#define LLC_SAP_EV_RX_TEST_R 9
|
||||
#define LLC_SAP_EV_DEACTIVATION_REQ 10
|
||||
|
||||
struct llc_sap_state_ev {
|
||||
u8 prim;
|
||||
u8 prim_type;
|
||||
u8 type;
|
||||
u8 reason;
|
||||
u8 ind_cfm_flag;
|
||||
struct llc_addr saddr;
|
||||
struct llc_addr daddr;
|
||||
};
|
||||
|
||||
static __inline__ struct llc_sap_state_ev *llc_sap_ev(struct sk_buff *skb)
|
||||
{
|
||||
return (struct llc_sap_state_ev *)skb->cb;
|
||||
}
|
||||
|
||||
struct llc_sap;
|
||||
|
||||
typedef int (*llc_sap_ev_t)(struct llc_sap *sap, struct sk_buff *skb);
|
||||
|
||||
int llc_sap_ev_activation_req(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_ev_xid_req(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_ev_test_req(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct sk_buff *skb);
|
||||
int llc_sap_ev_deactivation_req(struct llc_sap *sap, struct sk_buff *skb);
|
||||
#endif /* LLC_S_EV_H */
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef LLC_S_ST_H
|
||||
#define LLC_S_ST_H
|
||||
/*
|
||||
* Copyright (c) 1997 by Procom Technology,Inc.
|
||||
* 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <net/llc_s_ac.h>
|
||||
#include <net/llc_s_ev.h>
|
||||
|
||||
struct llc_sap_state_trans;
|
||||
|
||||
#define LLC_NR_SAP_STATES 2 /* size of state table */
|
||||
|
||||
/* structures and types */
|
||||
/* SAP state table structure */
|
||||
struct llc_sap_state_trans {
|
||||
llc_sap_ev_t ev;
|
||||
u8 next_state;
|
||||
const llc_sap_action_t *ev_actions;
|
||||
};
|
||||
|
||||
struct llc_sap_state {
|
||||
u8 curr_state;
|
||||
const struct llc_sap_state_trans **transitions;
|
||||
};
|
||||
|
||||
/* only access to SAP state table */
|
||||
extern struct llc_sap_state llc_sap_state_table[LLC_NR_SAP_STATES];
|
||||
#endif /* LLC_S_ST_H */
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef LLC_SAP_H
|
||||
#define LLC_SAP_H
|
||||
|
||||
#include <asm/types.h>
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 by Procom Technology,Inc.
|
||||
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
struct llc_sap;
|
||||
struct net_device;
|
||||
struct sk_buff;
|
||||
struct sock;
|
||||
|
||||
void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
|
||||
void llc_save_primitive(struct sock *sk, struct sk_buff *skb,
|
||||
unsigned char prim);
|
||||
struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev,
|
||||
u8 type, u32 data_size);
|
||||
|
||||
void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb,
|
||||
unsigned char *dmac, unsigned char dsap);
|
||||
void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
|
||||
unsigned char *dmac, unsigned char dsap);
|
||||
#endif /* LLC_SAP_H */
|
||||
|
|
@ -1,10 +1,3 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config LLC
|
||||
tristate
|
||||
|
||||
config LLC2
|
||||
tristate "ANSI/IEEE 802.2 LLC type 2 Support"
|
||||
select LLC
|
||||
help
|
||||
This is a Logical Link Layer type 2, connection oriented support.
|
||||
Select this if you want to have support for PF_LLC sockets.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
###########################################################################
|
||||
# Makefile for the Linux 802.2 LLC (fully-functional) layer.
|
||||
# Makefile for the Linux 802.2 LLC layer.
|
||||
#
|
||||
# Copyright (c) 1997 by Procom Technology,Inc.
|
||||
# 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
|
|
@ -9,11 +9,3 @@
|
|||
obj-$(CONFIG_LLC) += llc.o
|
||||
|
||||
llc-y := llc_core.o llc_input.o llc_output.o
|
||||
|
||||
obj-$(CONFIG_LLC2) += llc2.o
|
||||
|
||||
llc2-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_conn.o llc_c_st.o llc_pdu.o \
|
||||
llc_sap.o llc_s_ac.o llc_s_ev.o llc_s_st.o af_llc.o llc_station.o
|
||||
|
||||
llc2-$(CONFIG_PROC_FS) += llc_proc.o
|
||||
llc2-$(CONFIG_SYSCTL) += sysctl_net_llc.o
|
||||
|
|
|
|||
1304
net/llc/af_llc.c
1304
net/llc/af_llc.c
File diff suppressed because it is too large
Load Diff
1448
net/llc/llc_c_ac.c
1448
net/llc/llc_c_ac.c
File diff suppressed because it is too large
Load Diff
|
|
@ -1,742 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* llc_c_ev.c - Connection component state transition event qualifiers
|
||||
*
|
||||
* A 'state' consists of a number of possible event matching functions,
|
||||
* the actions associated with each being executed when that event is
|
||||
* matched; a 'state machine' accepts events in a serial fashion from an
|
||||
* event queue. Each event is passed to each successive event matching
|
||||
* function until a match is made (the event matching function returns
|
||||
* success, or '0') or the list of event matching functions is exhausted.
|
||||
* If a match is made, the actions associated with the event are executed
|
||||
* and the state is changed to that event's transition state. Before some
|
||||
* events are recognized, even after a match has been made, a certain
|
||||
* number of 'event qualifier' functions must also be executed. If these
|
||||
* all execute successfully, then the event is finally executed.
|
||||
*
|
||||
* These event functions must return 0 for success, to show a matched
|
||||
* event, of 1 if the event does not match. Event qualifier functions
|
||||
* must return a 0 for success or a non-zero for failure. Each function
|
||||
* is simply responsible for verifying one single thing and returning
|
||||
* either a success or failure.
|
||||
*
|
||||
* All of followed event functions are described in 802.2 LLC Protocol
|
||||
* standard document except two functions that we added that will explain
|
||||
* in their comments, at below.
|
||||
*
|
||||
* Copyright (c) 1997 by Procom Technology, Inc.
|
||||
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/llc_conn.h>
|
||||
#include <net/llc_sap.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/llc_c_ac.h>
|
||||
#include <net/llc_c_ev.h>
|
||||
#include <net/llc_pdu.h>
|
||||
|
||||
#if 1
|
||||
#define dprintk(args...) printk(KERN_DEBUG args)
|
||||
#else
|
||||
#define dprintk(args...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* llc_util_ns_inside_rx_window - check if sequence number is in rx window
|
||||
* @ns: sequence number of received pdu.
|
||||
* @vr: sequence number which receiver expects to receive.
|
||||
* @rw: receive window size of receiver.
|
||||
*
|
||||
* Checks if sequence number of received PDU is in range of receive
|
||||
* window. Returns 0 for success, 1 otherwise
|
||||
*/
|
||||
static u16 llc_util_ns_inside_rx_window(u8 ns, u8 vr, u8 rw)
|
||||
{
|
||||
return !llc_circular_between(vr, ns,
|
||||
(vr + rw - 1) % LLC_2_SEQ_NBR_MODULO);
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_util_nr_inside_tx_window - check if sequence number is in tx window
|
||||
* @sk: current connection.
|
||||
* @nr: N(R) of received PDU.
|
||||
*
|
||||
* This routine checks if N(R) of received PDU is in range of transmit
|
||||
* window; on the other hand checks if received PDU acknowledges some
|
||||
* outstanding PDUs that are in transmit window. Returns 0 for success, 1
|
||||
* otherwise.
|
||||
*/
|
||||
static u16 llc_util_nr_inside_tx_window(struct sock *sk, u8 nr)
|
||||
{
|
||||
u8 nr1, nr2;
|
||||
struct sk_buff *skb;
|
||||
struct llc_pdu_sn *pdu;
|
||||
struct llc_sock *llc = llc_sk(sk);
|
||||
int rc = 0;
|
||||
|
||||
if (llc->dev->flags & IFF_LOOPBACK)
|
||||
goto out;
|
||||
rc = 1;
|
||||
if (skb_queue_empty(&llc->pdu_unack_q))
|
||||
goto out;
|
||||
skb = skb_peek(&llc->pdu_unack_q);
|
||||
pdu = llc_pdu_sn_hdr(skb);
|
||||
nr1 = LLC_I_GET_NS(pdu);
|
||||
skb = skb_peek_tail(&llc->pdu_unack_q);
|
||||
pdu = llc_pdu_sn_hdr(skb);
|
||||
nr2 = LLC_I_GET_NS(pdu);
|
||||
rc = !llc_circular_between(nr1, nr, (nr2 + 1) % LLC_2_SEQ_NBR_MODULO);
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
return ev->prim == LLC_CONN_PRIM &&
|
||||
ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
return ev->prim == LLC_DATA_PRIM &&
|
||||
ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
return ev->prim == LLC_DISC_PRIM &&
|
||||
ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
return ev->prim == LLC_RESET_PRIM &&
|
||||
ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
|
||||
ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
|
||||
ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
|
||||
LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
|
||||
LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
|
||||
LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return llc_conn_space(sk, skb) &&
|
||||
LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
|
||||
LLC_I_PF_IS_0(pdu) &&
|
||||
LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return llc_conn_space(sk, skb) &&
|
||||
LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
|
||||
LLC_I_PF_IS_1(pdu) &&
|
||||
LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
const u8 vr = llc_sk(sk)->vR;
|
||||
const u8 ns = LLC_I_GET_NS(pdu);
|
||||
|
||||
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
|
||||
LLC_I_PF_IS_0(pdu) && ns != vr &&
|
||||
!llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
const u8 vr = llc_sk(sk)->vR;
|
||||
const u8 ns = LLC_I_GET_NS(pdu);
|
||||
|
||||
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
|
||||
LLC_I_PF_IS_1(pdu) && ns != vr &&
|
||||
!llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
|
||||
const u8 vr = llc_sk(sk)->vR;
|
||||
const u8 ns = LLC_I_GET_NS(pdu);
|
||||
const u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
|
||||
ns != vr &&
|
||||
llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
|
||||
if (!rc)
|
||||
dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
|
||||
__func__, llc_sk(sk)->state, ns, vr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return llc_conn_space(sk, skb) &&
|
||||
LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
|
||||
LLC_I_PF_IS_0(pdu) &&
|
||||
LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
|
||||
LLC_I_PF_IS_1(pdu) &&
|
||||
LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return llc_conn_space(sk, skb) &&
|
||||
LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
|
||||
LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
const u8 vr = llc_sk(sk)->vR;
|
||||
const u8 ns = LLC_I_GET_NS(pdu);
|
||||
|
||||
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
|
||||
LLC_I_PF_IS_0(pdu) && ns != vr &&
|
||||
!llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
const u8 vr = llc_sk(sk)->vR;
|
||||
const u8 ns = LLC_I_GET_NS(pdu);
|
||||
|
||||
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
|
||||
LLC_I_PF_IS_1(pdu) && ns != vr &&
|
||||
!llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
const u8 vr = llc_sk(sk)->vR;
|
||||
const u8 ns = LLC_I_GET_NS(pdu);
|
||||
|
||||
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
|
||||
!llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
const u8 vr = llc_sk(sk)->vR;
|
||||
const u8 ns = LLC_I_GET_NS(pdu);
|
||||
const u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
|
||||
ns != vr &&
|
||||
llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
|
||||
if (!rc)
|
||||
dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
|
||||
__func__, llc_sk(sk)->state, ns, vr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PF_IS_0(pdu) &&
|
||||
LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PF_IS_1(pdu) &&
|
||||
LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PF_IS_0(pdu) &&
|
||||
LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PF_IS_1(pdu) &&
|
||||
LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PF_IS_0(pdu) &&
|
||||
LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PF_IS_1(pdu) &&
|
||||
LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PF_IS_0(pdu) &&
|
||||
LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PF_IS_1(pdu) &&
|
||||
LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PF_IS_0(pdu) &&
|
||||
LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PF_IS_1(pdu) &&
|
||||
LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return llc_conn_space(sk, skb) &&
|
||||
LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PF_IS_0(pdu) &&
|
||||
LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
return llc_conn_space(sk, skb) &&
|
||||
LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
|
||||
LLC_S_PF_IS_1(pdu) &&
|
||||
LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
|
||||
LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
|
||||
LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
u16 rc = 1;
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
if (LLC_PDU_IS_CMD(pdu)) {
|
||||
if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
|
||||
if (LLC_I_PF_IS_1(pdu))
|
||||
rc = 0;
|
||||
} else if (LLC_PDU_TYPE_IS_U(pdu) && LLC_U_PF_IS_1(pdu))
|
||||
rc = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
u16 rc = 1;
|
||||
const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
if (LLC_PDU_IS_CMD(pdu)) {
|
||||
if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
|
||||
rc = 0;
|
||||
else if (LLC_PDU_TYPE_IS_U(pdu))
|
||||
switch (LLC_U_PDU_CMD(pdu)) {
|
||||
case LLC_2_PDU_CMD_SABME:
|
||||
case LLC_2_PDU_CMD_DISC:
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
u16 rc = 1;
|
||||
const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
if (LLC_PDU_IS_RSP(pdu)) {
|
||||
if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
|
||||
rc = 0;
|
||||
else if (LLC_PDU_TYPE_IS_U(pdu))
|
||||
switch (LLC_U_PDU_RSP(pdu)) {
|
||||
case LLC_2_PDU_RSP_UA:
|
||||
case LLC_2_PDU_RSP_DM:
|
||||
case LLC_2_PDU_RSP_FRMR:
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
u16 rc = 1;
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
const u8 vs = llc_sk(sk)->vS;
|
||||
const u8 nr = LLC_I_GET_NR(pdu);
|
||||
|
||||
if (LLC_PDU_IS_CMD(pdu) &&
|
||||
(LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
|
||||
nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
|
||||
dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
|
||||
__func__, llc_sk(sk)->state, vs, nr);
|
||||
rc = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
u16 rc = 1;
|
||||
const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
const u8 vs = llc_sk(sk)->vS;
|
||||
const u8 nr = LLC_I_GET_NR(pdu);
|
||||
|
||||
if (LLC_PDU_IS_RSP(pdu) &&
|
||||
(LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
|
||||
nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
|
||||
rc = 0;
|
||||
dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
|
||||
__func__, llc_sk(sk)->state, vs, nr);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
return ev->type != LLC_CONN_EV_TYPE_P_TMR;
|
||||
}
|
||||
|
||||
int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
return ev->type != LLC_CONN_EV_TYPE_ACK_TMR;
|
||||
}
|
||||
|
||||
int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
return ev->type != LLC_CONN_EV_TYPE_REJ_TMR;
|
||||
}
|
||||
|
||||
int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
|
||||
}
|
||||
|
||||
int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
|
||||
ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Event qualifier functions
|
||||
*
|
||||
* these functions simply verify the value of a state flag associated with
|
||||
* the connection and return either a 0 for success or a non-zero value
|
||||
* for not-success; verify the event is the type we expect
|
||||
*/
|
||||
int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return llc_sk(sk)->data_flag != 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return llc_sk(sk)->data_flag;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return llc_sk(sk)->data_flag != 2;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return llc_sk(sk)->p_flag != 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_conn_ev_qlfy_last_frame_eq_1 - checks if frame is last in tx window
|
||||
* @sk: current connection structure.
|
||||
* @skb: current event.
|
||||
*
|
||||
* This function determines when frame which is sent, is last frame of
|
||||
* transmit window, if it is then this function return zero else return
|
||||
* one. This function is used for sending last frame of transmit window
|
||||
* as I-format command with p-bit set to one. Returns 0 if frame is last
|
||||
* frame, 1 otherwise.
|
||||
*/
|
||||
int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return !(skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k);
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_conn_ev_qlfy_last_frame_eq_0 - checks if frame isn't last in tx window
|
||||
* @sk: current connection structure.
|
||||
* @skb: current event.
|
||||
*
|
||||
* This function determines when frame which is sent, isn't last frame of
|
||||
* transmit window, if it isn't then this function return zero else return
|
||||
* one. Returns 0 if frame isn't last frame, 1 otherwise.
|
||||
*/
|
||||
int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return llc_sk(sk)->p_flag;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
u8 f_bit;
|
||||
|
||||
llc_pdu_decode_pf_bit(skb, &f_bit);
|
||||
return llc_sk(sk)->p_flag == f_bit ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return llc_sk(sk)->remote_busy_flag;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return !llc_sk(sk)->remote_busy_flag;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return !(llc_sk(sk)->retry_count < llc_sk(sk)->n2);
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return !(llc_sk(sk)->retry_count >= llc_sk(sk)->n2);
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return !llc_sk(sk)->s_flag;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return llc_sk(sk)->s_flag;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return !llc_sk(sk)->cause_flag;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return llc_sk(sk)->cause_flag;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
ev->status = LLC_STATUS_CONN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
ev->status = LLC_STATUS_DISC;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
ev->status = LLC_STATUS_FAILED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
ev->status = LLC_STATUS_REMOTE_BUSY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
ev->status = LLC_STATUS_REFUSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
ev->status = LLC_STATUS_CONFLICT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
ev->status = LLC_STATUS_RESET_DONE;
|
||||
return 0;
|
||||
}
|
||||
4940
net/llc/llc_c_st.c
4940
net/llc/llc_c_st.c
File diff suppressed because it is too large
Load Diff
1025
net/llc/llc_conn.c
1025
net/llc/llc_conn.c
File diff suppressed because it is too large
Load Diff
151
net/llc/llc_if.c
151
net/llc/llc_if.c
|
|
@ -1,151 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* llc_if.c - Defines LLC interface to upper layer
|
||||
*
|
||||
* Copyright (c) 1997 by Procom Technology, Inc.
|
||||
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/errno.h>
|
||||
#include <net/llc_if.h>
|
||||
#include <net/llc_sap.h>
|
||||
#include <net/llc_s_ev.h>
|
||||
#include <net/llc_conn.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/tcp_states.h>
|
||||
|
||||
/**
|
||||
* llc_build_and_send_pkt - Connection data sending for upper layers.
|
||||
* @sk: connection
|
||||
* @skb: packet to send
|
||||
*
|
||||
* This function is called when upper layer wants to send data using
|
||||
* connection oriented communication mode. During sending data, connection
|
||||
* will be locked and received frames and expired timers will be queued.
|
||||
* Returns 0 for success, -ECONNABORTED when the connection already
|
||||
* closed and -EBUSY when sending data is not permitted in this state or
|
||||
* LLC has send an I pdu with p bit set to 1 and is waiting for it's
|
||||
* response.
|
||||
*
|
||||
* This function always consumes a reference to the skb.
|
||||
*/
|
||||
int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_conn_state_ev *ev;
|
||||
int rc = -ECONNABORTED;
|
||||
struct llc_sock *llc = llc_sk(sk);
|
||||
|
||||
if (unlikely(llc->state == LLC_CONN_STATE_ADM))
|
||||
goto out_free;
|
||||
rc = -EBUSY;
|
||||
if (unlikely(llc_data_accept_state(llc->state) || /* data_conn_refuse */
|
||||
llc->p_flag)) {
|
||||
llc->failed_data_req = 1;
|
||||
goto out_free;
|
||||
}
|
||||
ev = llc_conn_ev(skb);
|
||||
ev->type = LLC_CONN_EV_TYPE_PRIM;
|
||||
ev->prim = LLC_DATA_PRIM;
|
||||
ev->prim_type = LLC_PRIM_TYPE_REQ;
|
||||
skb->dev = llc->dev;
|
||||
return llc_conn_state_process(sk, skb);
|
||||
|
||||
out_free:
|
||||
kfree_skb(skb);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_establish_connection - Called by upper layer to establish a conn
|
||||
* @sk: connection
|
||||
* @lmac: local mac address
|
||||
* @dmac: destination mac address
|
||||
* @dsap: destination sap
|
||||
*
|
||||
* Upper layer calls this to establish an LLC connection with a remote
|
||||
* machine. This function packages a proper event and sends it connection
|
||||
* component state machine. Success or failure of connection
|
||||
* establishment will inform to upper layer via calling it's confirm
|
||||
* function and passing proper information.
|
||||
*/
|
||||
int llc_establish_connection(struct sock *sk, const u8 *lmac, u8 *dmac, u8 dsap)
|
||||
{
|
||||
int rc = -EISCONN;
|
||||
struct llc_addr laddr, daddr;
|
||||
struct sk_buff *skb;
|
||||
struct llc_sock *llc = llc_sk(sk);
|
||||
struct sock *existing;
|
||||
|
||||
laddr.lsap = llc->sap->laddr.lsap;
|
||||
daddr.lsap = dsap;
|
||||
memcpy(daddr.mac, dmac, sizeof(daddr.mac));
|
||||
memcpy(laddr.mac, lmac, sizeof(laddr.mac));
|
||||
existing = llc_lookup_established(llc->sap, &daddr, &laddr, sock_net(sk));
|
||||
if (existing) {
|
||||
if (existing->sk_state == TCP_ESTABLISHED) {
|
||||
sk = existing;
|
||||
goto out_put;
|
||||
} else
|
||||
sock_put(existing);
|
||||
}
|
||||
sock_hold(sk);
|
||||
rc = -ENOMEM;
|
||||
skb = alloc_skb(0, GFP_ATOMIC);
|
||||
if (skb) {
|
||||
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
|
||||
|
||||
ev->type = LLC_CONN_EV_TYPE_PRIM;
|
||||
ev->prim = LLC_CONN_PRIM;
|
||||
ev->prim_type = LLC_PRIM_TYPE_REQ;
|
||||
skb_set_owner_w(skb, sk);
|
||||
rc = llc_conn_state_process(sk, skb);
|
||||
}
|
||||
out_put:
|
||||
sock_put(sk);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_send_disc - Called by upper layer to close a connection
|
||||
* @sk: connection to be closed
|
||||
*
|
||||
* Upper layer calls this when it wants to close an established LLC
|
||||
* connection with a remote machine. This function packages a proper event
|
||||
* and sends it to connection component state machine. Returns 0 for
|
||||
* success, 1 otherwise.
|
||||
*/
|
||||
int llc_send_disc(struct sock *sk)
|
||||
{
|
||||
u16 rc = 1;
|
||||
struct llc_conn_state_ev *ev;
|
||||
struct sk_buff *skb;
|
||||
|
||||
sock_hold(sk);
|
||||
if (sk->sk_type != SOCK_STREAM || sk->sk_state != TCP_ESTABLISHED ||
|
||||
llc_sk(sk)->state == LLC_CONN_STATE_ADM ||
|
||||
llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC)
|
||||
goto out;
|
||||
/*
|
||||
* Postpone unassigning the connection from its SAP and returning the
|
||||
* connection until all ACTIONs have been completely executed
|
||||
*/
|
||||
skb = alloc_skb(0, GFP_ATOMIC);
|
||||
if (!skb)
|
||||
goto out;
|
||||
skb_set_owner_w(skb, sk);
|
||||
sk->sk_state = TCP_CLOSING;
|
||||
ev = llc_conn_ev(skb);
|
||||
ev->type = LLC_CONN_EV_TYPE_PRIM;
|
||||
ev->prim = LLC_DISC_PRIM;
|
||||
ev->prim_type = LLC_PRIM_TYPE_REQ;
|
||||
rc = llc_conn_state_process(sk, skb);
|
||||
out:
|
||||
sock_put(sk);
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -11,7 +11,6 @@
|
|||
#include <net/net_namespace.h>
|
||||
#include <net/llc.h>
|
||||
#include <net/llc_pdu.h>
|
||||
#include <net/llc_sap.h>
|
||||
|
||||
#if 0
|
||||
#define dprintk(args...) printk(KERN_DEBUG args)
|
||||
|
|
|
|||
|
|
@ -1,366 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* llc_pdu.c - access to PDU internals
|
||||
*
|
||||
* Copyright (c) 1997 by Procom Technology, Inc.
|
||||
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/llc_pdu.h>
|
||||
|
||||
static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type);
|
||||
static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu);
|
||||
|
||||
void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 pdu_type)
|
||||
{
|
||||
llc_pdu_un_hdr(skb)->ssap |= pdu_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_set_pf_bit - sets poll/final bit in LLC header
|
||||
* @skb: Frame to set bit in
|
||||
* @bit_value: poll/final bit (0 or 1).
|
||||
*
|
||||
* This function sets poll/final bit in LLC header (based on type of PDU).
|
||||
* in I or S pdus, p/f bit is right bit of fourth byte in header. in U
|
||||
* pdus p/f bit is fifth bit of third byte.
|
||||
*/
|
||||
void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value)
|
||||
{
|
||||
u8 pdu_type;
|
||||
struct llc_pdu_sn *pdu;
|
||||
|
||||
llc_pdu_decode_pdu_type(skb, &pdu_type);
|
||||
pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
switch (pdu_type) {
|
||||
case LLC_PDU_TYPE_I:
|
||||
case LLC_PDU_TYPE_S:
|
||||
pdu->ctrl_2 = (pdu->ctrl_2 & 0xFE) | bit_value;
|
||||
break;
|
||||
case LLC_PDU_TYPE_U:
|
||||
pdu->ctrl_1 |= (pdu->ctrl_1 & 0xEF) | (bit_value << 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_decode_pf_bit - extracs poll/final bit from LLC header
|
||||
* @skb: input skb that p/f bit must be extracted from it
|
||||
* @pf_bit: poll/final bit (0 or 1)
|
||||
*
|
||||
* This function extracts poll/final bit from LLC header (based on type of
|
||||
* PDU). In I or S pdus, p/f bit is right bit of fourth byte in header. In
|
||||
* U pdus p/f bit is fifth bit of third byte.
|
||||
*/
|
||||
void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit)
|
||||
{
|
||||
u8 pdu_type;
|
||||
struct llc_pdu_sn *pdu;
|
||||
|
||||
llc_pdu_decode_pdu_type(skb, &pdu_type);
|
||||
pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
switch (pdu_type) {
|
||||
case LLC_PDU_TYPE_I:
|
||||
case LLC_PDU_TYPE_S:
|
||||
*pf_bit = pdu->ctrl_2 & LLC_S_PF_BIT_MASK;
|
||||
break;
|
||||
case LLC_PDU_TYPE_U:
|
||||
*pf_bit = (pdu->ctrl_1 & LLC_U_PF_BIT_MASK) >> 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_init_as_disc_cmd - Builds DISC PDU
|
||||
* @skb: Address of the skb to build
|
||||
* @p_bit: The P bit to set in the PDU
|
||||
*
|
||||
* Builds a pdu frame as a DISC command.
|
||||
*/
|
||||
void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit)
|
||||
{
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
pdu->ctrl_1 = LLC_PDU_TYPE_U;
|
||||
pdu->ctrl_1 |= LLC_2_PDU_CMD_DISC;
|
||||
pdu->ctrl_1 |= ((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_init_as_i_cmd - builds I pdu
|
||||
* @skb: Address of the skb to build
|
||||
* @p_bit: The P bit to set in the PDU
|
||||
* @ns: The sequence number of the data PDU
|
||||
* @nr: The seq. number of the expected I PDU from the remote
|
||||
*
|
||||
* Builds a pdu frame as an I command.
|
||||
*/
|
||||
void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr)
|
||||
{
|
||||
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
pdu->ctrl_1 = LLC_PDU_TYPE_I;
|
||||
pdu->ctrl_2 = 0;
|
||||
pdu->ctrl_2 |= (p_bit & LLC_I_PF_BIT_MASK); /* p/f bit */
|
||||
pdu->ctrl_1 |= (ns << 1) & 0xFE; /* set N(S) in bits 2..8 */
|
||||
pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_init_as_rej_cmd - builds REJ PDU
|
||||
* @skb: Address of the skb to build
|
||||
* @p_bit: The P bit to set in the PDU
|
||||
* @nr: The seq. number of the expected I PDU from the remote
|
||||
*
|
||||
* Builds a pdu frame as a REJ command.
|
||||
*/
|
||||
void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
|
||||
{
|
||||
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
pdu->ctrl_1 = LLC_PDU_TYPE_S;
|
||||
pdu->ctrl_1 |= LLC_2_PDU_CMD_REJ;
|
||||
pdu->ctrl_2 = 0;
|
||||
pdu->ctrl_2 |= p_bit & LLC_S_PF_BIT_MASK;
|
||||
pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */
|
||||
pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_init_as_rnr_cmd - builds RNR pdu
|
||||
* @skb: Address of the skb to build
|
||||
* @p_bit: The P bit to set in the PDU
|
||||
* @nr: The seq. number of the expected I PDU from the remote
|
||||
*
|
||||
* Builds a pdu frame as an RNR command.
|
||||
*/
|
||||
void llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
|
||||
{
|
||||
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
pdu->ctrl_1 = LLC_PDU_TYPE_S;
|
||||
pdu->ctrl_1 |= LLC_2_PDU_CMD_RNR;
|
||||
pdu->ctrl_2 = 0;
|
||||
pdu->ctrl_2 |= p_bit & LLC_S_PF_BIT_MASK;
|
||||
pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */
|
||||
pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_init_as_rr_cmd - Builds RR pdu
|
||||
* @skb: Address of the skb to build
|
||||
* @p_bit: The P bit to set in the PDU
|
||||
* @nr: The seq. number of the expected I PDU from the remote
|
||||
*
|
||||
* Builds a pdu frame as an RR command.
|
||||
*/
|
||||
void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
|
||||
{
|
||||
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
pdu->ctrl_1 = LLC_PDU_TYPE_S;
|
||||
pdu->ctrl_1 |= LLC_2_PDU_CMD_RR;
|
||||
pdu->ctrl_2 = p_bit & LLC_S_PF_BIT_MASK;
|
||||
pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */
|
||||
pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_init_as_sabme_cmd - builds SABME pdu
|
||||
* @skb: Address of the skb to build
|
||||
* @p_bit: The P bit to set in the PDU
|
||||
*
|
||||
* Builds a pdu frame as an SABME command.
|
||||
*/
|
||||
void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit)
|
||||
{
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
pdu->ctrl_1 = LLC_PDU_TYPE_U;
|
||||
pdu->ctrl_1 |= LLC_2_PDU_CMD_SABME;
|
||||
pdu->ctrl_1 |= ((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_init_as_dm_rsp - builds DM response pdu
|
||||
* @skb: Address of the skb to build
|
||||
* @f_bit: The F bit to set in the PDU
|
||||
*
|
||||
* Builds a pdu frame as a DM response.
|
||||
*/
|
||||
void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit)
|
||||
{
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
pdu->ctrl_1 = LLC_PDU_TYPE_U;
|
||||
pdu->ctrl_1 |= LLC_2_PDU_RSP_DM;
|
||||
pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_init_as_frmr_rsp - builds FRMR response PDU
|
||||
* @skb: Address of the frame to build
|
||||
* @prev_pdu: The rejected PDU frame
|
||||
* @f_bit: The F bit to set in the PDU
|
||||
* @vs: tx state vari value for the data link conn at the rejecting LLC
|
||||
* @vr: rx state var value for the data link conn at the rejecting LLC
|
||||
* @vzyxw: completely described in the IEEE Std 802.2 document (Pg 55)
|
||||
*
|
||||
* Builds a pdu frame as a FRMR response.
|
||||
*/
|
||||
void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu,
|
||||
u8 f_bit, u8 vs, u8 vr, u8 vzyxw)
|
||||
{
|
||||
struct llc_frmr_info *frmr_info;
|
||||
u8 prev_pf = 0;
|
||||
u8 *ctrl;
|
||||
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
pdu->ctrl_1 = LLC_PDU_TYPE_U;
|
||||
pdu->ctrl_1 |= LLC_2_PDU_RSP_FRMR;
|
||||
pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
|
||||
|
||||
frmr_info = (struct llc_frmr_info *)&pdu->ctrl_2;
|
||||
ctrl = (u8 *)&prev_pdu->ctrl_1;
|
||||
FRMR_INFO_SET_REJ_CNTRL(frmr_info,ctrl);
|
||||
FRMR_INFO_SET_Vs(frmr_info, vs);
|
||||
FRMR_INFO_SET_Vr(frmr_info, vr);
|
||||
prev_pf = llc_pdu_get_pf_bit(prev_pdu);
|
||||
FRMR_INFO_SET_C_R_BIT(frmr_info, prev_pf);
|
||||
FRMR_INFO_SET_INVALID_PDU_CTRL_IND(frmr_info, vzyxw);
|
||||
FRMR_INFO_SET_INVALID_PDU_INFO_IND(frmr_info, vzyxw);
|
||||
FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw);
|
||||
FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw);
|
||||
FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw);
|
||||
skb_put(skb, sizeof(struct llc_frmr_info));
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_init_as_rr_rsp - builds RR response pdu
|
||||
* @skb: Address of the skb to build
|
||||
* @f_bit: The F bit to set in the PDU
|
||||
* @nr: The seq. number of the expected data PDU from the remote
|
||||
*
|
||||
* Builds a pdu frame as an RR response.
|
||||
*/
|
||||
void llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
|
||||
{
|
||||
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
pdu->ctrl_1 = LLC_PDU_TYPE_S;
|
||||
pdu->ctrl_1 |= LLC_2_PDU_RSP_RR;
|
||||
pdu->ctrl_2 = 0;
|
||||
pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK;
|
||||
pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */
|
||||
pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_init_as_rej_rsp - builds REJ response pdu
|
||||
* @skb: Address of the skb to build
|
||||
* @f_bit: The F bit to set in the PDU
|
||||
* @nr: The seq. number of the expected data PDU from the remote
|
||||
*
|
||||
* Builds a pdu frame as a REJ response.
|
||||
*/
|
||||
void llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
|
||||
{
|
||||
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
pdu->ctrl_1 = LLC_PDU_TYPE_S;
|
||||
pdu->ctrl_1 |= LLC_2_PDU_RSP_REJ;
|
||||
pdu->ctrl_2 = 0;
|
||||
pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK;
|
||||
pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */
|
||||
pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_init_as_rnr_rsp - builds RNR response pdu
|
||||
* @skb: Address of the frame to build
|
||||
* @f_bit: The F bit to set in the PDU
|
||||
* @nr: The seq. number of the expected data PDU from the remote
|
||||
*
|
||||
* Builds a pdu frame as an RNR response.
|
||||
*/
|
||||
void llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
|
||||
{
|
||||
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||
|
||||
pdu->ctrl_1 = LLC_PDU_TYPE_S;
|
||||
pdu->ctrl_1 |= LLC_2_PDU_RSP_RNR;
|
||||
pdu->ctrl_2 = 0;
|
||||
pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK;
|
||||
pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */
|
||||
pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_init_as_ua_rsp - builds UA response pdu
|
||||
* @skb: Address of the frame to build
|
||||
* @f_bit: The F bit to set in the PDU
|
||||
*
|
||||
* Builds a pdu frame as a UA response.
|
||||
*/
|
||||
void llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit)
|
||||
{
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
pdu->ctrl_1 = LLC_PDU_TYPE_U;
|
||||
pdu->ctrl_1 |= LLC_2_PDU_RSP_UA;
|
||||
pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_decode_pdu_type - designates PDU type
|
||||
* @skb: input skb that type of it must be designated.
|
||||
* @type: type of PDU (output argument).
|
||||
*
|
||||
* This function designates type of PDU (I, S or U).
|
||||
*/
|
||||
static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type)
|
||||
{
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
if (pdu->ctrl_1 & 1) {
|
||||
if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U)
|
||||
*type = LLC_PDU_TYPE_U;
|
||||
else
|
||||
*type = LLC_PDU_TYPE_S;
|
||||
} else
|
||||
*type = LLC_PDU_TYPE_I;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_pdu_get_pf_bit - extracts p/f bit of input PDU
|
||||
* @pdu: pointer to LLC header.
|
||||
*
|
||||
* This function extracts p/f bit of input PDU. at first examines type of
|
||||
* PDU and then extracts p/f bit. Returns the p/f bit.
|
||||
*/
|
||||
static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu)
|
||||
{
|
||||
u8 pdu_type;
|
||||
u8 pf_bit = 0;
|
||||
|
||||
if (pdu->ctrl_1 & 1) {
|
||||
if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U)
|
||||
pdu_type = LLC_PDU_TYPE_U;
|
||||
else
|
||||
pdu_type = LLC_PDU_TYPE_S;
|
||||
} else
|
||||
pdu_type = LLC_PDU_TYPE_I;
|
||||
switch (pdu_type) {
|
||||
case LLC_PDU_TYPE_I:
|
||||
case LLC_PDU_TYPE_S:
|
||||
pf_bit = pdu->ctrl_2 & LLC_S_PF_BIT_MASK;
|
||||
break;
|
||||
case LLC_PDU_TYPE_U:
|
||||
pf_bit = (pdu->ctrl_1 & LLC_U_PF_BIT_MASK) >> 4;
|
||||
break;
|
||||
}
|
||||
return pf_bit;
|
||||
}
|
||||
|
|
@ -1,245 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* proc_llc.c - proc interface for LLC
|
||||
*
|
||||
* Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
|
||||
* 2002-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/export.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/llc.h>
|
||||
#include <net/llc_c_ac.h>
|
||||
#include <net/llc_c_ev.h>
|
||||
#include <net/llc_c_st.h>
|
||||
#include <net/llc_conn.h>
|
||||
|
||||
static void llc_ui_format_mac(struct seq_file *seq, const u8 *addr)
|
||||
{
|
||||
seq_printf(seq, "%pM", addr);
|
||||
}
|
||||
|
||||
static struct sock *llc_get_sk_idx(loff_t pos)
|
||||
{
|
||||
struct llc_sap *sap;
|
||||
struct sock *sk = NULL;
|
||||
int i;
|
||||
|
||||
list_for_each_entry_rcu(sap, &llc_sap_list, node) {
|
||||
spin_lock_bh(&sap->sk_lock);
|
||||
for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++) {
|
||||
struct hlist_nulls_head *head = &sap->sk_laddr_hash[i];
|
||||
struct hlist_nulls_node *node;
|
||||
|
||||
sk_nulls_for_each(sk, node, head) {
|
||||
if (!pos)
|
||||
goto found; /* keep the lock */
|
||||
--pos;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&sap->sk_lock);
|
||||
}
|
||||
sk = NULL;
|
||||
found:
|
||||
return sk;
|
||||
}
|
||||
|
||||
static void *llc_seq_start(struct seq_file *seq, loff_t *pos) __acquires(RCU)
|
||||
{
|
||||
loff_t l = *pos;
|
||||
|
||||
rcu_read_lock_bh();
|
||||
return l ? llc_get_sk_idx(--l) : SEQ_START_TOKEN;
|
||||
}
|
||||
|
||||
static struct sock *laddr_hash_next(struct llc_sap *sap, int bucket)
|
||||
{
|
||||
struct hlist_nulls_node *node;
|
||||
struct sock *sk = NULL;
|
||||
|
||||
while (++bucket < LLC_SK_LADDR_HASH_ENTRIES)
|
||||
sk_nulls_for_each(sk, node, &sap->sk_laddr_hash[bucket])
|
||||
goto out;
|
||||
|
||||
out:
|
||||
return sk;
|
||||
}
|
||||
|
||||
static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
struct sock* sk, *next;
|
||||
struct llc_sock *llc;
|
||||
struct llc_sap *sap;
|
||||
|
||||
++*pos;
|
||||
if (v == SEQ_START_TOKEN) {
|
||||
sk = llc_get_sk_idx(0);
|
||||
goto out;
|
||||
}
|
||||
sk = v;
|
||||
next = sk_nulls_next(sk);
|
||||
if (next) {
|
||||
sk = next;
|
||||
goto out;
|
||||
}
|
||||
llc = llc_sk(sk);
|
||||
sap = llc->sap;
|
||||
sk = laddr_hash_next(sap, llc_sk_laddr_hashfn(sap, &llc->laddr));
|
||||
if (sk)
|
||||
goto out;
|
||||
spin_unlock_bh(&sap->sk_lock);
|
||||
list_for_each_entry_continue_rcu(sap, &llc_sap_list, node) {
|
||||
spin_lock_bh(&sap->sk_lock);
|
||||
sk = laddr_hash_next(sap, -1);
|
||||
if (sk)
|
||||
break; /* keep the lock */
|
||||
spin_unlock_bh(&sap->sk_lock);
|
||||
}
|
||||
out:
|
||||
return sk;
|
||||
}
|
||||
|
||||
static void llc_seq_stop(struct seq_file *seq, void *v)
|
||||
{
|
||||
if (v && v != SEQ_START_TOKEN) {
|
||||
struct sock *sk = v;
|
||||
struct llc_sock *llc = llc_sk(sk);
|
||||
struct llc_sap *sap = llc->sap;
|
||||
|
||||
spin_unlock_bh(&sap->sk_lock);
|
||||
}
|
||||
rcu_read_unlock_bh();
|
||||
}
|
||||
|
||||
static int llc_seq_socket_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct sock* sk;
|
||||
struct llc_sock *llc;
|
||||
|
||||
if (v == SEQ_START_TOKEN) {
|
||||
seq_puts(seq, "SKt Mc local_mac_sap remote_mac_sap "
|
||||
" tx_queue rx_queue st uid link\n");
|
||||
goto out;
|
||||
}
|
||||
sk = v;
|
||||
llc = llc_sk(sk);
|
||||
|
||||
/* FIXME: check if the address is multicast */
|
||||
seq_printf(seq, "%2X %2X ", sk->sk_type, 0);
|
||||
|
||||
if (llc->dev)
|
||||
llc_ui_format_mac(seq, llc->dev->dev_addr);
|
||||
else {
|
||||
u8 addr[6] = {0,0,0,0,0,0};
|
||||
llc_ui_format_mac(seq, addr);
|
||||
}
|
||||
seq_printf(seq, "@%02X ", llc->sap->laddr.lsap);
|
||||
llc_ui_format_mac(seq, llc->daddr.mac);
|
||||
seq_printf(seq, "@%02X %8d %8d %2d %3u %4d\n", llc->daddr.lsap,
|
||||
sk_wmem_alloc_get(sk),
|
||||
sk_rmem_alloc_get(sk) - llc->copied_seq,
|
||||
sk->sk_state,
|
||||
from_kuid_munged(seq_user_ns(seq), sk_uid(sk)),
|
||||
llc->link);
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *const llc_conn_state_names[] = {
|
||||
[LLC_CONN_STATE_ADM] = "adm",
|
||||
[LLC_CONN_STATE_SETUP] = "setup",
|
||||
[LLC_CONN_STATE_NORMAL] = "normal",
|
||||
[LLC_CONN_STATE_BUSY] = "busy",
|
||||
[LLC_CONN_STATE_REJ] = "rej",
|
||||
[LLC_CONN_STATE_AWAIT] = "await",
|
||||
[LLC_CONN_STATE_AWAIT_BUSY] = "await_busy",
|
||||
[LLC_CONN_STATE_AWAIT_REJ] = "await_rej",
|
||||
[LLC_CONN_STATE_D_CONN] = "d_conn",
|
||||
[LLC_CONN_STATE_RESET] = "reset",
|
||||
[LLC_CONN_STATE_ERROR] = "error",
|
||||
[LLC_CONN_STATE_TEMP] = "temp",
|
||||
};
|
||||
|
||||
static int llc_seq_core_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct sock* sk;
|
||||
struct llc_sock *llc;
|
||||
|
||||
if (v == SEQ_START_TOKEN) {
|
||||
seq_puts(seq, "Connection list:\n"
|
||||
"dsap state retr txw rxw pf ff sf df rs cs "
|
||||
"tack tpfc trs tbs blog busr\n");
|
||||
goto out;
|
||||
}
|
||||
sk = v;
|
||||
llc = llc_sk(sk);
|
||||
|
||||
seq_printf(seq, " %02X %-10s %3d %3d %3d %2d %2d %2d %2d %2d %2d "
|
||||
"%4d %4d %3d %3d %4d %4d\n",
|
||||
llc->daddr.lsap, llc_conn_state_names[llc->state],
|
||||
llc->retry_count, llc->k, llc->rw, llc->p_flag, llc->f_flag,
|
||||
llc->s_flag, llc->data_flag, llc->remote_busy_flag,
|
||||
llc->cause_flag, timer_pending(&llc->ack_timer.timer),
|
||||
timer_pending(&llc->pf_cycle_timer.timer),
|
||||
timer_pending(&llc->rej_sent_timer.timer),
|
||||
timer_pending(&llc->busy_state_timer.timer),
|
||||
!!sk->sk_backlog.tail, sock_owned_by_user_nocheck(sk));
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations llc_seq_socket_ops = {
|
||||
.start = llc_seq_start,
|
||||
.next = llc_seq_next,
|
||||
.stop = llc_seq_stop,
|
||||
.show = llc_seq_socket_show,
|
||||
};
|
||||
|
||||
static const struct seq_operations llc_seq_core_ops = {
|
||||
.start = llc_seq_start,
|
||||
.next = llc_seq_next,
|
||||
.stop = llc_seq_stop,
|
||||
.show = llc_seq_core_show,
|
||||
};
|
||||
|
||||
static struct proc_dir_entry *llc_proc_dir;
|
||||
|
||||
int __init llc_proc_init(void)
|
||||
{
|
||||
int rc = -ENOMEM;
|
||||
struct proc_dir_entry *p;
|
||||
|
||||
llc_proc_dir = proc_mkdir("llc", init_net.proc_net);
|
||||
if (!llc_proc_dir)
|
||||
goto out;
|
||||
|
||||
p = proc_create_seq("socket", 0444, llc_proc_dir, &llc_seq_socket_ops);
|
||||
if (!p)
|
||||
goto out_socket;
|
||||
|
||||
p = proc_create_seq("core", 0444, llc_proc_dir, &llc_seq_core_ops);
|
||||
if (!p)
|
||||
goto out_core;
|
||||
|
||||
rc = 0;
|
||||
out:
|
||||
return rc;
|
||||
out_core:
|
||||
remove_proc_entry("socket", llc_proc_dir);
|
||||
out_socket:
|
||||
remove_proc_entry("llc", init_net.proc_net);
|
||||
goto out;
|
||||
}
|
||||
|
||||
void llc_proc_exit(void)
|
||||
{
|
||||
remove_proc_entry("socket", llc_proc_dir);
|
||||
remove_proc_entry("core", llc_proc_dir);
|
||||
remove_proc_entry("llc", init_net.proc_net);
|
||||
}
|
||||
|
|
@ -1,220 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* llc_s_ac.c - actions performed during sap state transition.
|
||||
*
|
||||
* Description :
|
||||
* Functions in this module are implementation of sap component actions.
|
||||
* Details of actions can be found in IEEE-802.2 standard document.
|
||||
* All functions have one sap 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>
|
||||
*/
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/llc.h>
|
||||
#include <net/llc_pdu.h>
|
||||
#include <net/llc_s_ac.h>
|
||||
#include <net/llc_s_ev.h>
|
||||
#include <net/llc_sap.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
/**
|
||||
* llc_sap_action_unitdata_ind - forward UI PDU to network layer
|
||||
* @sap: SAP
|
||||
* @skb: the event to forward
|
||||
*
|
||||
* Received a UI PDU from MAC layer; forward to network layer as a
|
||||
* UNITDATA INDICATION; verify our event is the kind we expect
|
||||
*/
|
||||
int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
llc_sap_rtn_pdu(sap, skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int llc_prepare_and_xmit(struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
struct sk_buff *nskb;
|
||||
int rc;
|
||||
|
||||
rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (!nskb)
|
||||
return -ENOMEM;
|
||||
|
||||
if (skb->sk)
|
||||
skb_set_owner_w(nskb, skb->sk);
|
||||
|
||||
return dev_queue_xmit(nskb);
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_sap_action_send_ui - sends UI PDU resp to UNITDATA REQ to MAC layer
|
||||
* @sap: SAP
|
||||
* @skb: the event to send
|
||||
*
|
||||
* Sends a UI PDU to the MAC layer in response to a UNITDATA REQUEST
|
||||
* primitive from the network layer. Verifies event is a primitive type of
|
||||
* event. Verify the primitive is a UNITDATA REQUEST.
|
||||
*/
|
||||
int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(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);
|
||||
|
||||
return llc_prepare_and_xmit(skb);
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_sap_action_send_xid_c - send XID PDU as response to XID REQ
|
||||
* @sap: SAP
|
||||
* @skb: the event to send
|
||||
*
|
||||
* Send a XID command PDU to MAC layer in response to a XID REQUEST
|
||||
* primitive from the network layer. Verify event is a primitive type
|
||||
* event. Verify the primitive is a XID REQUEST.
|
||||
*/
|
||||
int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
|
||||
llc_pdu_header_init(skb, LLC_PDU_TYPE_U_XID, ev->saddr.lsap,
|
||||
ev->daddr.lsap, LLC_PDU_CMD);
|
||||
llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
|
||||
|
||||
return llc_prepare_and_xmit(skb);
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_sap_action_send_xid_r - send XID PDU resp to MAC for received XID
|
||||
* @sap: SAP
|
||||
* @skb: the event to send
|
||||
*
|
||||
* Send XID response PDU to MAC in response to an earlier received XID
|
||||
* command PDU. Verify event is a PDU type event
|
||||
*/
|
||||
int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
|
||||
int rc = 1;
|
||||
struct sk_buff *nskb;
|
||||
|
||||
llc_pdu_decode_sa(skb, mac_da);
|
||||
llc_pdu_decode_da(skb, mac_sa);
|
||||
llc_pdu_decode_ssap(skb, &dsap);
|
||||
nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
|
||||
sizeof(struct llc_xid_info));
|
||||
if (!nskb)
|
||||
goto out;
|
||||
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 = llc_mac_hdr_init(nskb, mac_sa, mac_da);
|
||||
if (likely(!rc))
|
||||
rc = dev_queue_xmit(nskb);
|
||||
else
|
||||
kfree_skb(nskb);
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_sap_action_send_test_c - send TEST PDU to MAC in resp to TEST REQ
|
||||
* @sap: SAP
|
||||
* @skb: the event to send
|
||||
*
|
||||
* Send a TEST command PDU to the MAC layer in response to a TEST REQUEST
|
||||
* primitive from the network layer. Verify event is a primitive type
|
||||
* event; verify the primitive is a TEST REQUEST.
|
||||
*/
|
||||
int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(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);
|
||||
|
||||
return llc_prepare_and_xmit(skb);
|
||||
}
|
||||
|
||||
int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
|
||||
struct sk_buff *nskb;
|
||||
int rc = 1;
|
||||
u32 data_size;
|
||||
|
||||
if (skb->mac_len < ETH_HLEN)
|
||||
return 1;
|
||||
|
||||
llc_pdu_decode_sa(skb, mac_da);
|
||||
llc_pdu_decode_da(skb, mac_sa);
|
||||
llc_pdu_decode_ssap(skb, &dsap);
|
||||
|
||||
/* The test request command is type U (llc_len = 3) */
|
||||
data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
|
||||
nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
|
||||
if (!nskb)
|
||||
goto out;
|
||||
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 = llc_mac_hdr_init(nskb, mac_sa, mac_da);
|
||||
if (likely(!rc))
|
||||
rc = dev_queue_xmit(nskb);
|
||||
else
|
||||
kfree_skb(nskb);
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_sap_action_report_status - report data link status to layer mgmt
|
||||
* @sap: SAP
|
||||
* @skb: the event to send
|
||||
*
|
||||
* Report data link status to layer management. Verify our event is the
|
||||
* kind we expect.
|
||||
*/
|
||||
int llc_sap_action_report_status(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_sap_action_xid_ind - send XID PDU resp to net layer via XID IND
|
||||
* @sap: SAP
|
||||
* @skb: the event to send
|
||||
*
|
||||
* Send a XID response PDU to the network layer via a XID INDICATION
|
||||
* primitive.
|
||||
*/
|
||||
int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
llc_sap_rtn_pdu(sap, skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_sap_action_test_ind - send TEST PDU to net layer via TEST IND
|
||||
* @sap: SAP
|
||||
* @skb: the event to send
|
||||
*
|
||||
* Send a TEST response PDU to the network layer via a TEST INDICATION
|
||||
* primitive. Verify our event is a PDU type event.
|
||||
*/
|
||||
int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
llc_sap_rtn_pdu(sap, skb);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* llc_s_ev.c - Defines SAP component events
|
||||
*
|
||||
* The followed event functions are SAP component events which are described
|
||||
* in 802.2 LLC protocol standard document.
|
||||
*
|
||||
* Copyright (c) 1997 by Procom Technology, Inc.
|
||||
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
#include <linux/socket.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/llc_if.h>
|
||||
#include <net/llc_s_ev.h>
|
||||
#include <net/llc_pdu.h>
|
||||
|
||||
int llc_sap_ev_activation_req(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
|
||||
return ev->type == LLC_SAP_EV_TYPE_SIMPLE &&
|
||||
ev->prim_type == LLC_SAP_EV_ACTIVATION_REQ ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_CMD(pdu) &&
|
||||
LLC_PDU_TYPE_IS_U(pdu) &&
|
||||
LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_UI ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
|
||||
return ev->type == LLC_SAP_EV_TYPE_PRIM &&
|
||||
ev->prim == LLC_DATAUNIT_PRIM &&
|
||||
ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
|
||||
|
||||
}
|
||||
|
||||
int llc_sap_ev_xid_req(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
|
||||
return ev->type == LLC_SAP_EV_TYPE_PRIM &&
|
||||
ev->prim == LLC_XID_PRIM &&
|
||||
ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_CMD(pdu) &&
|
||||
LLC_PDU_TYPE_IS_U(pdu) &&
|
||||
LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_RSP(pdu) &&
|
||||
LLC_PDU_TYPE_IS_U(pdu) &&
|
||||
LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_sap_ev_test_req(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
|
||||
return ev->type == LLC_SAP_EV_TYPE_PRIM &&
|
||||
ev->prim == LLC_TEST_PRIM &&
|
||||
ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_CMD(pdu) &&
|
||||
LLC_PDU_TYPE_IS_U(pdu) &&
|
||||
LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_RSP(pdu) &&
|
||||
LLC_PDU_TYPE_IS_U(pdu) &&
|
||||
LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_TEST ? 0 : 1;
|
||||
}
|
||||
|
||||
int llc_sap_ev_deactivation_req(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
|
||||
return ev->type == LLC_SAP_EV_TYPE_SIMPLE &&
|
||||
ev->prim_type == LLC_SAP_EV_DEACTIVATION_REQ ? 0 : 1;
|
||||
}
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* llc_s_st.c - Defines SAP component state machine transitions.
|
||||
*
|
||||
* The followed transitions are SAP component state machine transitions
|
||||
* which are described in 802.2 LLC protocol standard document.
|
||||
*
|
||||
* Copyright (c) 1997 by Procom Technology, Inc.
|
||||
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <net/llc_if.h>
|
||||
#include <net/llc_s_ev.h>
|
||||
#include <net/llc_s_ac.h>
|
||||
#include <net/llc_s_st.h>
|
||||
|
||||
/* dummy last-transition indicator; common to all state transition groups
|
||||
* last entry for this state
|
||||
* all members are zeros, .bss zeroes it
|
||||
*/
|
||||
static const struct llc_sap_state_trans llc_sap_state_trans_end;
|
||||
|
||||
/* state LLC_SAP_STATE_INACTIVE transition for
|
||||
* LLC_SAP_EV_ACTIVATION_REQ event
|
||||
*/
|
||||
static const llc_sap_action_t llc_sap_inactive_state_actions_1[] = {
|
||||
[0] = llc_sap_action_report_status,
|
||||
[1] = NULL,
|
||||
};
|
||||
|
||||
static const struct llc_sap_state_trans llc_sap_inactive_state_trans_1 = {
|
||||
.ev = llc_sap_ev_activation_req,
|
||||
.next_state = LLC_SAP_STATE_ACTIVE,
|
||||
.ev_actions = llc_sap_inactive_state_actions_1,
|
||||
};
|
||||
|
||||
/* array of pointers; one to each transition */
|
||||
static const struct llc_sap_state_trans *llc_sap_inactive_state_transitions[] = {
|
||||
[0] = &llc_sap_inactive_state_trans_1,
|
||||
[1] = &llc_sap_state_trans_end,
|
||||
};
|
||||
|
||||
/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_UI event */
|
||||
static const llc_sap_action_t llc_sap_active_state_actions_1[] = {
|
||||
[0] = llc_sap_action_unitdata_ind,
|
||||
[1] = NULL,
|
||||
};
|
||||
|
||||
static const struct llc_sap_state_trans llc_sap_active_state_trans_1 = {
|
||||
.ev = llc_sap_ev_rx_ui,
|
||||
.next_state = LLC_SAP_STATE_ACTIVE,
|
||||
.ev_actions = llc_sap_active_state_actions_1,
|
||||
};
|
||||
|
||||
/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_UNITDATA_REQ event */
|
||||
static const llc_sap_action_t llc_sap_active_state_actions_2[] = {
|
||||
[0] = llc_sap_action_send_ui,
|
||||
[1] = NULL,
|
||||
};
|
||||
|
||||
static const struct llc_sap_state_trans llc_sap_active_state_trans_2 = {
|
||||
.ev = llc_sap_ev_unitdata_req,
|
||||
.next_state = LLC_SAP_STATE_ACTIVE,
|
||||
.ev_actions = llc_sap_active_state_actions_2,
|
||||
};
|
||||
|
||||
/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_XID_REQ event */
|
||||
static const llc_sap_action_t llc_sap_active_state_actions_3[] = {
|
||||
[0] = llc_sap_action_send_xid_c,
|
||||
[1] = NULL,
|
||||
};
|
||||
|
||||
static const struct llc_sap_state_trans llc_sap_active_state_trans_3 = {
|
||||
.ev = llc_sap_ev_xid_req,
|
||||
.next_state = LLC_SAP_STATE_ACTIVE,
|
||||
.ev_actions = llc_sap_active_state_actions_3,
|
||||
};
|
||||
|
||||
/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_XID_C event */
|
||||
static const llc_sap_action_t llc_sap_active_state_actions_4[] = {
|
||||
[0] = llc_sap_action_send_xid_r,
|
||||
[1] = NULL,
|
||||
};
|
||||
|
||||
static const struct llc_sap_state_trans llc_sap_active_state_trans_4 = {
|
||||
.ev = llc_sap_ev_rx_xid_c,
|
||||
.next_state = LLC_SAP_STATE_ACTIVE,
|
||||
.ev_actions = llc_sap_active_state_actions_4,
|
||||
};
|
||||
|
||||
/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_XID_R event */
|
||||
static const llc_sap_action_t llc_sap_active_state_actions_5[] = {
|
||||
[0] = llc_sap_action_xid_ind,
|
||||
[1] = NULL,
|
||||
};
|
||||
|
||||
static const struct llc_sap_state_trans llc_sap_active_state_trans_5 = {
|
||||
.ev = llc_sap_ev_rx_xid_r,
|
||||
.next_state = LLC_SAP_STATE_ACTIVE,
|
||||
.ev_actions = llc_sap_active_state_actions_5,
|
||||
};
|
||||
|
||||
/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_TEST_REQ event */
|
||||
static const llc_sap_action_t llc_sap_active_state_actions_6[] = {
|
||||
[0] = llc_sap_action_send_test_c,
|
||||
[1] = NULL,
|
||||
};
|
||||
|
||||
static const struct llc_sap_state_trans llc_sap_active_state_trans_6 = {
|
||||
.ev = llc_sap_ev_test_req,
|
||||
.next_state = LLC_SAP_STATE_ACTIVE,
|
||||
.ev_actions = llc_sap_active_state_actions_6,
|
||||
};
|
||||
|
||||
/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_TEST_C event */
|
||||
static const llc_sap_action_t llc_sap_active_state_actions_7[] = {
|
||||
[0] = llc_sap_action_send_test_r,
|
||||
[1] = NULL,
|
||||
};
|
||||
|
||||
static const struct llc_sap_state_trans llc_sap_active_state_trans_7 = {
|
||||
.ev = llc_sap_ev_rx_test_c,
|
||||
.next_state = LLC_SAP_STATE_ACTIVE,
|
||||
.ev_actions = llc_sap_active_state_actions_7
|
||||
};
|
||||
|
||||
/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_TEST_R event */
|
||||
static const llc_sap_action_t llc_sap_active_state_actions_8[] = {
|
||||
[0] = llc_sap_action_test_ind,
|
||||
[1] = NULL,
|
||||
};
|
||||
|
||||
static const struct llc_sap_state_trans llc_sap_active_state_trans_8 = {
|
||||
.ev = llc_sap_ev_rx_test_r,
|
||||
.next_state = LLC_SAP_STATE_ACTIVE,
|
||||
.ev_actions = llc_sap_active_state_actions_8,
|
||||
};
|
||||
|
||||
/* state LLC_SAP_STATE_ACTIVE transition for
|
||||
* LLC_SAP_EV_DEACTIVATION_REQ event
|
||||
*/
|
||||
static const llc_sap_action_t llc_sap_active_state_actions_9[] = {
|
||||
[0] = llc_sap_action_report_status,
|
||||
[1] = NULL,
|
||||
};
|
||||
|
||||
static const struct llc_sap_state_trans llc_sap_active_state_trans_9 = {
|
||||
.ev = llc_sap_ev_deactivation_req,
|
||||
.next_state = LLC_SAP_STATE_INACTIVE,
|
||||
.ev_actions = llc_sap_active_state_actions_9
|
||||
};
|
||||
|
||||
/* array of pointers; one to each transition */
|
||||
static const struct llc_sap_state_trans *llc_sap_active_state_transitions[] = {
|
||||
[0] = &llc_sap_active_state_trans_2,
|
||||
[1] = &llc_sap_active_state_trans_1,
|
||||
[2] = &llc_sap_active_state_trans_3,
|
||||
[3] = &llc_sap_active_state_trans_4,
|
||||
[4] = &llc_sap_active_state_trans_5,
|
||||
[5] = &llc_sap_active_state_trans_6,
|
||||
[6] = &llc_sap_active_state_trans_7,
|
||||
[7] = &llc_sap_active_state_trans_8,
|
||||
[8] = &llc_sap_active_state_trans_9,
|
||||
[9] = &llc_sap_state_trans_end,
|
||||
};
|
||||
|
||||
/* SAP state transition table */
|
||||
struct llc_sap_state llc_sap_state_table[LLC_NR_SAP_STATES] = {
|
||||
[LLC_SAP_STATE_INACTIVE - 1] = {
|
||||
.curr_state = LLC_SAP_STATE_INACTIVE,
|
||||
.transitions = llc_sap_inactive_state_transitions,
|
||||
},
|
||||
[LLC_SAP_STATE_ACTIVE - 1] = {
|
||||
.curr_state = LLC_SAP_STATE_ACTIVE,
|
||||
.transitions = llc_sap_active_state_transitions,
|
||||
},
|
||||
};
|
||||
|
|
@ -1,437 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* llc_sap.c - driver routines for SAP component.
|
||||
*
|
||||
* Copyright (c) 1997 by Procom Technology, Inc.
|
||||
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
|
||||
#include <net/llc.h>
|
||||
#include <net/llc_if.h>
|
||||
#include <net/llc_conn.h>
|
||||
#include <net/llc_pdu.h>
|
||||
#include <net/llc_sap.h>
|
||||
#include <net/llc_s_ac.h>
|
||||
#include <net/llc_s_ev.h>
|
||||
#include <net/llc_s_st.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/tcp_states.h>
|
||||
#include <linux/llc.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
static int llc_mac_header_len(struct net_device *dev)
|
||||
{
|
||||
switch (dev->type) {
|
||||
case ARPHRD_ETHER:
|
||||
case ARPHRD_LOOPBACK:
|
||||
return LL_RESERVED_SPACE(dev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_alloc_frame - allocates sk_buff for frame
|
||||
* @sk: socket to allocate frame to
|
||||
* @dev: network device this skb will be sent over
|
||||
* @type: pdu type to allocate
|
||||
* @data_size: data size to allocate
|
||||
*
|
||||
* Allocates an sk_buff for frame and initializes sk_buff fields.
|
||||
* Returns allocated skb or %NULL when out of memory.
|
||||
*/
|
||||
struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev,
|
||||
u8 type, u32 data_size)
|
||||
{
|
||||
int hlen = type == LLC_PDU_TYPE_U ? 3 : 4;
|
||||
struct sk_buff *skb;
|
||||
|
||||
hlen += llc_mac_header_len(dev);
|
||||
skb = alloc_skb(hlen + data_size, GFP_ATOMIC);
|
||||
|
||||
if (skb) {
|
||||
skb_reset_mac_header(skb);
|
||||
skb_reserve(skb, hlen);
|
||||
skb_reset_network_header(skb);
|
||||
skb_reset_transport_header(skb);
|
||||
skb->protocol = htons(ETH_P_802_2);
|
||||
skb->dev = dev;
|
||||
if (sk != NULL)
|
||||
skb_set_owner_w(skb, sk);
|
||||
}
|
||||
return skb;
|
||||
}
|
||||
|
||||
void llc_save_primitive(struct sock *sk, struct sk_buff *skb, u8 prim)
|
||||
{
|
||||
struct sockaddr_llc *addr;
|
||||
|
||||
/* save primitive for use by the user. */
|
||||
addr = llc_ui_skb_cb(skb);
|
||||
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
addr->sllc_family = sk->sk_family;
|
||||
addr->sllc_arphrd = skb->dev->type;
|
||||
addr->sllc_test = prim == LLC_TEST_PRIM;
|
||||
addr->sllc_xid = prim == LLC_XID_PRIM;
|
||||
addr->sllc_ua = prim == LLC_DATAUNIT_PRIM;
|
||||
llc_pdu_decode_sa(skb, addr->sllc_mac);
|
||||
llc_pdu_decode_ssap(skb, &addr->sllc_sap);
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_sap_rtn_pdu - Informs upper layer on rx of an UI, XID or TEST pdu.
|
||||
* @sap: pointer to SAP
|
||||
* @skb: received pdu
|
||||
*/
|
||||
void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
switch (LLC_U_PDU_RSP(pdu)) {
|
||||
case LLC_1_PDU_CMD_TEST:
|
||||
ev->prim = LLC_TEST_PRIM; break;
|
||||
case LLC_1_PDU_CMD_XID:
|
||||
ev->prim = LLC_XID_PRIM; break;
|
||||
case LLC_1_PDU_CMD_UI:
|
||||
ev->prim = LLC_DATAUNIT_PRIM; break;
|
||||
}
|
||||
ev->ind_cfm_flag = LLC_IND;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_find_sap_trans - finds transition for event
|
||||
* @sap: pointer to SAP
|
||||
* @skb: happened event
|
||||
*
|
||||
* This function finds transition that matches with happened event.
|
||||
* Returns the pointer to found transition on success or %NULL for
|
||||
* failure.
|
||||
*/
|
||||
static const struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
int i = 0;
|
||||
const struct llc_sap_state_trans *rc = NULL;
|
||||
const struct llc_sap_state_trans **next_trans;
|
||||
struct llc_sap_state *curr_state = &llc_sap_state_table[sap->state - 1];
|
||||
/*
|
||||
* Search thru events for this state until list exhausted or until
|
||||
* its obvious the event is not valid for the current state
|
||||
*/
|
||||
for (next_trans = curr_state->transitions; next_trans[i]->ev; i++)
|
||||
if (!next_trans[i]->ev(sap, skb)) {
|
||||
rc = next_trans[i]; /* got event match; return it */
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_exec_sap_trans_actions - execute actions related to event
|
||||
* @sap: pointer to SAP
|
||||
* @trans: pointer to transition that it's actions must be performed
|
||||
* @skb: happened event.
|
||||
*
|
||||
* This function executes actions that is related to happened event.
|
||||
* Returns 0 for success and 1 for failure of at least one action.
|
||||
*/
|
||||
static int llc_exec_sap_trans_actions(struct llc_sap *sap,
|
||||
const struct llc_sap_state_trans *trans,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
int rc = 0;
|
||||
const llc_sap_action_t *next_action = trans->ev_actions;
|
||||
|
||||
for (; next_action && *next_action; next_action++)
|
||||
if ((*next_action)(sap, skb))
|
||||
rc = 1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_sap_next_state - finds transition, execs actions & change SAP state
|
||||
* @sap: pointer to SAP
|
||||
* @skb: happened event
|
||||
*
|
||||
* This function finds transition that matches with happened event, then
|
||||
* executes related actions and finally changes state of SAP. It returns
|
||||
* 0 on success and 1 for failure.
|
||||
*/
|
||||
static int llc_sap_next_state(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
const struct llc_sap_state_trans *trans;
|
||||
int rc = 1;
|
||||
|
||||
if (sap->state > LLC_NR_SAP_STATES)
|
||||
goto out;
|
||||
trans = llc_find_sap_trans(sap, skb);
|
||||
if (!trans)
|
||||
goto out;
|
||||
/*
|
||||
* Got the state to which we next transition; perform the actions
|
||||
* associated with this transition before actually transitioning to the
|
||||
* next state
|
||||
*/
|
||||
rc = llc_exec_sap_trans_actions(sap, trans, skb);
|
||||
if (rc)
|
||||
goto out;
|
||||
/*
|
||||
* Transition SAP to next state if all actions execute successfully
|
||||
*/
|
||||
sap->state = trans->next_state;
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_sap_state_process - sends event to SAP state machine
|
||||
* @sap: sap to use
|
||||
* @skb: pointer to occurred event
|
||||
*
|
||||
* After executing actions of the event, upper layer will be indicated
|
||||
* if needed(on receiving an UI frame). sk can be null for the
|
||||
* datalink_proto case.
|
||||
*
|
||||
* This function always consumes a reference to the skb.
|
||||
*/
|
||||
static void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
|
||||
ev->ind_cfm_flag = 0;
|
||||
llc_sap_next_state(sap, skb);
|
||||
|
||||
if (ev->ind_cfm_flag == LLC_IND && skb->sk->sk_state != TCP_LISTEN) {
|
||||
llc_save_primitive(skb->sk, skb, ev->prim);
|
||||
|
||||
/* queue skb to the user. */
|
||||
if (sock_queue_rcv_skb(skb->sk, skb) == 0)
|
||||
return;
|
||||
}
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_build_and_send_test_pkt - TEST interface for upper layers.
|
||||
* @sap: sap to use
|
||||
* @skb: packet to send
|
||||
* @dmac: destination mac address
|
||||
* @dsap: destination sap
|
||||
*
|
||||
* This function is called when upper layer wants to send a TEST pdu.
|
||||
* Returns 0 for success, 1 otherwise.
|
||||
*/
|
||||
void llc_build_and_send_test_pkt(struct llc_sap *sap,
|
||||
struct sk_buff *skb, u8 *dmac, u8 dsap)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
|
||||
ev->saddr.lsap = sap->laddr.lsap;
|
||||
ev->daddr.lsap = dsap;
|
||||
memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
|
||||
memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
|
||||
|
||||
ev->type = LLC_SAP_EV_TYPE_PRIM;
|
||||
ev->prim = LLC_TEST_PRIM;
|
||||
ev->prim_type = LLC_PRIM_TYPE_REQ;
|
||||
llc_sap_state_process(sap, skb);
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_build_and_send_xid_pkt - XID interface for upper layers
|
||||
* @sap: sap to use
|
||||
* @skb: packet to send
|
||||
* @dmac: destination mac address
|
||||
* @dsap: destination sap
|
||||
*
|
||||
* This function is called when upper layer wants to send a XID pdu.
|
||||
* Returns 0 for success, 1 otherwise.
|
||||
*/
|
||||
void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
|
||||
u8 *dmac, u8 dsap)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
|
||||
ev->saddr.lsap = sap->laddr.lsap;
|
||||
ev->daddr.lsap = dsap;
|
||||
memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
|
||||
memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
|
||||
|
||||
ev->type = LLC_SAP_EV_TYPE_PRIM;
|
||||
ev->prim = LLC_XID_PRIM;
|
||||
ev->prim_type = LLC_PRIM_TYPE_REQ;
|
||||
llc_sap_state_process(sap, skb);
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_sap_rcv - sends received pdus to the sap state machine
|
||||
* @sap: current sap component structure.
|
||||
* @skb: received frame.
|
||||
* @sk: socket to associate to frame
|
||||
*
|
||||
* Sends received pdus to the sap state machine.
|
||||
*/
|
||||
static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb,
|
||||
struct sock *sk)
|
||||
{
|
||||
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
|
||||
|
||||
ev->type = LLC_SAP_EV_TYPE_PDU;
|
||||
ev->reason = 0;
|
||||
skb_orphan(skb);
|
||||
sock_hold(sk);
|
||||
skb->sk = sk;
|
||||
skb->destructor = sock_efree;
|
||||
llc_sap_state_process(sap, skb);
|
||||
}
|
||||
|
||||
static inline bool llc_dgram_match(const struct llc_sap *sap,
|
||||
const struct llc_addr *laddr,
|
||||
const struct sock *sk,
|
||||
const struct net *net)
|
||||
{
|
||||
struct llc_sock *llc = llc_sk(sk);
|
||||
|
||||
return sk->sk_type == SOCK_DGRAM &&
|
||||
net_eq(sock_net(sk), net) &&
|
||||
llc->laddr.lsap == laddr->lsap &&
|
||||
ether_addr_equal(llc->laddr.mac, laddr->mac);
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_lookup_dgram - Finds dgram socket for the local sap/mac
|
||||
* @sap: SAP
|
||||
* @laddr: address of local LLC (MAC + SAP)
|
||||
* @net: netns to look up a socket in
|
||||
*
|
||||
* Search socket list of the SAP and finds connection using the local
|
||||
* mac, and local sap. Returns pointer for socket found, %NULL otherwise.
|
||||
*/
|
||||
static struct sock *llc_lookup_dgram(struct llc_sap *sap,
|
||||
const struct llc_addr *laddr,
|
||||
const struct net *net)
|
||||
{
|
||||
struct sock *rc;
|
||||
struct hlist_nulls_node *node;
|
||||
int slot = llc_sk_laddr_hashfn(sap, laddr);
|
||||
struct hlist_nulls_head *laddr_hb = &sap->sk_laddr_hash[slot];
|
||||
|
||||
rcu_read_lock_bh();
|
||||
again:
|
||||
sk_nulls_for_each_rcu(rc, node, laddr_hb) {
|
||||
if (llc_dgram_match(sap, laddr, rc, net)) {
|
||||
/* Extra checks required by SLAB_TYPESAFE_BY_RCU */
|
||||
if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt)))
|
||||
goto again;
|
||||
if (unlikely(llc_sk(rc)->sap != sap ||
|
||||
!llc_dgram_match(sap, laddr, rc, net))) {
|
||||
sock_put(rc);
|
||||
continue;
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
rc = NULL;
|
||||
/*
|
||||
* if the nulls value we got at the end of this lookup is
|
||||
* not the expected one, we must restart lookup.
|
||||
* We probably met an item that was moved to another chain.
|
||||
*/
|
||||
if (unlikely(get_nulls_value(node) != slot))
|
||||
goto again;
|
||||
found:
|
||||
rcu_read_unlock_bh();
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline bool llc_mcast_match(const struct llc_sap *sap,
|
||||
const struct llc_addr *laddr,
|
||||
const struct sk_buff *skb,
|
||||
const struct sock *sk)
|
||||
{
|
||||
struct llc_sock *llc = llc_sk(sk);
|
||||
|
||||
return sk->sk_type == SOCK_DGRAM &&
|
||||
llc->laddr.lsap == laddr->lsap &&
|
||||
llc->dev == skb->dev;
|
||||
}
|
||||
|
||||
static void llc_do_mcast(struct llc_sap *sap, struct sk_buff *skb,
|
||||
struct sock **stack, int count)
|
||||
{
|
||||
struct sk_buff *skb1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
skb1 = skb_clone(skb, GFP_ATOMIC);
|
||||
if (!skb1) {
|
||||
sock_put(stack[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
llc_sap_rcv(sap, skb1, stack[i]);
|
||||
sock_put(stack[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_sap_mcast - Deliver multicast PDU's to all matching datagram sockets.
|
||||
* @sap: SAP
|
||||
* @laddr: address of local LLC (MAC + SAP)
|
||||
* @skb: PDU to deliver
|
||||
*
|
||||
* Search socket list of the SAP and finds connections with same sap.
|
||||
* Deliver clone to each.
|
||||
*/
|
||||
static void llc_sap_mcast(struct llc_sap *sap,
|
||||
const struct llc_addr *laddr,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
int i = 0;
|
||||
struct sock *sk;
|
||||
struct sock *stack[256 / sizeof(struct sock *)];
|
||||
struct llc_sock *llc;
|
||||
struct hlist_head *dev_hb = llc_sk_dev_hash(sap, skb->dev->ifindex);
|
||||
|
||||
spin_lock_bh(&sap->sk_lock);
|
||||
hlist_for_each_entry(llc, dev_hb, dev_hash_node) {
|
||||
|
||||
sk = &llc->sk;
|
||||
|
||||
if (!llc_mcast_match(sap, laddr, skb, sk))
|
||||
continue;
|
||||
|
||||
sock_hold(sk);
|
||||
if (i < ARRAY_SIZE(stack))
|
||||
stack[i++] = sk;
|
||||
else {
|
||||
llc_do_mcast(sap, skb, stack, i);
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&sap->sk_lock);
|
||||
|
||||
llc_do_mcast(sap, skb, stack, i);
|
||||
}
|
||||
|
||||
|
||||
void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb)
|
||||
{
|
||||
struct llc_addr laddr;
|
||||
|
||||
llc_pdu_decode_da(skb, laddr.mac);
|
||||
llc_pdu_decode_dsap(skb, &laddr.lsap);
|
||||
|
||||
if (is_multicast_ether_addr(laddr.mac)) {
|
||||
llc_sap_mcast(sap, &laddr, skb);
|
||||
kfree_skb(skb);
|
||||
} else {
|
||||
struct sock *sk = llc_lookup_dgram(sap, &laddr, dev_net(skb->dev));
|
||||
if (sk) {
|
||||
llc_sap_rcv(sap, skb, sk);
|
||||
sock_put(sk);
|
||||
} else
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* llc_station.c - station component of LLC
|
||||
*
|
||||
* Copyright (c) 1997 by Procom Technology, Inc.
|
||||
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <net/llc.h>
|
||||
#include <net/llc_sap.h>
|
||||
#include <net/llc_conn.h>
|
||||
#include <net/llc_c_ac.h>
|
||||
#include <net/llc_s_ac.h>
|
||||
#include <net/llc_c_ev.h>
|
||||
#include <net/llc_c_st.h>
|
||||
#include <net/llc_s_ev.h>
|
||||
#include <net/llc_s_st.h>
|
||||
#include <net/llc_pdu.h>
|
||||
|
||||
static int llc_stat_ev_rx_null_dsap_xid_c(struct sk_buff *skb)
|
||||
{
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_CMD(pdu) && /* command PDU */
|
||||
LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */
|
||||
LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID &&
|
||||
!pdu->dsap; /* NULL DSAP value */
|
||||
}
|
||||
|
||||
static int llc_stat_ev_rx_null_dsap_test_c(struct sk_buff *skb)
|
||||
{
|
||||
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
|
||||
|
||||
return LLC_PDU_IS_CMD(pdu) && /* command PDU */
|
||||
LLC_PDU_TYPE_IS_U(pdu) && /* U type PDU */
|
||||
LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST &&
|
||||
!pdu->dsap; /* NULL DSAP */
|
||||
}
|
||||
|
||||
static int llc_station_ac_send_xid_r(struct sk_buff *skb)
|
||||
{
|
||||
u8 mac_da[ETH_ALEN], dsap;
|
||||
int rc = 1;
|
||||
struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
|
||||
sizeof(struct llc_xid_info));
|
||||
|
||||
if (!nskb)
|
||||
goto out;
|
||||
llc_pdu_decode_sa(skb, mac_da);
|
||||
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);
|
||||
rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da);
|
||||
if (unlikely(rc))
|
||||
goto free;
|
||||
dev_queue_xmit(nskb);
|
||||
out:
|
||||
return rc;
|
||||
free:
|
||||
kfree_skb(nskb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
static int llc_station_ac_send_test_r(struct sk_buff *skb)
|
||||
{
|
||||
u8 mac_da[ETH_ALEN], dsap;
|
||||
int rc = 1;
|
||||
u32 data_size;
|
||||
struct sk_buff *nskb;
|
||||
|
||||
if (skb->mac_len < ETH_HLEN)
|
||||
goto out;
|
||||
|
||||
/* The test request command is type U (llc_len = 3) */
|
||||
data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
|
||||
nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
|
||||
|
||||
if (!nskb)
|
||||
goto out;
|
||||
llc_pdu_decode_sa(skb, mac_da);
|
||||
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);
|
||||
rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da);
|
||||
if (unlikely(rc))
|
||||
goto free;
|
||||
dev_queue_xmit(nskb);
|
||||
out:
|
||||
return rc;
|
||||
free:
|
||||
kfree_skb(nskb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**
|
||||
* llc_station_rcv - send received pdu to the station state machine
|
||||
* @skb: received frame.
|
||||
*
|
||||
* Sends data unit to station state machine.
|
||||
*/
|
||||
static void llc_station_rcv(struct sk_buff *skb)
|
||||
{
|
||||
if (llc_stat_ev_rx_null_dsap_xid_c(skb))
|
||||
llc_station_ac_send_xid_r(skb);
|
||||
else if (llc_stat_ev_rx_null_dsap_test_c(skb))
|
||||
llc_station_ac_send_test_r(skb);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
void __init llc_station_init(void)
|
||||
{
|
||||
llc_set_station_handler(llc_station_rcv);
|
||||
}
|
||||
|
||||
void llc_station_exit(void)
|
||||
{
|
||||
llc_set_station_handler(NULL);
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* sysctl_net_llc.c: sysctl interface to LLC net subsystem.
|
||||
*
|
||||
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
*/
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/llc.h>
|
||||
|
||||
static struct ctl_table llc2_timeout_table[] = {
|
||||
{
|
||||
.procname = "ack",
|
||||
.data = &sysctl_llc2_ack_timeout,
|
||||
.maxlen = sizeof(sysctl_llc2_ack_timeout),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "busy",
|
||||
.data = &sysctl_llc2_busy_timeout,
|
||||
.maxlen = sizeof(sysctl_llc2_busy_timeout),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "p",
|
||||
.data = &sysctl_llc2_p_timeout,
|
||||
.maxlen = sizeof(sysctl_llc2_p_timeout),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
{
|
||||
.procname = "rej",
|
||||
.data = &sysctl_llc2_rej_timeout,
|
||||
.maxlen = sizeof(sysctl_llc2_rej_timeout),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
};
|
||||
|
||||
static struct ctl_table_header *llc2_timeout_header;
|
||||
static struct ctl_table_header *llc_station_header;
|
||||
|
||||
int __init llc_sysctl_init(void)
|
||||
{
|
||||
static struct ctl_table empty[1] = {};
|
||||
llc2_timeout_header = register_net_sysctl(&init_net, "net/llc/llc2/timeout", llc2_timeout_table);
|
||||
llc_station_header = register_net_sysctl_sz(&init_net, "net/llc/station", empty, 0);
|
||||
|
||||
if (!llc2_timeout_header || !llc_station_header) {
|
||||
llc_sysctl_exit();
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void llc_sysctl_exit(void)
|
||||
{
|
||||
if (llc2_timeout_header) {
|
||||
unregister_net_sysctl_table(llc2_timeout_header);
|
||||
llc2_timeout_header = NULL;
|
||||
}
|
||||
if (llc_station_header) {
|
||||
unregister_net_sysctl_table(llc_station_header);
|
||||
llc_station_header = NULL;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user