Commit 551e7a61 authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/BAK-net-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents 10715329 8d01fbf7
No related merge requests found
......@@ -149,6 +149,8 @@ csum_partial:
30: subl $2, %ecx
ja 20b
je 32f
addl $2, %ecx
jz 80f
movzbl (%esi),%ebx # csumming 1 byte, 2-aligned
addl %ebx, %eax
adcl $0, %eax
......
......@@ -3337,8 +3337,10 @@ static int tg3_reset_hw(struct tg3 *tp)
/* Clear statistics/status block in chip, and status block in ram. */
for (i = NIC_SRAM_STATS_BLK;
i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
i += sizeof(u32))
i += sizeof(u32)) {
tg3_write_mem(tp, i, 0);
udelay(40);
}
memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
/* This value is determined during the probe time DMA
......
......@@ -43,12 +43,57 @@ enum ip_conntrack_status {
IPS_ASSURED = (1 << IPS_ASSURED_BIT),
};
#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
#include <linux/netfilter_ipv4/ip_conntrack_icmp.h>
/* per conntrack: protocol private data */
union ip_conntrack_proto {
/* insert conntrack proto private data here */
struct ip_ct_tcp tcp;
struct ip_ct_icmp icmp;
};
union ip_conntrack_expect_proto {
/* insert expect proto private data here */
};
/* Add protocol helper include file here */
#include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
#include <linux/netfilter_ipv4/ip_conntrack_irc.h>
/* per expectation: application helper private data */
union ip_conntrack_expect_help {
/* insert conntrack helper private data (expect) here */
struct ip_ct_ftp_expect exp_ftp_info;
struct ip_ct_irc_expect exp_irc_info;
#ifdef CONFIG_IP_NF_NAT_NEEDED
union {
/* insert nat helper private data (expect) here */
} nat;
#endif
};
/* per conntrack: application helper private data */
union ip_conntrack_help {
/* insert conntrack helper private data (master) here */
struct ip_ct_ftp_master ct_ftp_info;
struct ip_ct_irc_master ct_irc_info;
};
#ifdef CONFIG_IP_NF_NAT_NEEDED
#include <linux/netfilter_ipv4/ip_nat.h>
/* per conntrack: nat application helper private data */
union ip_conntrack_nat_help {
/* insert nat helper private data here */
};
#endif
#ifdef __KERNEL__
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
#include <linux/netfilter_ipv4/ip_conntrack_icmp.h>
#ifdef CONFIG_NF_DEBUG
#define IP_NF_ASSERT(x) \
......@@ -63,19 +108,14 @@ do { \
#define IP_NF_ASSERT(x)
#endif
#ifdef CONFIG_IP_NF_NAT_NEEDED
#include <linux/netfilter_ipv4/ip_nat.h>
#endif
/* Add protocol helper include file here */
#include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
#include <linux/netfilter_ipv4/ip_conntrack_irc.h>
struct ip_conntrack_expect
{
/* Internal linked list (global expectation list) */
struct list_head list;
/* reference count */
atomic_t use;
/* expectation list for this master */
struct list_head expected_list;
......@@ -103,19 +143,12 @@ struct ip_conntrack_expect
/* At which sequence number did this expectation occur */
u_int32_t seq;
union {
/* insert conntrack helper private data (expect) here */
struct ip_ct_ftp_expect exp_ftp_info;
struct ip_ct_irc_expect exp_irc_info;
#ifdef CONFIG_IP_NF_NAT_NEEDED
union {
/* insert nat helper private data (expect) here */
} nat;
#endif
} help;
union ip_conntrack_expect_proto proto;
union ip_conntrack_expect_help help;
};
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
struct ip_conntrack
{
/* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
......@@ -150,23 +183,14 @@ struct ip_conntrack
/* Storage reserved for other modules: */
union {
struct ip_ct_tcp tcp;
struct ip_ct_icmp icmp;
} proto;
union ip_conntrack_proto proto;
union {
/* insert conntrack helper private data (master) here */
struct ip_ct_ftp_master ct_ftp_info;
struct ip_ct_irc_master ct_irc_info;
} help;
union ip_conntrack_help help;
#ifdef CONFIG_IP_NF_NAT_NEEDED
struct {
struct ip_nat_info info;
union {
/* insert nat helper private data here */
} help;
union ip_conntrack_nat_help help;
#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
int masq_index;
......@@ -195,6 +219,16 @@ ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple,
extern struct ip_conntrack *
ip_conntrack_get(struct sk_buff *skb, enum ip_conntrack_info *ctinfo);
/* decrement reference count on a conntrack */
extern inline void ip_conntrack_put(struct ip_conntrack *ct);
/* find unconfirmed expectation based on tuple */
struct ip_conntrack_expect *
ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple);
/* decrement reference count on an expectation */
void ip_conntrack_expect_put(struct ip_conntrack_expect *exp);
extern struct module *ip_conntrack_module;
extern int invert_tuplepr(struct ip_conntrack_tuple *inverse,
......
......@@ -45,7 +45,7 @@ static inline int ip_conntrack_confirm(struct sk_buff *skb)
}
extern struct list_head *ip_conntrack_hash;
extern struct list_head expect_list;
extern struct list_head ip_conntrack_expect_list;
DECLARE_RWLOCK_EXTERN(ip_conntrack_lock);
#endif /* _IP_CONNTRACK_CORE_H */
......@@ -2,9 +2,7 @@
#define _IP_CONNTRACK_FTP_H
/* FTP tracking. */
#ifndef __KERNEL__
#error Only in kernel.
#endif
#ifdef __KERNEL__
#include <linux/netfilter_ipv4/lockhelp.h>
......@@ -13,6 +11,8 @@ DECLARE_LOCK_EXTERN(ip_ftp_lock);
#define FTP_PORT 21
#endif /* __KERNEL__ */
enum ip_ct_ftp_type
{
/* PORT command from client */
......
......@@ -14,22 +14,6 @@
#ifndef _IP_CONNTRACK_IRC_H
#define _IP_CONNTRACK_IRC_H
#ifndef __KERNEL__
#error Only in kernel.
#endif
#include <linux/netfilter_ipv4/lockhelp.h>
#define IRC_PORT 6667
struct dccproto {
char* match;
int matchlen;
};
/* Protects irc part of conntracks */
DECLARE_LOCK_EXTERN(ip_irc_lock);
/* We record seq number and length of irc ip/port text here: all in
host order. */
......@@ -46,4 +30,21 @@ struct ip_ct_irc_expect
struct ip_ct_irc_master {
};
#ifdef __KERNEL__
#include <linux/netfilter_ipv4/lockhelp.h>
#define IRC_PORT 6667
struct dccproto {
char* match;
int matchlen;
};
/* Protects irc part of conntracks */
DECLARE_LOCK_EXTERN(ip_irc_lock);
#endif /* __KERNEL__ */
#endif /* _IP_CONNTRACK_IRC_H */
......@@ -2,10 +2,6 @@
#define _IP_CONNTRACK_TCP_H
/* TCP tracking. */
#ifndef __KERNEL__
#error Only in kernel.
#endif
enum tcp_conntrack {
TCP_CONNTRACK_NONE,
TCP_CONNTRACK_ESTABLISHED,
......
......@@ -60,22 +60,6 @@ struct ip_nat_multi_range
struct ip_nat_range range[1];
};
#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/netfilter_ipv4/lockhelp.h>
/* Protects NAT hash tables, and NAT-private part of conntracks. */
DECLARE_RWLOCK_EXTERN(ip_nat_lock);
/* Hashes for by-source and IP/protocol. */
struct ip_nat_hash
{
struct list_head list;
/* conntrack we're embedded in: NULL if not in hash. */
struct ip_conntrack *conntrack;
};
/* Worst case: local-out manip + 1 post-routing, and reverse dirn. */
#define IP_NAT_MAX_MANIPS (2*3)
......@@ -93,7 +77,23 @@ struct ip_nat_info_manip
/* Manipulations to occur at each conntrack in this dirn. */
struct ip_conntrack_manip manip;
};
#ifdef __KERNEL__
#include <linux/list.h>
#include <linux/netfilter_ipv4/lockhelp.h>
/* Protects NAT hash tables, and NAT-private part of conntracks. */
DECLARE_RWLOCK_EXTERN(ip_nat_lock);
/* Hashes for by-source and IP/protocol. */
struct ip_nat_hash
{
struct list_head list;
/* conntrack we're embedded in: NULL if not in hash. */
struct ip_conntrack *conntrack;
};
/* The structure embedded in the conntrack structure. */
struct ip_nat_info
{
......
/* iptables module for setting the IPv4 DSCP field
*
* (C) 2002 Harald Welte <laforge@gnumonks.org>
* based on ipt_FTOS.c (C) 2000 by Matthew G. Marsh <mgm@paktronix.com>
* This software is distributed under GNU GPL v2, 1991
*
* See RFC2474 for a description of the DSCP field within the IP Header.
*
* ipt_DSCP.h,v 1.7 2002/03/14 12:03:13 laforge Exp
*/
#ifndef _IPT_DSCP_TARGET_H
#define _IPT_DSCP_TARGET_H
#include <linux/netfilter_ipv4/ipt_dscp.h>
/* target info */
struct ipt_DSCP_info {
u_int8_t dscp;
};
#endif /* _IPT_DSCP_TARGET_H */
/* Header file for iptables ipt_ECN target
*
* (C) 2002 by Harald Welte <laforge@gnumonks.org>
*
* This software is distributed under GNU GPL v2, 1991
*
* ipt_ECN.h,v 1.3 2002/05/29 12:17:40 laforge Exp
*/
#ifndef _IPT_ECN_TARGET_H
#define _IPT_ECN_TARGET_H
#include <linux/netfilter_ipv4/ipt_DSCP.h>
#define IPT_ECN_IP_MASK (~IPT_DSCP_MASK)
#define IPT_ECN_OP_SET_IP 0x01 /* set ECN bits of IPv4 header */
#define IPT_ECN_OP_SET_ECE 0x10 /* set ECE bit of TCP header */
#define IPT_ECN_OP_SET_CWR 0x20 /* set CWR bit of TCP header */
#define IPT_ECN_OP_MASK 0xce
struct ipt_ECN_info {
u_int8_t operation; /* bitset of operations */
u_int8_t ip_ect; /* ECT codepoint of IPv4 header, pre-shifted */
union {
struct {
u_int8_t ece:1, cwr:1; /* TCP ECT bits */
} tcp;
} proto;
};
#endif /* _IPT_ECN_TARGET_H */
/* Header file for kernel module to match connection tracking information.
* GPL (C) 2001 Marc Boucher (marc@mbsi.ca).
*/
#ifndef _IPT_CONNTRACK_H
#define _IPT_CONNTRACK_H
#define IPT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
#define IPT_CONNTRACK_STATE_INVALID (1 << 0)
#define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1))
#define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2))
/* flags, invflags: */
#define IPT_CONNTRACK_STATE 0x01
#define IPT_CONNTRACK_PROTO 0x02
#define IPT_CONNTRACK_ORIGSRC 0x04
#define IPT_CONNTRACK_ORIGDST 0x08
#define IPT_CONNTRACK_REPLSRC 0x10
#define IPT_CONNTRACK_REPLDST 0x20
#define IPT_CONNTRACK_STATUS 0x40
#define IPT_CONNTRACK_EXPIRES 0x80
struct ipt_conntrack_info
{
unsigned int statemask, statusmask;
struct ip_conntrack_tuple tuple[IP_CT_DIR_MAX];
struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX];
unsigned long expires_min, expires_max;
/* Flags word */
u_int8_t flags;
/* Inverse flags */
u_int8_t invflags;
};
#endif /*_IPT_CONNTRACK_H*/
/* iptables module for matching the IPv4 DSCP field
*
* (C) 2002 Harald Welte <laforge@gnumonks.org>
* This software is distributed under GNU GPL v2, 1991
*
* See RFC2474 for a description of the DSCP field within the IP Header.
*
* ipt_dscp.h,v 1.3 2002/08/05 19:00:21 laforge Exp
*/
#ifndef _IPT_DSCP_H
#define _IPT_DSCP_H
#define IPT_DSCP_MASK 0xfc /* 11111100 */
#define IPT_DSCP_SHIFT 2
#define IPT_DSCP_MAX 0x3f /* 00111111 */
/* match info */
struct ipt_dscp_info {
u_int8_t dscp;
u_int8_t invert;
};
#endif /* _IPT_DSCP_H */
/* iptables module for matching the ECN header in IPv4 and TCP header
*
* (C) 2002 Harald Welte <laforge@gnumonks.org>
*
* This software is distributed under GNU GPL v2, 1991
*
* ipt_ecn.h,v 1.4 2002/08/05 19:39:00 laforge Exp
*/
#ifndef _IPT_ECN_H
#define _IPT_ECN_H
#include <linux/netfilter_ipv4/ipt_dscp.h>
#define IPT_ECN_IP_MASK (~IPT_DSCP_MASK)
#define IPT_ECN_OP_MATCH_IP 0x01
#define IPT_ECN_OP_MATCH_ECE 0x10
#define IPT_ECN_OP_MATCH_CWR 0x20
#define IPT_ECN_OP_MATCH_MASK 0xce
/* match info */
struct ipt_ecn_info {
u_int8_t operation;
u_int8_t invert;
u_int8_t ip_ect;
union {
struct {
u_int8_t ect;
} tcp;
} proto;
};
#endif /* _IPT_ECN_H */
#ifndef _IPT_HELPER_H
#define _IPT_HELPER_H
struct ipt_helper_info {
int invert;
char name[30];
};
#endif /* _IPT_HELPER_H */
......@@ -6,12 +6,14 @@
#define IPT_OWNER_GID 0x02
#define IPT_OWNER_PID 0x04
#define IPT_OWNER_SID 0x08
#define IPT_OWNER_COMM 0x10
struct ipt_owner_info {
uid_t uid;
gid_t gid;
pid_t pid;
pid_t sid;
char comm[16];
u_int8_t match, invert; /* flags */
};
......
#ifndef _IPT_PKTTYPE_H
#define _IPT_PKTTYPE_H
struct ipt_pkttype_info {
int pkttype;
int invert;
};
#endif /*_IPT_PKTTYPE_H*/
#ifndef _IP6T_LENGTH_H
#define _IP6T_LENGTH_H
struct ip6t_length_info {
u_int16_t min, max;
u_int8_t invert;
};
#endif /*_IP6T_LENGTH_H*/
......@@ -24,25 +24,25 @@
/* All station state event action functions look like this */
typedef int (*llc_station_action_t)(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_station_ac_start_ack_timer(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_station_ac_set_retry_cnt_0(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_station_ac_inc_retry_cnt_by_1(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_station_ac_set_xid_r_cnt_0(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_station_ac_inc_xid_r_cnt_by_1(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_station_ac_send_null_dsap_xid_c(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_station_ac_send_xid_r(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_station_ac_send_test_r(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_station_ac_report_status(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_station_ac_report_status(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
#endif /* LLC_ACTN_H */
......@@ -87,168 +87,128 @@
#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 llc_conn_state_ev *ev);
typedef int (*llc_conn_action_t)(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ac_clear_remote_busy(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_conn_ind(struct sock *sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ac_conn_confirm(struct sock* sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ac_data_ind(struct sock* sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ac_disc_ind(struct sock* sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ac_rst_ind(struct sock* sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ac_rst_confirm(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_report_status(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ac_conn_confirm(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_data_ind(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_disc_ind(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_rst_ind(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_rst_confirm(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_report_status(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_disc_cmd_p_set_x(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_dm_rsp_f_set_p(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_dm_rsp_f_set_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_dm_rsp_f_set_f_flag(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_send_i_cmd_p_set_1(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_send_i_cmd_p_set_0(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_i_cmd_p_set_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_send_i_cmd_p_set_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_resend_i_cmd_p_set_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_resend_i_cmd_p_set_1_or_send_rr(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_send_i_xxx_x_set_0(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_i_xxx_x_set_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_resend_i_xxx_x_set_0(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_resend_i_rsp_f_set_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_rej_cmd_p_set_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_rej_rsp_f_set_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_rej_xxx_x_set_0(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_remote_busy(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_set_remote_busy(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_rr_cmd_p_set_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_ack_cmd_p_set_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_rr_rsp_f_set_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_ack_rsp_f_set_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_rr_xxx_x_set_0(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_ack_xxx_x_set_0(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_ua_rsp_f_set_f_flag(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_ua_rsp_f_set_p(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_s_flag_0(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_s_flag_1(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_start_p_timer(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_start_ack_timer(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_start_rej_timer(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_set_s_flag_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_s_flag_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_start_p_timer(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_start_ack_timer(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_start_rej_timer(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_start_ack_tmr_if_not_running(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_stop_ack_timer(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_stop_p_timer(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_stop_rej_timer(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_stop_all_timers(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_stop_other_timers(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_upd_nr_received(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_inc_tx_win_size(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_dec_tx_win_size(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_upd_p_flag(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_data_flag_2(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_data_flag_0(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_data_flag_1(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_stop_ack_timer(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_stop_p_timer(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_stop_rej_timer(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_stop_all_timers(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_stop_other_timers(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_upd_nr_received(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_inc_tx_win_size(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_dec_tx_win_size(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_upd_p_flag(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_data_flag_2(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_data_flag_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_data_flag_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_p_flag_0(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_p_flag_1(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_remote_busy_0(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_retry_cnt_0(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_cause_flag_0(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_cause_flag_1(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_inc_retry_cnt_by_1(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_vr_0(struct sock* sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ac_inc_vr_by_1(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_vs_0(struct sock* sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_vs_nr(struct sock* sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ac_rst_vs(struct sock* sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ac_upd_vs(struct sock* sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ac_set_f_flag_p(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_disc(struct sock* sk, struct llc_conn_state_ev *ev);
extern int llc_conn_reset(struct sock* sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ac_disc_confirm(struct sock* sk, struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_set_p_flag_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_p_flag_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_remote_busy_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_retry_cnt_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_cause_flag_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_cause_flag_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_inc_retry_cnt_by_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_vr_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_inc_vr_by_1(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_vs_0(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_vs_nr(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_rst_vs(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_upd_vs(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_set_f_flag_p(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_disc(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_reset(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_disc_confirm(struct sock* sk, struct sk_buff *skb);
extern u8 llc_circular_between(u8 a, u8 b, u8 c);
extern int llc_conn_ac_send_ack_if_needed(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_inc_npta_value(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_adjust_npta_by_rr(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_adjust_npta_by_rnr(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_rst_sendack_flag(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_send_ack_if_needed(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_inc_npta_value(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_adjust_npta_by_rr(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_adjust_npta_by_rnr(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_rst_sendack_flag(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_send_i_rsp_as_ack(struct sock* sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ac_send_i_as_ack(struct sock* sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ac_send_i_rsp_as_ack(struct sock* sk, struct sk_buff *skb);
extern int llc_conn_ac_send_i_as_ack(struct sock* sk, struct sk_buff *skb);
#endif /* LLC_C_AC_H */
......@@ -124,7 +124,6 @@ struct llc_conn_ev_prim_if {
struct llc_conn_ev_pdu_if {
u8 ev;
u8 reason;
struct sk_buff *skb;
};
/* Event interface for timer-generated events */
......@@ -155,169 +154,156 @@ struct llc_conn_state_ev {
union llc_conn_ev_if data;
};
typedef int (*llc_conn_ev_t)(struct sock *sk, struct llc_conn_state_ev *ev);
typedef int (*llc_conn_ev_qfyr_t)(struct sock *sk,
struct llc_conn_state_ev *ev);
static __inline__ struct llc_conn_state_ev *llc_conn_ev(struct sk_buff *skb)
{
return (struct llc_conn_state_ev *)skb->cb;
}
extern int llc_conn_ev_conn_req(struct sock *sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ev_conn_resp(struct sock *sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ev_data_req(struct sock *sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ev_disc_req(struct sock *sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ev_rst_req(struct sock *sk, struct llc_conn_state_ev *ev);
extern int llc_conn_ev_rst_resp(struct sock *sk, struct llc_conn_state_ev *ev);
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);
extern int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_conn_resp(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_rst_resp(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_local_busy_detected(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_local_busy_cleared(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_rx_bad_pdu(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_rx_xxx_yyy(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_xxx_yyy(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_p_tmr_exp(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_ack_tmr_exp(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_rej_tmr_exp(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_busy_tmr_exp(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_any_tmr_exp(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_sendack_tmr_exp(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_any_tmr_exp(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_sendack_tmr_exp(struct sock *sk, struct sk_buff *skb);
/* NOT_USED functions and their variations */
extern int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_xxx_cmd_pbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_rx_any_frame(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_tx_buffer_full(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_init_p_f_cycle(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb);
/* Available connection action qualifiers */
extern int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk,
struct llc_conn_state_ev *ev);
extern int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb);
extern int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_init_p_f_cycle(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_conn(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_disc(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_failed(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_impossible(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_received(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
extern int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk,
struct llc_conn_state_ev *ev);
struct sk_buff *skb);
#endif /* LLC_C_EV_H */
......@@ -136,12 +136,10 @@ extern void llc_sock_reset(struct sock *sk);
extern int llc_sock_init(struct sock *sk);
/* Access to a connection */
extern struct llc_conn_state_ev *llc_conn_alloc_ev(struct sock *sk);
extern int llc_conn_send_ev(struct sock *sk, struct llc_conn_state_ev *ev);
extern int llc_conn_send_ev(struct sock *sk, struct sk_buff *skb);
extern void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
extern void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb,
struct llc_conn_state_ev *ev);
extern void llc_conn_free_ev(struct llc_conn_state_ev *ev);
extern void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb);
extern void llc_conn_free_ev(struct sk_buff *skb);
extern void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr,
u8 first_p_bit);
extern void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr,
......
......@@ -58,7 +58,7 @@ union llc_stat_ev_if {
struct llc_stat_ev_simple_if a; /* 'a' for simple, easy ... */
struct llc_stat_ev_prim_if prim;
struct llc_stat_ev_pdu_if pdu;
struct llc_stat_ev_tmr_if tmr;
struct llc_stat_ev_tmr_if tmr;
struct llc_stat_ev_rpt_sts_if rsts; /* report status */
};
......@@ -68,26 +68,32 @@ struct llc_station_state_ev {
struct list_head node; /* node in station->ev_q.list */
};
static __inline__ struct llc_station_state_ev *
llc_station_ev(struct sk_buff *skb)
{
return (struct llc_station_state_ev *)skb->cb;
}
typedef int (*llc_station_ev_t)(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_stat_ev_enable_with_dup_addr_check(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_stat_ev_enable_without_dup_addr_check(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry(struct llc_station *
station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_stat_ev_rx_null_dsap_xid_c(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_stat_ev_rx_null_dsap_test_c(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern int llc_stat_ev_disable_req(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
#endif /* LLC_EVNT_H */
......@@ -20,4 +20,15 @@ extern struct net_device *mac_dev_peer(struct net_device *current_dev,
extern int llc_pdu_router(struct llc_sap *sap, struct sock *sk,
struct sk_buff *skb, u8 type);
extern u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da);
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];
}
#endif /* LLC_MAC_H */
......@@ -19,35 +19,40 @@
#define LLC_ACK_TIME 3
#define LLC_REJ_TIME 3
#define LLC_BUSY_TIME 3
#define LLC_SENDACK_TIME 50
#define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */
#define LLC_DEST_SAP 1 /* Type 1 goes here */
#define LLC_DEST_CONN 2 /* Type 2 goes here */
/* LLC Layer global default parameters */
#define LLC_GLOBAL_DEFAULT_MAX_NBR_SAPS 4
#define LLC_GLOBAL_DEFAULT_MAX_NBR_CONNS 64
/* LLC station component (SAP and connection resource manager) */
/* Station component; one per adapter */
/**
* struct llc_station - LLC station component
*
* SAP and connection resource manager, one per adapter.
*
* @state - state of station
* @xid_r_count - XID response PDU counter
* @ack_tmr_running - 1 or 0
* @mac_sa - MAC source address
* @sap_list - list of related SAPs
* @ev_q - events entering state mach.
* @mac_pdu_q - PDUs ready to send to MAC
*/
struct llc_station {
u8 state; /* state of station */
u8 xid_r_count; /* XID response PDU counter */
struct timer_list ack_timer;
u8 ack_tmr_running; /* 1 or 0 */
u8 retry_count;
u8 maximum_retry;
u8 mac_sa[6]; /* MAC source address */
u8 state;
u8 xid_r_count;
struct timer_list ack_timer;
u8 ack_tmr_running;
u8 retry_count;
u8 maximum_retry;
u8 mac_sa[6];
struct {
spinlock_t lock;
struct list_head list;
} sap_list; /* list of related SAPs */
spinlock_t lock;
struct list_head list;
} sap_list;
struct {
spinlock_t lock;
struct list_head list;
} ev_q; /* events entering state mach. */
struct sk_buff_head mac_pdu_q; /* PDUs ready to send to MAC */
struct sk_buff_head list;
spinlock_t lock;
} ev_q;
struct sk_buff_head mac_pdu_q;
};
struct llc_station_state_ev;
......@@ -56,10 +61,8 @@ extern void llc_sap_save(struct llc_sap *sap);
extern void llc_free_sap(struct llc_sap *sap);
extern struct llc_sap *llc_sap_find(u8 lsap);
extern struct llc_station *llc_station_get(void);
extern struct llc_station_state_ev *
llc_station_alloc_ev(struct llc_station *station);
extern void llc_station_send_ev(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
extern void llc_station_send_pdu(struct llc_station *station,
struct sk_buff *skb);
extern struct sk_buff *llc_alloc_frame(void);
......
......@@ -23,25 +23,17 @@
#define SAP_ACT_TEST_IND 9
/* All action functions must look like this */
typedef int (*llc_sap_action_t)(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
typedef int (*llc_sap_action_t)(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_unitdata_ind(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_action_send_ui(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_action_send_xid_c(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_action_send_xid_r(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_action_send_test_c(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_action_send_test_r(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
struct sk_buff *skb);
extern int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_report_status(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_action_xid_ind(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_action_test_ind(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
struct sk_buff *skb);
extern int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb);
#endif /* LLC_S_AC_H */
......@@ -11,6 +11,9 @@
*
* See the GNU General Public License for more details.
*/
#include <linux/skbuff.h>
/* Defines SAP component events */
/* Types of events (possible values in 'ev->type') */
#define LLC_SAP_EV_TYPE_SIMPLE 1
......@@ -45,9 +48,8 @@ struct llc_sap_ev_prim_if {
};
struct llc_sap_ev_pdu_if {
u8 ev;
u8 reason;
struct sk_buff *skb;
u8 ev;
u8 reason;
};
struct llc_sap_ev_tmr_if {
......@@ -75,27 +77,24 @@ struct llc_sap_state_ev {
union llc_sap_ev_if data;
};
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 llc_sap_state_ev *ev);
extern int llc_sap_ev_activation_req(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_ev_rx_ui(struct llc_sap *sap, struct llc_sap_state_ev *ev);
extern int llc_sap_ev_unitdata_req(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_ev_xid_req(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_ev_rx_xid_c(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_ev_rx_xid_r(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_ev_test_req(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_ev_rx_test_c(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
extern int llc_sap_ev_rx_test_r(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
typedef int (*llc_sap_ev_t)(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_activation_req(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_xid_req(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_test_req(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_deactivation_req(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
struct sk_buff *skb);
#endif /* LLC_S_EV_H */
......@@ -15,7 +15,8 @@
#define LLC_SAP_STATE_INACTIVE 1
#define LLC_SAP_STATE_ACTIVE 2
#define LLC_NBR_SAP_STATES 2 /* size of state table */
#define LLC_NR_SAP_STATES 2 /* size of state table */
/* structures and types */
/* SAP state table structure */
struct llc_sap_state_trans {
......@@ -25,10 +26,10 @@ struct llc_sap_state_trans {
};
struct llc_sap_state {
u8 curr_state;
struct llc_sap_state_trans **transitions;
u8 curr_state;
struct llc_sap_state_trans **transitions;
};
/* only access to SAP state table */
extern struct llc_sap_state llc_sap_state_table[LLC_NBR_SAP_STATES];
extern struct llc_sap_state llc_sap_state_table[LLC_NR_SAP_STATES];
#endif /* LLC_S_ST_H */
......@@ -49,9 +49,7 @@ struct llc_sap_state_ev;
extern void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk);
extern void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk);
extern void llc_sap_send_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev);
extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb,
struct llc_sap_state_ev *ev);
extern void llc_sap_send_ev(struct llc_sap *sap, struct sk_buff *skb);
extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
extern void llc_sap_send_pdu(struct llc_sap *sap, struct sk_buff *skb);
extern struct llc_sap_state_ev *llc_sap_alloc_ev(struct llc_sap *sap);
#endif /* LLC_SAP_H */
......@@ -26,6 +26,9 @@
*
* Merged changes from 2.2.19 into 2.4.3
* -- Eric Biederman <ebiederman@lnxi.com>, 22 April Aug 2001
*
* Multipe Nameservers in /proc/net/pnp
* -- Josef Siemes <jsiemes@web.de>, Aug 2002
*/
#include <linux/config.h>
......@@ -91,6 +94,8 @@
#define CONF_TIMEOUT_RANDOM (HZ) /* Maximum amount of randomization */
#define CONF_TIMEOUT_MULT *7/4 /* Rate of timeout growth */
#define CONF_TIMEOUT_MAX (HZ*30) /* Maximum allowed timeout */
#define CONF_NAMESERVERS_MAX 3 /* Maximum number of nameservers
- '3' from resolv.h */
/*
......@@ -132,7 +137,7 @@ u8 root_server_path[256] __initdata = { 0, }; /* Path to mount as root */
/* Persistent data: */
int ic_proto_used; /* Protocol used, if any */
u32 ic_nameserver = INADDR_NONE; /* DNS Server IP address */
u32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
u8 ic_domain[64]; /* DNS (not NIS) domain name */
/*
......@@ -625,6 +630,11 @@ static void __init ic_bootp_init_ext(u8 *e)
*/
static inline void ic_bootp_init(void)
{
int i;
for (i = 0; i < CONF_NAMESERVERS_MAX; i++)
ic_nameservers[i] = INADDR_NONE;
dev_add_pack(&bootp_packet_type);
}
......@@ -729,6 +739,9 @@ static int __init ic_bootp_string(char *dest, char *src, int len, int max)
*/
static void __init ic_do_bootp_ext(u8 *ext)
{
u8 servers;
int i;
#ifdef IPCONFIG_DEBUG
u8 *c;
......@@ -748,8 +761,13 @@ static void __init ic_do_bootp_ext(u8 *ext)
memcpy(&ic_gateway, ext+1, 4);
break;
case 6: /* DNS server */
if (ic_nameserver == INADDR_NONE)
memcpy(&ic_nameserver, ext+1, 4);
servers= *ext/4;
if (servers > CONF_NAMESERVERS_MAX)
servers = CONF_NAMESERVERS_MAX;
for (i = 0; i < servers; i++) {
if (ic_nameservers[i] == INADDR_NONE)
memcpy(&ic_nameservers[i], ext+1+4*i, 4);
}
break;
case 12: /* Host name */
ic_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);
......@@ -914,8 +932,8 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
ic_servaddr = b->server_ip;
if (ic_gateway == INADDR_NONE && b->relay_ip)
ic_gateway = b->relay_ip;
if (ic_nameserver == INADDR_NONE)
ic_nameserver = ic_servaddr;
if (ic_nameservers[0] == INADDR_NONE)
ic_nameservers[0] = ic_servaddr;
ic_got_reply = IC_BOOTP;
drop:
......@@ -1078,6 +1096,7 @@ static int pnp_get_info(char *buffer, char **start,
off_t offset, int length)
{
int len;
int i;
if (ic_proto_used & IC_PROTO)
sprintf(buffer, "#PROTO: %s\n",
......@@ -1090,9 +1109,12 @@ static int pnp_get_info(char *buffer, char **start,
if (ic_domain[0])
len += sprintf(buffer + len,
"domain %s\n", ic_domain);
if (ic_nameserver != INADDR_NONE)
len += sprintf(buffer + len,
"nameserver %u.%u.%u.%u\n", NIPQUAD(ic_nameserver));
for (i = 0; i < CONF_NAMESERVERS_MAX; i++) {
if (ic_nameservers[i] != INADDR_NONE)
len += sprintf(buffer + len,
"nameserver %u.%u.%u.%u\n",
NIPQUAD(ic_nameservers[i]));
}
if (offset > len)
offset = len;
......
......@@ -56,6 +56,16 @@ CONFIG_IP_NF_MATCH_LIMIT
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
CONFIG_IP_NF_MATCH_PKTTYPE
This patch allows you to match packet in accrodance
to its "class", eg. BROADCAST, MULTICAST, ...
Typical usage:
iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
CONFIG_IP_NF_MATCH_MAC
MAC matching allows you to match packets based on the source
Ethernet address of the packet.
......@@ -100,6 +110,22 @@ CONFIG_IP_NF_MATCH_AH_ESP
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
CONFIG_IP_NF_TARGET_DSCP
This option adds a `DSCP' match, which allows you to match against
the IPv4 header DSCP field (DSCP codepoint).
The DSCP codepoint can have any value between 0x0 and 0x4f.
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
CONFIG_IP_NF_MATCH_ECN
This option adds a `ECN' match, which allows you to match against
the IPv4 and TCP header ECN fields.
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
CONFIG_IP_NF_MATCH_TOS
TOS matching allows you to match packets based on the Type Of
Service fields of the IP packet.
......@@ -107,6 +133,16 @@ CONFIG_IP_NF_MATCH_TOS
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
CONFIG_IP_NF_MATCH_CONNTRACK
This is a general conntrack match module, a superset of the state match.
It allows matching on additional conntrack information, which is
useful in complex configurations, such as NAT gateways with multiple
internet links or tunnels.
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
CONFIG_IP_NF_MATCH_STATE
Connection state matching allows you to match packets based on their
relationship to a tracked connection (ie. previous packets). This
......@@ -211,6 +247,30 @@ CONFIG_IP_NF_MANGLE
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
CONFIG_IP_NF_TARGET_DSCP
This option adds a `DSCP' target, which allows you to create rules in
the iptables mangle table. The selected packet has the DSCP field set
to the hex value provided on the command line; unlike the TOS target
which will only set the legal values within ip.h.
The DSCP field can be set to any value between 0x0 and 0x4f. It does
take into account that bits 6 and 7 are used by ECN.
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
CONFIG_IP_NF_TARGET_ECN
This option adds a `ECN' target, which can be used in the iptables mangle
table.
You can use this target to remove the ECN bits from the IPv4 header of
an IP packet. This is particularly useful, if you need to work around
existing ECN blackholes on the internet, but don't want to disable
ECN support in general.
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
CONFIG_IP_NF_TARGET_TOS
This option adds a `TOS' target, which allows you to create rules in
the `mangle' table which alter the Type Of Service field of an IP
......@@ -230,6 +290,13 @@ CONFIG_IP_NF_TARGET_MARK
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
CONFIG_IP_NF_MATCH_HELPER
Helper matching allows you to match packets in dynamic connections
tracked by a conntrack-helper, ie. ip_conntrack_ftp
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `Y'.
CONFIG_IP_NF_TARGET_TCPMSS
This option adds a `TCPMSS' target, which allows you to alter the
MSS value of TCP SYN packets, to control the maximum size for that
......
......@@ -18,15 +18,24 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then
# The simple matches.
dep_tristate ' limit match support' CONFIG_IP_NF_MATCH_LIMIT $CONFIG_IP_NF_IPTABLES
dep_tristate ' MAC address match support' CONFIG_IP_NF_MATCH_MAC $CONFIG_IP_NF_IPTABLES
dep_tristate ' Packet type match support' CONFIG_IP_NF_MATCH_PKTTYPE $CONFIG_IP_NF_IPTABLES
dep_tristate ' netfilter MARK match support' CONFIG_IP_NF_MATCH_MARK $CONFIG_IP_NF_IPTABLES
dep_tristate ' Multiple port match support' CONFIG_IP_NF_MATCH_MULTIPORT $CONFIG_IP_NF_IPTABLES
dep_tristate ' TOS match support' CONFIG_IP_NF_MATCH_TOS $CONFIG_IP_NF_IPTABLES
dep_tristate ' ECN match support' CONFIG_IP_NF_MATCH_ECN $CONFIG_IP_NF_IPTABLES
dep_tristate ' DSCP match support' CONFIG_IP_NF_MATCH_DSCP $CONFIG_IP_NF_IPTABLES
dep_tristate ' AH/ESP match support' CONFIG_IP_NF_MATCH_AH_ESP $CONFIG_IP_NF_IPTABLES
dep_tristate ' LENGTH match support' CONFIG_IP_NF_MATCH_LENGTH $CONFIG_IP_NF_IPTABLES
dep_tristate ' TTL match support' CONFIG_IP_NF_MATCH_TTL $CONFIG_IP_NF_IPTABLES
dep_tristate ' tcpmss match support' CONFIG_IP_NF_MATCH_TCPMSS $CONFIG_IP_NF_IPTABLES
if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
dep_tristate ' Helper match support' CONFIG_IP_NF_MATCH_HELPER $CONFIG_IP_NF_IPTABLES
fi
if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
dep_tristate ' Connection state match support' CONFIG_IP_NF_MATCH_STATE $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES
dep_tristate ' Connection tracking match support' CONFIG_IP_NF_MATCH_CONNTRACK $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES
fi
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_tristate ' Unclean match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_UNCLEAN $CONFIG_IP_NF_IPTABLES
......@@ -73,6 +82,10 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then
dep_tristate ' Packet mangling' CONFIG_IP_NF_MANGLE $CONFIG_IP_NF_IPTABLES
if [ "$CONFIG_IP_NF_MANGLE" != "n" ]; then
dep_tristate ' TOS target support' CONFIG_IP_NF_TARGET_TOS $CONFIG_IP_NF_MANGLE
dep_tristate ' ECN target support' CONFIG_IP_NF_TARGET_ECN $CONFIG_IP_NF_MANGLE
dep_tristate ' DSCP target support' CONFIG_IP_NF_TARGET_DSCP $CONFIG_IP_NF_MANGLE
dep_tristate ' MARK target support' CONFIG_IP_NF_TARGET_MARK $CONFIG_IP_NF_MANGLE
fi
dep_tristate ' LOG target support' CONFIG_IP_NF_TARGET_LOG $CONFIG_IP_NF_IPTABLES
......
......@@ -3,8 +3,7 @@
#
export-objs := ip_conntrack_standalone.o ip_fw_compat.o ip_nat_standalone.o \
ip_tables.o arp_tables.o ip_conntrack_ftp.o \
ip_conntrack_irc.o
ip_tables.o arp_tables.o
# objects for the conntrack and NAT core (used by standalone and backw. compat)
ip_nf_conntrack-objs := ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
......@@ -25,7 +24,13 @@ obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
# connection tracking helpers
obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
ifdef CONFIG_IP_NF_NAT_FTP
export-objs += ip_conntrack_ftp.o
endif
obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
ifdef CONFIG_IP_NF_NAT_IRC
export-objs += ip_conntrack_irc.o
endif
# NAT helpers
obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
......@@ -40,18 +45,24 @@ obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
# matches
obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o
obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o
obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o
obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o
obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o
obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
......@@ -59,6 +70,8 @@ obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
obj-$(CONFIG_IP_NF_TARGET_MIRROR) += ipt_MIRROR.o
obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o
obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o
obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
......
......@@ -8,6 +8,9 @@
* 23 Apr 2001: Harald Welte <laforge@gnumonks.org>
* - new API and handling of conntrack/nat helpers
* - now capable of multiple expectations for one master
* 16 Jul 2002: Harald Welte <laforge@gnumonks.org>
* - add usage/reference counts to ip_conntrack_expect
* - export ip_conntrack[_expect]_{find_get,put} functions
* */
#ifdef MODULE
......@@ -43,7 +46,7 @@
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
#include <linux/netfilter_ipv4/listhelp.h>
#define IP_CONNTRACK_VERSION "2.0"
#define IP_CONNTRACK_VERSION "2.1"
#if 0
#define DEBUGP printk
......@@ -55,7 +58,7 @@ DECLARE_RWLOCK(ip_conntrack_lock);
DECLARE_RWLOCK(ip_conntrack_expect_tuple_lock);
void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack) = NULL;
LIST_HEAD(expect_list);
LIST_HEAD(ip_conntrack_expect_list);
LIST_HEAD(protocol_list);
static LIST_HEAD(helpers);
unsigned int ip_conntrack_htable_size = 0;
......@@ -95,7 +98,8 @@ struct ip_conntrack_protocol *ip_ct_find_proto(u_int8_t protocol)
return p;
}
static inline void ip_conntrack_put(struct ip_conntrack *ct)
inline void
ip_conntrack_put(struct ip_conntrack *ct)
{
IP_NF_ASSERT(ct);
IP_NF_ASSERT(ct->infos[0].master);
......@@ -159,26 +163,109 @@ invert_tuple(struct ip_conntrack_tuple *inverse,
return protocol->invert_tuple(inverse, orig);
}
/* remove one specific expectation from all lists and free it */
static void unexpect_related(struct ip_conntrack_expect *expect)
/* ip_conntrack_expect helper functions */
/* Compare tuple parts depending on mask. */
static inline int expect_cmp(const struct ip_conntrack_expect *i,
const struct ip_conntrack_tuple *tuple)
{
MUST_BE_READ_LOCKED(&ip_conntrack_expect_tuple_lock);
return ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask);
}
static void
destroy_expect(struct ip_conntrack_expect *exp)
{
DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(exp->use));
IP_NF_ASSERT(atomic_read(exp->use));
IP_NF_ASSERT(!timer_pending(&exp->timeout));
kfree(exp);
}
inline void ip_conntrack_expect_put(struct ip_conntrack_expect *exp)
{
IP_NF_ASSERT(exp);
if (atomic_dec_and_test(&exp->use)) {
/* usage count dropped to zero */
destroy_expect(exp);
}
}
static inline struct ip_conntrack_expect *
__ip_ct_expect_find(const struct ip_conntrack_tuple *tuple)
{
MUST_BE_READ_LOCKED(&ip_conntrack_lock);
MUST_BE_READ_LOCKED(&ip_conntrack_expect_tuple_lock);
return LIST_FIND(&ip_conntrack_expect_list, expect_cmp,
struct ip_conntrack_expect *, tuple);
}
/* Find a expectation corresponding to a tuple. */
struct ip_conntrack_expect *
ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple)
{
struct ip_conntrack_expect *exp;
READ_LOCK(&ip_conntrack_lock);
READ_LOCK(&ip_conntrack_expect_tuple_lock);
exp = __ip_ct_expect_find(tuple);
if (exp)
atomic_inc(&exp->use);
READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
READ_UNLOCK(&ip_conntrack_lock);
return exp;
}
/* remove one specific expectation from all lists and drop refcount,
* does _NOT_ delete the timer. */
static void __unexpect_related(struct ip_conntrack_expect *expect)
{
MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
DEBUGP("unexpect_related(%p)\n", expect);
MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
/* we're not allowed to unexpect a confirmed expectation! */
IP_NF_ASSERT(!expect->sibling);
/* delete from global and local lists */
list_del(&expect->list);
list_del(&expect->expected_list);
if (!expect->sibling)
/* decrement expect-count of master conntrack */
if (expect->expectant)
expect->expectant->expecting--;
kfree(expect);
ip_conntrack_expect_put(expect);
}
/* delete all expectations for this conntrack */
static void destroy_expectations(struct ip_conntrack *ct)
/* remove one specific expecatation from all lists, drop refcount
* and expire timer.
* This function can _NOT_ be called for confirmed expects! */
static void unexpect_related(struct ip_conntrack_expect *expect)
{
IP_NF_ASSERT(expect->expectant);
IP_NF_ASSERT(expect->expectant->helper);
/* if we are supposed to have a timer, but we can't delete
* it: race condition. __unexpect_related will
* be calledd by timeout function */
if (expect->expectant->helper->timeout
&& !del_timer(&expect->timeout))
return;
__unexpect_related(expect);
}
/* delete all unconfirmed expectations for this conntrack */
static void remove_expectations(struct ip_conntrack *ct)
{
struct list_head *exp_entry, *next;
struct ip_conntrack_expect *exp;
DEBUGP("destroy_expectations(%p)\n", ct);
DEBUGP("remove_expectations(%p)\n", ct);
for (exp_entry = ct->sibling_list.next;
exp_entry != &ct->sibling_list; exp_entry = next) {
......@@ -189,19 +276,13 @@ static void destroy_expectations(struct ip_conntrack *ct)
/* we skip established expectations, as we want to delete
* the un-established ones only */
if (exp->sibling) {
DEBUGP("destroy_expectations: skipping established %p of %p\n", exp->sibling, ct);
DEBUGP("remove_expectations: skipping established %p of %p\n", exp->sibling, ct);
continue;
}
IP_NF_ASSERT(list_inlist(&expect_list, exp));
IP_NF_ASSERT(list_inlist(&ip_conntrack_expect_list, exp));
IP_NF_ASSERT(exp->expectant == ct);
if (exp->expectant->helper->timeout
&& ! del_timer(&exp->timeout)) {
DEBUGP("destroy_expectations: skipping dying expectation %p of %p\n", exp, ct);
continue;
}
/* delete expectation from global and private lists */
unexpect_related(exp);
}
......@@ -223,7 +304,7 @@ clean_from_lists(struct ip_conntrack *ct)
&ct->tuplehash[IP_CT_DIR_REPLY]);
/* Destroy all un-established, pending expectations */
destroy_expectations(ct);
remove_expectations(ct);
}
static void
......@@ -250,15 +331,15 @@ destroy_conntrack(struct nf_conntrack *nfct)
ip_conntrack_destroyed(ct);
WRITE_LOCK(&ip_conntrack_lock);
/* Delete our master expectation from the local list
* and destroy it, if we've been expected */
/* Delete our master expectation */
if (ct->master) {
/* can't call __unexpect_related here,
* since it would screw up expect_list */
list_del(&ct->master->expected_list);
kfree(ct->master);
}
WRITE_UNLOCK(&ip_conntrack_lock);
DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
kmem_cache_free(ip_conntrack_cachep, ct);
atomic_dec(&ip_conntrack_count);
......@@ -383,7 +464,7 @@ __ip_conntrack_confirm(struct nf_ct_info *nfct)
&ct->tuplehash[IP_CT_DIR_REPLY]);
/* Timer relative to confirmation time, not original
setting time, otherwise we'd get timer wrap in
wierd delay cases. */
weird delay cases. */
ct->timeout.expires += jiffies;
add_timer(&ct->timeout);
atomic_inc(&ct->ct_general.use);
......@@ -544,14 +625,6 @@ struct ip_conntrack_helper *ip_ct_find_helper(const struct ip_conntrack_tuple *t
tuple);
}
/* Compare parts depending on mask. */
static inline int expect_cmp(const struct ip_conntrack_expect *i,
const struct ip_conntrack_tuple *tuple)
{
MUST_BE_READ_LOCKED(&ip_conntrack_expect_tuple_lock);
return ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask);
}
/* Allocate a new conntrack: we return -ENOMEM if classification
failed due to stress. Otherwise it really is unclassifiable. */
static struct ip_conntrack_tuple_hash *
......@@ -573,9 +646,9 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
/* Try dropping from random chain, or else from the
chain about to put into (in case they're trying to
bomb one hash chain). */
if (drop_next >= ip_conntrack_htable_size)
drop_next = 0;
if (!early_drop(&ip_conntrack_hash[drop_next++])
unsigned int next = (drop_next++)%ip_conntrack_htable_size;
if (!early_drop(&ip_conntrack_hash[next])
&& !early_drop(&ip_conntrack_hash[hash])) {
if (net_ratelimit())
printk(KERN_WARNING
......@@ -624,7 +697,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
WRITE_LOCK(&ip_conntrack_lock);
/* Need finding and deleting of expected ONLY if we win race */
READ_LOCK(&ip_conntrack_expect_tuple_lock);
expected = LIST_FIND(&expect_list, expect_cmp,
expected = LIST_FIND(&ip_conntrack_expect_list, expect_cmp,
struct ip_conntrack_expect *, tuple);
READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
......@@ -651,7 +724,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
conntrack->status = IPS_EXPECTED;
conntrack->master = expected;
expected->sibling = conntrack;
LIST_DELETE(&expect_list, expected);
LIST_DELETE(&ip_conntrack_expect_list, expected);
expected->expectant->expecting--;
nf_conntrack_get(&master_ct(conntrack)->infos[0]);
}
......@@ -835,7 +908,7 @@ static inline int expect_clash(const struct ip_conntrack_expect *i,
return ip_ct_tuple_mask_cmp(&i->tuple, tuple, &intersect_mask);
}
void ip_conntrack_unexpect_related(struct ip_conntrack_expect *expect)
inline void ip_conntrack_unexpect_related(struct ip_conntrack_expect *expect)
{
WRITE_LOCK(&ip_conntrack_lock);
unexpect_related(expect);
......@@ -847,14 +920,16 @@ static void expectation_timed_out(unsigned long ul_expect)
struct ip_conntrack_expect *expect = (void *) ul_expect;
DEBUGP("expectation %p timed out\n", expect);
ip_conntrack_unexpect_related(expect);
WRITE_LOCK(&ip_conntrack_lock);
__unexpect_related(expect);
WRITE_UNLOCK(&ip_conntrack_lock);
}
/* Add a related connection. */
int ip_conntrack_expect_related(struct ip_conntrack *related_to,
struct ip_conntrack_expect *expect)
{
struct ip_conntrack_expect *new;
struct ip_conntrack_expect *old, *new;
int ret = 0;
WRITE_LOCK(&ip_conntrack_lock);
......@@ -865,78 +940,88 @@ int ip_conntrack_expect_related(struct ip_conntrack *related_to,
DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple);
DEBUGP("mask: "); DUMP_TUPLE(&expect->mask);
new = LIST_FIND(&expect_list, resent_expect,
struct ip_conntrack_expect *, &expect->tuple, &expect->mask);
if (new) {
old = LIST_FIND(&ip_conntrack_expect_list, resent_expect,
struct ip_conntrack_expect *, &expect->tuple,
&expect->mask);
if (old) {
/* Helper private data may contain offsets but no pointers
pointing into the payload - otherwise we should have to copy
the data filled out by the helper over the old one */
DEBUGP("expect_related: resent packet\n");
if (related_to->helper->timeout) {
/* Refresh timer, if possible... */
if (del_timer(&new->timeout)) {
new->timeout.expires = jiffies + related_to->helper->timeout * HZ;
add_timer(&new->timeout);
WRITE_UNLOCK(&ip_conntrack_lock);
return -EEXIST;
if (!del_timer(&old->timeout)) {
/* expectation is dying. Fall through */
old = NULL;
} else {
old->timeout.expires = jiffies +
related_to->helper->timeout * HZ;
add_timer(&old->timeout);
}
/* ... otherwise expectation is dying. Fall over and create a new one. */
new = NULL;
} else {
}
if (old) {
WRITE_UNLOCK(&ip_conntrack_lock);
return -EEXIST;
}
} else if (related_to->helper->max_expected
&& related_to->expecting >= related_to->helper->max_expected) {
} else if (related_to->helper->max_expected &&
related_to->expecting >= related_to->helper->max_expected) {
struct list_head *cur_item;
/* old == NULL */
if (net_ratelimit())
printk(KERN_WARNING
"ip_conntrack: max number of expected connections %i of %s reached for %u.%u.%u.%u->%u.%u.%u.%u%s\n",
"ip_conntrack: max number of expected "
"connections %i of %s reached for "
"%u.%u.%u.%u->%u.%u.%u.%u%s\n",
related_to->helper->max_expected,
related_to->helper->name,
NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip),
related_to->helper->flags & IP_CT_HELPER_F_REUSE_EXPECT ?
", reusing" : "");
if (related_to->helper->flags & IP_CT_HELPER_F_REUSE_EXPECT) {
struct list_head *cur_item;
/* Let's choose the the oldest expectation to overwrite */
list_for_each(cur_item, &related_to->sibling_list) {
new = list_entry(cur_item, struct ip_conntrack_expect,
expected_list);
if (new->sibling == NULL)
break;
}
IP_NF_ASSERT(new);
if (related_to->helper->timeout
&& !del_timer(&new->timeout)) {
/* Expectation is dying. Fall over and create a new one */
new = NULL;
} else {
list_del(&new->list);
list_del(&new->expected_list);
related_to->expecting--;
ret = -EPERM;
}
} else {
if (!(related_to->helper->flags &
IP_CT_HELPER_F_REUSE_EXPECT)) {
WRITE_UNLOCK(&ip_conntrack_lock);
return -EPERM;
}
} else if (LIST_FIND(&expect_list, expect_clash,
struct ip_conntrack_expect *, &expect->tuple, &expect->mask)) {
/* choose the the oldest expectation to evict */
list_for_each(cur_item, &related_to->sibling_list) {
struct ip_conntrack_expect *cur;
cur = list_entry(cur_item,
struct ip_conntrack_expect,
expected_list);
if (cur->sibling == NULL) {
old = cur;
break;
}
}
/* (!old) cannot happen, since related_to->expecting is the
* number of unconfirmed expects */
IP_NF_ASSERT(old);
/* newnat14 does not reuse the real allocated memory
* structures but rather unexpects the old and
* allocates a new. unexpect_related will decrement
* related_to->expecting.
*/
unexpect_related(old);
ret = -EPERM;
} else if (LIST_FIND(&ip_conntrack_expect_list, expect_clash,
struct ip_conntrack_expect *, &expect->tuple,
&expect->mask)) {
WRITE_UNLOCK(&ip_conntrack_lock);
DEBUGP("expect_related: busy!\n");
return -EBUSY;
}
new = (struct ip_conntrack_expect *)
kmalloc(sizeof(struct ip_conntrack_expect), GFP_ATOMIC);
if (!new) {
new = (struct ip_conntrack_expect *)
kmalloc(sizeof(*expect), GFP_ATOMIC);
if (!new) {
WRITE_UNLOCK(&ip_conntrack_lock);
DEBUGP("expect_relaed: OOM allocating expect\n");
return -ENOMEM;
}
WRITE_UNLOCK(&ip_conntrack_lock);
DEBUGP("expect_relaed: OOM allocating expect\n");
return -ENOMEM;
}
/* Zero out the new structure, then fill out it with the data */
......@@ -947,17 +1032,22 @@ int ip_conntrack_expect_related(struct ip_conntrack *related_to,
memcpy(new, expect, sizeof(*expect));
new->expectant = related_to;
new->sibling = NULL;
/* increase usage count. This sucks. The memset above overwrites
* old usage count [if still present] and we increase to one. Only
* works because everything is done under ip_conntrack_lock() */
atomic_inc(&new->use);
/* add to expected list for this connection */
list_add(&new->expected_list, &related_to->sibling_list);
/* add to global list of expectations */
list_prepend(&expect_list, &new->list);
list_prepend(&ip_conntrack_expect_list, &new->list);
/* add and start timer if required */
if (related_to->helper->timeout) {
init_timer(&new->timeout);
new->timeout.data = (unsigned long)new;
new->timeout.function = expectation_timed_out;
new->timeout.expires = jiffies + related_to->helper->timeout * HZ;
new->timeout.expires = jiffies +
related_to->helper->timeout * HZ;
add_timer(&new->timeout);
}
related_to->expecting++;
......@@ -981,7 +1071,7 @@ int ip_conntrack_change_expect(struct ip_conntrack_expect *expect,
/* Never seen before */
DEBUGP("change expect: never seen before\n");
if (!ip_ct_tuple_equal(&expect->tuple, newtuple)
&& LIST_FIND(&expect_list, expect_clash,
&& LIST_FIND(&ip_conntrack_expect_list, expect_clash,
struct ip_conntrack_expect *, newtuple, &expect->mask)) {
/* Force NAT to find an unused tuple */
return -1;
......@@ -1048,7 +1138,7 @@ static inline int unhelp(struct ip_conntrack_tuple_hash *i,
{
if (i->ctrack->helper == me) {
/* Get rid of any expected. */
destroy_expectations(i->ctrack);
remove_expectations(i->ctrack);
/* And *then* set helper to NULL */
i->ctrack->helper = NULL;
}
......@@ -1340,14 +1430,16 @@ int __init ip_conntrack_init(void)
sizeof(struct ip_conntrack));
ret = nf_register_sockopt(&so_getorigdst);
if (ret != 0)
if (ret != 0) {
printk(KERN_ERR "Unable to register netfilter socket option\n");
return ret;
}
ip_conntrack_hash = vmalloc(sizeof(struct list_head)
* ip_conntrack_htable_size);
if (!ip_conntrack_hash) {
nf_unregister_sockopt(&so_getorigdst);
return -ENOMEM;
printk(KERN_ERR "Unable to create ip_conntrack_hash\n");
goto err_unreg_sockopt;
}
ip_conntrack_cachep = kmem_cache_create("ip_conntrack",
......@@ -1355,11 +1447,8 @@ int __init ip_conntrack_init(void)
SLAB_HWCACHE_ALIGN, NULL, NULL);
if (!ip_conntrack_cachep) {
printk(KERN_ERR "Unable to create ip_conntrack slab cache\n");
vfree(ip_conntrack_hash);
nf_unregister_sockopt(&so_getorigdst);
return -ENOMEM;
goto err_free_hash;
}
/* Don't NEED lock here, but good form anyway. */
WRITE_LOCK(&ip_conntrack_lock);
/* Sew in builtin protocols. */
......@@ -1378,14 +1467,20 @@ int __init ip_conntrack_init(void)
ip_conntrack_sysctl_header
= register_sysctl_table(ip_conntrack_root_table, 0);
if (ip_conntrack_sysctl_header == NULL) {
kmem_cache_destroy(ip_conntrack_cachep);
vfree(ip_conntrack_hash);
nf_unregister_sockopt(&so_getorigdst);
return -ENOMEM;
goto err_free_ct_cachep;
}
#endif /*CONFIG_SYSCTL*/
/* For use by ipt_REJECT */
ip_ct_attach = ip_conntrack_attach;
return ret;
err_free_ct_cachep:
kmem_cache_destroy(ip_conntrack_cachep);
err_free_hash:
vfree(ip_conntrack_hash);
err_unreg_sockopt:
nf_unregister_sockopt(&so_getorigdst);
return -ENOMEM;
}
......@@ -16,7 +16,7 @@ struct module *ip_conntrack_ftp = THIS_MODULE;
#define MAX_PORTS 8
static int ports[MAX_PORTS];
static int ports_c;
static int ports_c = 0;
#ifdef MODULE_PARM
MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
#endif
......@@ -389,7 +389,7 @@ static char ftp_names[MAX_PORTS][10];
static void fini(void)
{
int i;
for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
for (i = 0; i < ports_c; i++) {
DEBUGP("ip_ct_ftp: unregistering helper for port %d\n",
ports[i]);
ip_conntrack_helper_unregister(&ftp[i]);
......
......@@ -35,7 +35,7 @@
#define MAX_PORTS 8
static int ports[MAX_PORTS];
static int ports_n_c = 0;
static int ports_c = 0;
static int max_dcc_channels = 8;
static unsigned int dcc_timeout = 300;
......@@ -288,7 +288,7 @@ static int __init init(void)
fini();
return -EBUSY;
}
ports_n_c++;
ports_c++;
}
return 0;
}
......@@ -298,7 +298,7 @@ static int __init init(void)
static void fini(void)
{
int i;
for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
for (i = 0; i < ports_c; i++) {
DEBUGP("unregistering port %d\n",
ports[i]);
ip_conntrack_helper_unregister(&irc_helpers[i]);
......
......@@ -68,8 +68,8 @@ print_expect(char *buffer, const struct ip_conntrack_expect *expect)
? (expect->timeout.expires - jiffies)/HZ : 0);
else
len = sprintf(buffer, "EXPECTING: - ");
len += sprintf(buffer + len, "proto=%u ",
expect->tuple.dst.protonum);
len += sprintf(buffer + len, "use=%u proto=%u ",
atomic_read(&expect->use), expect->tuple.dst.protonum);
len += print_tuple(buffer + len, &expect->tuple,
__find_proto(expect->tuple.dst.protonum));
len += sprintf(buffer + len, "\n");
......@@ -153,7 +153,8 @@ list_conntracks(char *buffer, char **start, off_t offset, int length)
}
/* Now iterate through expecteds. */
for (e = expect_list.next; e != &expect_list; e = e->next) {
for (e = ip_conntrack_expect_list.next;
e != &ip_conntrack_expect_list; e = e->next) {
unsigned int last_len;
struct ip_conntrack_expect *expect
= (struct ip_conntrack_expect *)e;
......@@ -364,7 +365,13 @@ EXPORT_SYMBOL(ip_ct_find_helper);
EXPORT_SYMBOL(ip_conntrack_expect_related);
EXPORT_SYMBOL(ip_conntrack_change_expect);
EXPORT_SYMBOL(ip_conntrack_unexpect_related);
EXPORT_SYMBOL_GPL(ip_conntrack_expect_find_get);
EXPORT_SYMBOL_GPL(ip_conntrack_expect_put);
EXPORT_SYMBOL(ip_conntrack_tuple_taken);
EXPORT_SYMBOL(ip_ct_gather_frags);
EXPORT_SYMBOL(ip_conntrack_htable_size);
EXPORT_SYMBOL(ip_conntrack_expect_list);
EXPORT_SYMBOL(ip_conntrack_lock);
EXPORT_SYMBOL(ip_conntrack_hash);
EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
EXPORT_SYMBOL_GPL(ip_conntrack_put);
......@@ -18,6 +18,7 @@ struct notifier_block;
/* Theoretically, we could one day use 2.4 helpers, but for now it
just confuses depmod --RR */
EXPORT_NO_SYMBOLS;
static struct firewall_ops *fwops;
......
......@@ -738,11 +738,10 @@ static inline int exp_for_packet(struct ip_conntrack_expect *exp,
struct ip_conntrack_protocol *proto;
int ret = 1;
READ_LOCK(&ip_conntrack_lock);
MUST_BE_READ_LOCKED(&ip_conntrack_lock);
proto = ip_ct_find_proto((*pskb)->nh.iph->protocol);
if (proto->exp_matches_pkt)
ret = proto->exp_matches_pkt(exp, pskb);
READ_UNLOCK(&ip_conntrack_lock);
return ret;
}
......@@ -999,4 +998,5 @@ void ip_nat_cleanup(void)
{
ip_ct_selective_cleanup(&clean_nat, NULL);
ip_conntrack_destroyed = NULL;
vfree(bysource);
}
......@@ -291,7 +291,7 @@ static void fini(void)
{
int i;
for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
for (i = 0; i < ports_c; i++) {
DEBUGP("ip_nat_ftp: unregistering port %d\n", ports[i]);
ip_nat_helper_unregister(&ftp[i]);
}
......
......@@ -52,11 +52,10 @@
#include <linux/netfilter_ipv4/ip_nat_helper.h>
#include <linux/brlock.h>
#include <linux/types.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <net/udp.h>
#include <asm/uaccess.h>
#include <net/checksum.h>
#include <asm/checksum.h>
......
......@@ -122,8 +122,10 @@
#include <net/icmp.h>
#include <linux/netlink.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/netfilter_ipv4/ipfwadm_core.h>
#include <linux/netfilter_ipv4/compat_firewall.h>
#include <linux/netfilter_ipv4/lockhelp.h>
#include <net/checksum.h>
#include <linux/proc_fs.h>
......@@ -154,6 +156,8 @@
#define dprint_ip(a)
#endif
static rwlock_t ip_fw_lock = RW_LOCK_UNLOCKED;
#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
struct ip_fw *ip_fw_fwd_chain;
......@@ -442,6 +446,11 @@ int ip_fw_chk(struct iphdr *ip, struct net_device *rif, __u16 *redirport,
dprintf1("\n");
#endif
if (mode == IP_FW_MODE_CHK)
READ_LOCK(&ip_fw_lock);
else
WRITE_LOCK(&ip_fw_lock);
for (f=chain;f;f=f->fw_next)
{
/*
......@@ -646,7 +655,8 @@ int ip_fw_chk(struct iphdr *ip, struct net_device *rif, __u16 *redirport,
#ifdef CONFIG_IP_FIREWALL_NETLINK
if((policy&IP_FW_F_PRN) && (answer == FW_REJECT || answer == FW_BLOCK))
{
struct sk_buff *skb=alloc_skb(128, GFP_ATOMIC);
struct sk_buff *skb=alloc_skb(128, (mode == IP_FW_MODE_CHK) ?
GFP_KERNEL : GFP_ATOMIC);
if(skb)
{
int len = min_t(unsigned int,
......@@ -659,29 +669,36 @@ int ip_fw_chk(struct iphdr *ip, struct net_device *rif, __u16 *redirport,
}
}
#endif
return answer;
} else
/* we're doing accounting, always ok */
return 0;
answer = 0;
if (mode == IP_FW_MODE_CHK)
READ_UNLOCK(&ip_fw_lock);
else
WRITE_UNLOCK(&ip_fw_lock);
return answer;
}
static void zero_fw_chain(struct ip_fw *chainptr)
{
struct ip_fw *ctmp=chainptr;
WRITE_LOCK(&ip_fw_lock);
while(ctmp)
{
ctmp->fw_pcnt=0L;
ctmp->fw_bcnt=0L;
ctmp=ctmp->fw_next;
}
WRITE_UNLOCK(&ip_fw_lock);
}
static void free_fw_chain(struct ip_fw *volatile* chainptr)
{
unsigned long flags;
save_flags(flags);
cli();
WRITE_LOCK(&ip_fw_lock);
while ( *chainptr != NULL )
{
struct ip_fw *ftmp;
......@@ -690,7 +707,7 @@ static void free_fw_chain(struct ip_fw *volatile* chainptr)
kfree(ftmp);
MOD_DEC_USE_COUNT;
}
restore_flags(flags);
WRITE_UNLOCK(&ip_fw_lock);
}
/* Volatiles to keep some of the compiler versions amused */
......@@ -698,11 +715,8 @@ static void free_fw_chain(struct ip_fw *volatile* chainptr)
static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,int len)
{
struct ip_fw *ftmp;
unsigned long flags;
save_flags(flags);
ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
ftmp = kmalloc( sizeof(struct ip_fw), GFP_KERNEL );
if ( ftmp == NULL )
{
#ifdef DEBUG_IP_FIREWALL
......@@ -721,7 +735,7 @@ static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
ftmp->fw_pcnt=0L;
ftmp->fw_bcnt=0L;
cli();
WRITE_LOCK(&ip_fw_lock);
if ((ftmp->fw_vianame)[0]) {
if (!(ftmp->fw_viadev = dev_get_by_name(ftmp->fw_vianame)))
......@@ -731,7 +745,7 @@ static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
ftmp->fw_next = *chainptr;
*chainptr=ftmp;
restore_flags(flags);
WRITE_UNLOCK(&ip_fw_lock);
MOD_INC_USE_COUNT;
return(0);
}
......@@ -741,11 +755,8 @@ static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
struct ip_fw *ftmp;
struct ip_fw *chtmp=NULL;
struct ip_fw *volatile chtmp_prev=NULL;
unsigned long flags;
save_flags(flags);
ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
ftmp = kmalloc( sizeof(struct ip_fw), GFP_KERNEL );
if ( ftmp == NULL )
{
#ifdef DEBUG_IP_FIREWALL
......@@ -766,7 +777,7 @@ static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
ftmp->fw_next = NULL;
cli();
WRITE_LOCK(&ip_fw_lock);
if ((ftmp->fw_vianame)[0]) {
if (!(ftmp->fw_viadev = dev_get_by_name(ftmp->fw_vianame)))
......@@ -782,7 +793,7 @@ static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
chtmp_prev->fw_next=ftmp;
else
*chainptr=ftmp;
restore_flags(flags);
WRITE_UNLOCK(&ip_fw_lock);
MOD_INC_USE_COUNT;
return(0);
}
......@@ -792,10 +803,8 @@ static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
struct ip_fw *ftmp,*ltmp;
unsigned short tport1,tport2,tmpnum;
char matches,was_found;
unsigned long flags;
save_flags(flags);
cli();
WRITE_LOCK(&ip_fw_lock);
ftmp=*chainptr;
......@@ -804,7 +813,7 @@ static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: chain is empty\n");
#endif
restore_flags(flags);
WRITE_UNLOCK(&ip_fw_lock);
return( EINVAL );
}
......@@ -856,7 +865,7 @@ static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
ftmp = ftmp->fw_next;
}
}
restore_flags(flags);
WRITE_UNLOCK(&ip_fw_lock);
if (was_found) {
MOD_DEC_USE_COUNT;
return 0;
......@@ -1110,7 +1119,6 @@ static int ip_chain_procinfo(int stage, char *buffer, char **start,
{
off_t pos=0, begin=0;
struct ip_fw *i;
unsigned long flags;
int len, p;
int last_len = 0;
......@@ -1147,8 +1155,7 @@ static int ip_chain_procinfo(int stage, char *buffer, char **start,
break;
}
save_flags(flags);
cli();
READ_LOCK(&ip_fw_lock);
while(i!=NULL)
{
......@@ -1177,16 +1184,19 @@ static int ip_chain_procinfo(int stage, char *buffer, char **start,
len = last_len;
break;
}
/* Not possible in 2.3.29+, also allowing read lock instead of write -- JM */
#if 0
else if(reset)
{
/* This needs to be done at this specific place! */
i->fw_pcnt=0L;
i->fw_bcnt=0L;
}
#endif
last_len = len;
i=i->fw_next;
}
restore_flags(flags);
READ_UNLOCK(&ip_fw_lock);
*start=buffer+(offset-begin);
len-=(offset-begin);
if(len>length)
......@@ -1329,12 +1339,10 @@ int ipfw_device_event(struct notifier_block *this, unsigned long event, void *pt
{
struct net_device *dev=ptr;
char *devname = dev->name;
unsigned long flags;
struct ip_fw *fw;
int chn;
save_flags(flags);
cli();
WRITE_LOCK(&ip_fw_lock);
if (event == NETDEV_UP) {
for (chn = 0; chn < IP_FW_CHAINS; chn++)
......@@ -1351,7 +1359,7 @@ int ipfw_device_event(struct notifier_block *this, unsigned long event, void *pt
fw->fw_viadev = (struct net_device*)-1;
}
restore_flags(flags);
WRITE_UNLOCK(&ip_fw_lock);
return NOTIFY_DONE;
}
......
/* iptables module for setting the IPv4 DSCP field, Version 1.8
*
* (C) 2002 by Harald Welte <laforge@gnumonks.org>
* based on ipt_FTOS.c (C) 2000 by Matthew G. Marsh <mgm@paktronix.com>
* This software is distributed under GNU GPL v2, 1991
*
* See RFC2474 for a description of the DSCP field within the IP Header.
*
* ipt_DSCP.c,v 1.8 2002/08/06 18:41:57 laforge Exp
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <net/checksum.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_DSCP.h>
MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
MODULE_DESCRIPTION("IP tables DSCP modification module");
MODULE_LICENSE("GPL");
static unsigned int
target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
const void *targinfo,
void *userinfo)
{
struct iphdr *iph = (*pskb)->nh.iph;
const struct ipt_DSCP_info *dinfo = targinfo;
u_int8_t sh_dscp = ((dinfo->dscp << IPT_DSCP_SHIFT) & IPT_DSCP_MASK);
if ((iph->tos & IPT_DSCP_MASK) != sh_dscp) {
u_int16_t diffs[2];
/* raw socket (tcpdump) may have clone of incoming
* skb: don't disturb it --RR */
if (skb_cloned(*pskb) && !(*pskb)->sk) {
struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
if (!nskb)
return NF_DROP;
kfree_skb(*pskb);
*pskb = nskb;
iph = (*pskb)->nh.iph;
}
diffs[0] = htons(iph->tos) ^ 0xFFFF;
iph->tos = (iph->tos & ~IPT_DSCP_MASK) | sh_dscp;
diffs[1] = htons(iph->tos);
iph->check = csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
iph->check^0xFFFF));
(*pskb)->nfcache |= NFC_ALTERED;
}
return IPT_CONTINUE;
}
static int
checkentry(const char *tablename,
const struct ipt_entry *e,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)
{
const u_int8_t dscp = ((struct ipt_DSCP_info *)targinfo)->dscp;
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_DSCP_info))) {
printk(KERN_WARNING "DSCP: targinfosize %u != %Zu\n",
targinfosize,
IPT_ALIGN(sizeof(struct ipt_DSCP_info)));
return 0;
}
if (strcmp(tablename, "mangle") != 0) {
printk(KERN_WARNING "DSCP: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
return 0;
}
if ((dscp > IPT_DSCP_MAX)) {
printk(KERN_WARNING "DSCP: dscp %x out of range\n", dscp);
return 0;
}
return 1;
}
static struct ipt_target ipt_dscp_reg
= { { NULL, NULL }, "DSCP", target, checkentry, NULL, THIS_MODULE };
static int __init init(void)
{
if (ipt_register_target(&ipt_dscp_reg))
return -EINVAL;
return 0;
}
static void __exit fini(void)
{
ipt_unregister_target(&ipt_dscp_reg);
}
module_init(init);
module_exit(fini);
/* iptables module for the IPv4 and TCP ECN bits, Version 1.5
*
* (C) 2002 by Harald Welte <laforge@gnumonks.org>
*
* This software is distributed under GNU GPL v2, 1991
*
* ipt_ECN.c,v 1.5 2002/08/18 19:36:51 laforge Exp
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <net/checksum.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_ECN.h>
MODULE_LICENSE("GPL");
/* set ECT codepoint from IP header.
* return 0 in case there was no ECT codepoint
* return 1 in case ECT codepoint has been overwritten
* return < 0 in case there was error */
static int inline
set_ect_ip(struct sk_buff **pskb, struct iphdr *iph,
const struct ipt_ECN_info *einfo)
{
if ((iph->tos & IPT_ECN_IP_MASK)
!= (einfo->ip_ect & IPT_ECN_IP_MASK)) {
u_int16_t diffs[2];
/* raw socket (tcpdump) may have clone of incoming
* skb: don't disturb it --RR */
if (skb_cloned(*pskb) && !(*pskb)->sk) {
struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
if (!nskb)
return NF_DROP;
kfree_skb(*pskb);
*pskb = nskb;
iph = (*pskb)->nh.iph;
}
diffs[0] = htons(iph->tos) ^ 0xFFFF;
iph->tos = iph->tos & ~IPT_ECN_IP_MASK;
iph->tos = iph->tos | (einfo->ip_ect & IPT_ECN_IP_MASK);
diffs[1] = htons(iph->tos);
iph->check = csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
iph->check^0xFFFF));
(*pskb)->nfcache |= NFC_ALTERED;
return 1;
}
return 0;
}
static int inline
set_ect_tcp(struct sk_buff **pskb, struct iphdr *iph,
const struct ipt_ECN_info *einfo)
{
struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
u_int16_t *tcpflags = (u_int16_t *)tcph + 6;
u_int16_t diffs[2];
/* raw socket (tcpdump) may have clone of incoming
* skb: don't disturb it --RR */
if (skb_cloned(*pskb) && !(*pskb)->sk) {
struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
if (!nskb)
return NF_DROP;
kfree_skb(*pskb);
*pskb = nskb;
iph = (*pskb)->nh.iph;
}
diffs[0] = *tcpflags;
if (einfo->operation & IPT_ECN_OP_SET_ECE
&& tcph->ece != einfo->proto.tcp.ece) {
tcph->ece = einfo->proto.tcp.ece;
}
if (einfo->operation & IPT_ECN_OP_SET_CWR
&& tcph->cwr != einfo->proto.tcp.cwr) {
tcph->cwr = einfo->proto.tcp.cwr;
}
if (diffs[0] != *tcpflags) {
diffs[0] = htons(diffs[0]) ^ 0xFFFF;
diffs[1] = htons(*tcpflags);
tcph->check = csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
tcph->check^0xFFFF));
(*pskb)->nfcache |= NFC_ALTERED;
return 1;
}
return 0;
}
static unsigned int
target(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
const void *targinfo,
void *userinfo)
{
struct iphdr *iph = (*pskb)->nh.iph;
const struct ipt_ECN_info *einfo = targinfo;
if (einfo->operation & IPT_ECN_OP_SET_IP)
set_ect_ip(pskb, iph, einfo);
if (einfo->operation & (IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR)
&& iph->protocol == IPPROTO_TCP)
set_ect_tcp(pskb, iph, einfo);
return IPT_CONTINUE;
}
static int
checkentry(const char *tablename,
const struct ipt_entry *e,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)
{
const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo;
if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ECN_info))) {
printk(KERN_WARNING "ECN: targinfosize %u != %Zu\n",
targinfosize,
IPT_ALIGN(sizeof(struct ipt_ECN_info)));
return 0;
}
if (strcmp(tablename, "mangle") != 0) {
printk(KERN_WARNING "ECN: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
return 0;
}
if (einfo->operation & IPT_ECN_OP_MASK) {
printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
einfo->operation);
return 0;
}
if (einfo->ip_ect & ~IPT_ECN_IP_MASK) {
printk(KERN_WARNING "ECN: new ECT codepoint %x out of mask\n",
einfo->ip_ect);
return 0;
}
if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR))
&& e->ip.proto != IPPROTO_TCP) {
printk(KERN_WARNING "ECN: cannot use TCP operations on a "
"non-tcp rule\n");
return 0;
}
return 1;
}
static struct ipt_target ipt_ecn_reg
= { { NULL, NULL }, "ECN", target, checkentry, NULL, THIS_MODULE };
static int __init init(void)
{
if (ipt_register_target(&ipt_ecn_reg))
return -EINVAL;
return 0;
}
static void __exit fini(void)
{
ipt_unregister_target(&ipt_ecn_reg);
}
module_init(init);
module_exit(fini);
......@@ -39,7 +39,8 @@ static void send_reset(struct sk_buff *oldskb, int local)
struct tcphdr *otcph, *tcph;
struct rtable *rt;
unsigned int otcplen;
u_int16_t tmp;
u_int16_t tmp_port;
u_int32_t tmp_addr;
int needs_ack;
/* IP header checks: fragment, too short. */
......@@ -74,14 +75,17 @@ static void send_reset(struct sk_buff *oldskb, int local)
#ifdef CONFIG_NETFILTER_DEBUG
nskb->nf_debug = 0;
#endif
nskb->nfmark = 0;
tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
/* Swap source and dest */
nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
tmp = tcph->source;
tmp_addr = nskb->nh.iph->saddr;
nskb->nh.iph->saddr = nskb->nh.iph->daddr;
nskb->nh.iph->daddr = tmp_addr;
tmp_port = tcph->source;
tcph->source = tcph->dest;
tcph->dest = tmp;
tcph->dest = tmp_port;
/* Truncate to length (no data) */
tcph->doff = sizeof(struct tcphdr)/4;
......
......@@ -5,6 +5,7 @@
#include <linux/netfilter_ipv4/ipt_ah.h>
#include <linux/netfilter_ipv4/ip_tables.h>
EXPORT_NO_SYMBOLS;
MODULE_LICENSE("GPL");
#ifdef DEBUG_CONNTRACK
......@@ -90,12 +91,12 @@ checkentry(const char *tablename,
static struct ipt_match ah_match
= { { NULL, NULL }, "ah", &match, &checkentry, NULL, THIS_MODULE };
int __init init(void)
static int __init init(void)
{
return ipt_register_match(&ah_match);
}
void __exit cleanup(void)
static void __exit cleanup(void)
{
ipt_unregister_match(&ah_match);
}
......
/* Kernel module to match connection tracking information.
* Superset of Rusty's minimalistic state match.
* GPL (C) 2001 Marc Boucher (marc@mbsi.ca).
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_conntrack.h>
static int
match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_conntrack_info *sinfo = matchinfo;
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
unsigned int statebit;
ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
#define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
statebit = ct ? IPT_CONNTRACK_STATE_INVALID : IPT_CONNTRACK_STATE_BIT(ctinfo);
if(sinfo->flags & IPT_CONNTRACK_STATE) {
if (ct) {
if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip !=
ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip)
statebit |= IPT_CONNTRACK_STATE_SNAT;
if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip !=
ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip)
statebit |= IPT_CONNTRACK_STATE_DNAT;
}
if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE))
return 0;
}
if(sinfo->flags & IPT_CONNTRACK_PROTO) {
if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO))
return 0;
}
if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) {
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC))
return 0;
}
if(sinfo->flags & IPT_CONNTRACK_ORIGDST) {
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST))
return 0;
}
if(sinfo->flags & IPT_CONNTRACK_REPLSRC) {
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC))
return 0;
}
if(sinfo->flags & IPT_CONNTRACK_REPLDST) {
if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST))
return 0;
}
if(sinfo->flags & IPT_CONNTRACK_STATUS) {
if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS))
return 0;
}
if(sinfo->flags & IPT_CONNTRACK_EXPIRES) {
unsigned long expires;
if(!ct)
return 0;
expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0;
if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES))
return 0;
}
return 1;
}
static int check(const char *tablename,
const struct ipt_ip *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
if (matchsize != IPT_ALIGN(sizeof(struct ipt_conntrack_info)))
return 0;
return 1;
}
static struct ipt_match conntrack_match
= { { NULL, NULL }, "conntrack", &match, &check, NULL, THIS_MODULE };
static int __init init(void)
{
/* NULL if ip_conntrack not a module */
if (ip_conntrack_module)
__MOD_INC_USE_COUNT(ip_conntrack_module);
return ipt_register_match(&conntrack_match);
}
static void __exit fini(void)
{
ipt_unregister_match(&conntrack_match);
if (ip_conntrack_module)
__MOD_DEC_USE_COUNT(ip_conntrack_module);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
/* IP tables module for matching the value of the IPv4 DSCP field
*
* ipt_dscp.c,v 1.3 2002/08/05 19:00:21 laforge Exp
*
* (C) 2002 by Harald Welte <laforge@gnumonks.org>
*
* This software is distributed under the terms GNU GPL
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv4/ipt_dscp.h>
#include <linux/netfilter_ipv4/ip_tables.h>
MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
MODULE_DESCRIPTION("IP tables DSCP matching module");
MODULE_LICENSE("GPL");
static int match(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *matchinfo,
int offset, const void *hdr, u_int16_t datalen,
int *hotdrop)
{
const struct ipt_dscp_info *info = matchinfo;
const struct iphdr *iph = skb->nh.iph;
u_int8_t sh_dscp = ((info->dscp << IPT_DSCP_SHIFT) & IPT_DSCP_MASK);
return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert;
}
static int checkentry(const char *tablename, const struct ipt_ip *ip,
void *matchinfo, unsigned int matchsize,
unsigned int hook_mask)
{
if (matchsize != IPT_ALIGN(sizeof(struct ipt_dscp_info)))
return 0;
return 1;
}
static struct ipt_match dscp_match = { { NULL, NULL }, "dscp", &match,
&checkentry, NULL, THIS_MODULE };
static int __init init(void)
{
return ipt_register_match(&dscp_match);
}
static void __exit fini(void)
{
ipt_unregister_match(&dscp_match);
}
module_init(init);
module_exit(fini);
/* IP tables module for matching the value of the IPv4 and TCP ECN bits
*
* ipt_ecn.c,v 1.3 2002/05/29 15:09:00 laforge Exp
*
* (C) 2002 by Harald Welte <laforge@gnumonks.org>
*
* This software is distributed under the terms GNU GPL v2
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/tcp.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_ecn.h>
MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
MODULE_DESCRIPTION("IP tables ECN matching module");
MODULE_LICENSE("GPL");
static inline int match_ip(const struct sk_buff *skb,
const struct iphdr *iph,
const struct ipt_ecn_info *einfo)
{
return ((iph->tos&IPT_ECN_IP_MASK) == einfo->ip_ect);
}
static inline int match_tcp(const struct sk_buff *skb,
const struct iphdr *iph,
const struct ipt_ecn_info *einfo)
{
struct tcphdr *tcph = (void *)iph + iph->ihl*4;
if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
if (einfo->invert & IPT_ECN_OP_MATCH_ECE) {
if (tcph->ece == 1)
return 0;
} else {
if (tcph->ece == 0)
return 0;
}
}
if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
if (einfo->invert & IPT_ECN_OP_MATCH_CWR) {
if (tcph->cwr == 1)
return 0;
} else {
if (tcph->cwr == 0)
return 0;
}
}
return 1;
}
static int match(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *matchinfo,
int offset, const void *hdr, u_int16_t datalen,
int *hotdrop)
{
const struct ipt_ecn_info *info = matchinfo;
const struct iphdr *iph = skb->nh.iph;
if (info->operation & IPT_ECN_OP_MATCH_IP)
if (!match_ip(skb, iph, info))
return 0;
if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
if (iph->protocol != IPPROTO_TCP)
return 0;
if (!match_tcp(skb, iph, info))
return 0;
}
return 1;
}
static int checkentry(const char *tablename, const struct ipt_ip *ip,
void *matchinfo, unsigned int matchsize,
unsigned int hook_mask)
{
const struct ipt_ecn_info *info = matchinfo;
if (matchsize != IPT_ALIGN(sizeof(struct ipt_ecn_info)))
return 0;
if (info->operation & IPT_ECN_OP_MATCH_MASK)
return 0;
if (info->invert & IPT_ECN_OP_MATCH_MASK)
return 0;
if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)
&& ip->proto != IPPROTO_TCP) {
printk(KERN_WARNING "ipt_ecn: can't match TCP bits in rule for"
" non-tcp packets\n");
return 0;
}
return 1;
}
static struct ipt_match ecn_match = { { NULL, NULL }, "ecn", &match,
&checkentry, NULL, THIS_MODULE };
static int __init init(void)
{
return ipt_register_match(&ecn_match);
}
static void __exit fini(void)
{
ipt_unregister_match(&ecn_match);
}
module_init(init);
module_exit(fini);
......@@ -5,6 +5,7 @@
#include <linux/netfilter_ipv4/ipt_esp.h>
#include <linux/netfilter_ipv4/ip_tables.h>
EXPORT_NO_SYMBOLS;
MODULE_LICENSE("GPL");
#ifdef DEBUG_CONNTRACK
......
/*
* iptables module to match on related connections
* (c) 2001 Martin Josefsson <gandalf@wlug.westbo.se>
*
* Released under the terms of GNU GPLv2.
*
* 19 Mar 2002 Harald Welte <laforge@gnumonks.org>:
* - Port to newnat infrastructure
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_helper.h>
MODULE_LICENSE("GPL");
#if 0
#define DEBUGP printk
#else
#define DEBUGP(format, args...)
#endif
static int
match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_helper_info *info = matchinfo;
struct ip_conntrack_expect *exp;
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
if (!ct) {
DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
return 0;
}
if (!ct->master) {
DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
return 0;
}
exp = ct->master;
if (!exp->expectant) {
DEBUGP("ipt_helper: expectation %p without expectant !?!\n",
exp);
return 0;
}
if (!exp->expectant->helper) {
DEBUGP("ipt_helper: master ct %p has no helper\n",
exp->expectant);
return 0;
}
DEBUGP("master's name = %s , info->name = %s\n",
exp->expectant->helper->name, info->name);
return !strncmp(exp->expectant->helper->name, info->name,
strlen(exp->expectant->helper->name)) ^ info->invert;
}
static int check(const char *tablename,
const struct ipt_ip *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
struct ipt_helper_info *info = matchinfo;
info->name[29] = '\0';
/* verify size */
if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info)))
return 0;
/* verify that we actually should match anything */
if ( strlen(info->name) == 0 )
return 0;
return 1;
}
static struct ipt_match helper_match
= { { NULL, NULL }, "helper", &match, &check, NULL, THIS_MODULE };
static int __init init(void)
{
/* NULL if ip_conntrack not a module */
if (ip_conntrack_module)
__MOD_INC_USE_COUNT(ip_conntrack_module);
return ipt_register_match(&helper_match);
}
static void __exit fini(void)
{
ipt_unregister_match(&helper_match);
if (ip_conntrack_module)
__MOD_DEC_USE_COUNT(ip_conntrack_module);
}
module_init(init);
module_exit(fini);
......@@ -11,6 +11,38 @@
#include <linux/netfilter_ipv4/ipt_owner.h>
#include <linux/netfilter_ipv4/ip_tables.h>
static int
match_comm(const struct sk_buff *skb, const char *comm)
{
struct task_struct *p;
struct files_struct *files;
int i;
read_lock(&tasklist_lock);
for_each_task(p) {
if(strncmp(p->comm, comm, sizeof(p->comm)))
continue;
task_lock(p);
files = p->files;
if(files) {
read_lock(&files->file_lock);
for (i=0; i < files->max_fds; i++) {
if (fcheck_files(files, i) == skb->sk->socket->file) {
read_unlock(&files->file_lock);
task_unlock(p);
read_unlock(&tasklist_lock);
return 1;
}
}
read_unlock(&files->file_lock);
}
task_unlock(p);
}
read_unlock(&tasklist_lock);
return 0;
}
static int
match_pid(const struct sk_buff *skb, pid_t pid)
{
......@@ -115,6 +147,12 @@ match(const struct sk_buff *skb,
return 0;
}
if(info->match & IPT_OWNER_COMM) {
if (!match_comm(skb, info->comm) ^
!!(info->invert & IPT_OWNER_COMM))
return 0;
}
return 1;
}
......
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/netfilter_ipv4/ipt_pkttype.h>
#include <linux/netfilter_ipv4/ip_tables.h>
MODULE_LICENSE("GPL");
static int match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ipt_pkttype_info *info = matchinfo;
return (skb->pkt_type == info->pkttype) ^ info->invert;
}
static int checkentry(const char *tablename,
const struct ipt_ip *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
/*
if (hook_mask
& ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN)
| (1 << NF_IP_FORWARD))) {
printk("ipt_pkttype: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n");
return 0;
}
*/
if (matchsize != IPT_ALIGN(sizeof(struct ipt_pkttype_info)))
return 0;
return 1;
}
static struct ipt_match pkttype_match
= { { NULL, NULL }, "pkttype", &match, &checkentry, NULL, THIS_MODULE };
static int __init init(void)
{
return ipt_register_match(&pkttype_match);
}
static void __exit fini(void)
{
ipt_unregister_match(&pkttype_match);
}
module_init(init);
module_exit(fini);
......@@ -66,7 +66,8 @@ static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
r->tcpdiag_retrans = 0;
r->id.tcpdiag_if = sk->bound_dev_if;
*((struct sock **)&r->id.tcpdiag_cookie) = sk;
r->id.tcpdiag_cookie[0] = (u32)(unsigned long)sk;
r->id.tcpdiag_cookie[1] = (u32)(((unsigned long)sk >> 31) >> 1);
if (r->tcpdiag_state == TCP_TIME_WAIT) {
struct tcp_tw_bucket *tw = (struct tcp_tw_bucket*)sk;
......@@ -237,7 +238,8 @@ static int tcpdiag_get_exact(struct sk_buff *in_skb, struct nlmsghdr *nlh)
err = -ESTALE;
if ((req->id.tcpdiag_cookie[0] != TCPDIAG_NOCOOKIE ||
req->id.tcpdiag_cookie[1] != TCPDIAG_NOCOOKIE) &&
sk != *((struct sock **)&req->id.tcpdiag_cookie[0]))
((u32)(unsigned long)sk != req->id.tcpdiag_cookie[0] ||
(u32)((((unsigned long)sk) >> 31) >> 1) != req->id.tcpdiag_cookie[1]))
goto out;
err = -ENOMEM;
......
CONFIG_IP6_NF_MATCH_EUI64
This module performs checking on the IPv6 source address
Compares the last 64 bits with the EUI64 (delivered
from the MAC address) address
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
CONFIG_IP6_NF_MATCH_MAC
mac matching allows you to match packets based on the source
Ethernet address of the packet.
......@@ -5,6 +13,13 @@ CONFIG_IP6_NF_MATCH_MAC
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
CONFIG_IP6_NF_MATCH_LENGTH
This option allows you to match the length of a packet against a
specific value or range of values.
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
CONFIG_IP6_NF_MATCH_MARK
Netfilter mark matching allows you to match packets based on the
`nfmark' value in the packet. This can be set by the MARK target
......
......@@ -24,6 +24,10 @@ if [ "$CONFIG_IP6_NF_IPTABLES" != "n" ]; then
fi
# dep_tristate ' MAC address match support' CONFIG_IP6_NF_MATCH_MAC $CONFIG_IP6_NF_IPTABLES
dep_tristate ' netfilter MARK match support' CONFIG_IP6_NF_MATCH_MARK $CONFIG_IP6_NF_IPTABLES
dep_tristate ' Packet Length match support' CONFIG_IP6_NF_MATCH_LENGTH $CONFIG_IP6_NF_IPTABLES
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_tristate ' EUI64 address check (EXPERIMENTAL)' CONFIG_IP6_NF_MATCH_EUI64 $CONFIG_IP6_NF_IPTABLES
fi
# dep_tristate ' Multiple port match support' CONFIG_IP6_NF_MATCH_MULTIPORT $CONFIG_IP6_NF_IPTABLES
# dep_tristate ' TOS match support' CONFIG_IP6_NF_MATCH_TOS $CONFIG_IP6_NF_IPTABLES
# if [ "$CONFIG_IP6_NF_CONNTRACK" != "n" ]; then
......
......@@ -8,7 +8,9 @@ export-objs := ip6_tables.o
obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o
obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o
obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
......
......@@ -7,6 +7,8 @@
* 19 Jan 2002 Harald Welte <laforge@gnumonks.org>
* - increase module usage count as soon as we have rules inside
* a table
* 06 Jun 2002 Andras Kis-Szabo <kisza@sch.bme.hu>
* - new extension header parser code
*/
#include <linux/config.h>
#include <linux/skbuff.h>
......@@ -25,6 +27,7 @@
#include <linux/netfilter_ipv6/ip6_tables.h>
#define IPV6_HDR_LEN (sizeof(struct ipv6hdr))
#define IPV6_OPTHDR_LEN (sizeof(struct ipv6_opt_hdr))
/*#define DEBUG_IP_FIREWALL*/
/*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */
......@@ -133,43 +136,23 @@ static int ip6_masked_addrcmp(struct in6_addr addr1, struct in6_addr mask,
return 0;
}
/* takes in current header and pointer to the header */
/* if another header exists, sets hdrptr to the next header
and returns the new header value, else returns 0 */
static u_int8_t ip6_nexthdr(u_int8_t currenthdr, u_int8_t *hdrptr)
/* Check for an extension */
int
ip6t_ext_hdr(u8 nexthdr)
{
int i;
u_int8_t hdrlen, nexthdr = 0;
switch(currenthdr){
case IPPROTO_AH:
/* whoever decided to do the length of AUTH for ipv6
in 32bit units unlike other headers should be beaten...
repeatedly...with a large stick...no, an even LARGER
stick...no, you're still not thinking big enough */
nexthdr = *hdrptr;
hdrlen = hdrptr[i] * 4 + 8;
hdrptr = hdrptr + hdrlen;
break;
/*stupid rfc2402 */
case IPPROTO_DSTOPTS:
case IPPROTO_ROUTING:
case IPPROTO_HOPOPTS:
nexthdr = *hdrptr;
hdrlen = hdrptr[1] * 8 + 8;
hdrptr = hdrptr + hdrlen;
break;
case IPPROTO_FRAGMENT:
nexthdr = *hdrptr;
hdrptr = hdrptr + 8;
break;
}
return nexthdr;
return ( (nexthdr == IPPROTO_HOPOPTS) ||
(nexthdr == IPPROTO_ROUTING) ||
(nexthdr == IPPROTO_FRAGMENT) ||
(nexthdr == IPPROTO_ESP) ||
(nexthdr == IPPROTO_AH) ||
(nexthdr == IPPROTO_NONE) ||
(nexthdr == IPPROTO_DSTOPTS) );
}
/* Returns whether matches rule or not. */
static inline int
ip6_packet_match(const struct ipv6hdr *ipv6,
ip6_packet_match(const struct sk_buff *skb,
const struct ipv6hdr *ipv6,
const char *indev,
const char *outdev,
const struct ip6t_ip6 *ip6info,
......@@ -227,17 +210,58 @@ ip6_packet_match(const struct ipv6hdr *ipv6,
/* look for the desired protocol header */
if((ip6info->flags & IP6T_F_PROTO)) {
u_int8_t currenthdr = ipv6->nexthdr;
u_int8_t *hdrptr;
hdrptr = (u_int8_t *)(ipv6 + 1);
do {
if (ip6info->proto == currenthdr) {
if(ip6info->invflags & IP6T_INV_PROTO)
return 0;
return 1;
struct ipv6_opt_hdr *hdrptr;
u_int16_t ptr; /* Header offset in skb */
u_int16_t hdrlen; /* Header */
ptr = IPV6_HDR_LEN;
while (ip6t_ext_hdr(currenthdr)) {
/* Is there enough space for the next ext header? */
if (skb->len - ptr < IPV6_OPTHDR_LEN)
return 0;
/* NONE or ESP: there isn't protocol part */
/* If we want to count these packets in '-p all',
* we will change the return 0 to 1*/
if ((currenthdr == IPPROTO_NONE) ||
(currenthdr == IPPROTO_ESP))
return 0;
hdrptr = (struct ipv6_opt_hdr *)(skb->data + ptr);
/* Size calculation */
if (currenthdr == IPPROTO_FRAGMENT) {
hdrlen = 8;
} else if (currenthdr == IPPROTO_AH)
hdrlen = (hdrptr->hdrlen+2)<<2;
else
hdrlen = ipv6_optlen(hdrptr);
currenthdr = hdrptr->nexthdr;
ptr += hdrlen;
/* ptr is too large */
if ( ptr > skb->len )
return 0;
}
/* currenthdr contains the protocol header */
dprintf("Packet protocol %hi ?= %s%hi.\n",
currenthdr,
ip6info->invflags & IP6T_INV_PROTO ? "!":"",
ip6info->proto);
if (ip6info->proto == currenthdr) {
if(ip6info->invflags & IP6T_INV_PROTO) {
return 0;
}
currenthdr = ip6_nexthdr(currenthdr, hdrptr);
} while(currenthdr);
if (!(ip6info->invflags & IP6T_INV_PROTO))
return 1;
}
/* We need match for the '-p all', too! */
if ((ip6info->proto != 0) &&
!(ip6info->invflags & IP6T_INV_PROTO))
return 0;
}
return 1;
......@@ -359,7 +383,8 @@ ip6t_do_table(struct sk_buff **pskb,
IP_NF_ASSERT(e);
IP_NF_ASSERT(back);
(*pskb)->nfcache |= e->nfcache;
if (ip6_packet_match(ipv6, indev, outdev, &e->ipv6, offset)) {
if (ip6_packet_match(*pskb, ipv6, indev, outdev,
&e->ipv6, offset)) {
struct ip6t_entry_target *t;
if (IP6T_MATCH_ITERATE(e, do_match,
......@@ -1826,6 +1851,7 @@ EXPORT_SYMBOL(ip6t_register_match);
EXPORT_SYMBOL(ip6t_unregister_match);
EXPORT_SYMBOL(ip6t_register_target);
EXPORT_SYMBOL(ip6t_unregister_target);
EXPORT_SYMBOL(ip6t_ext_hdr);
module_init(init);
module_exit(fini);
......
/* Kernel module to match EUI64 address parameters. */
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/if_ether.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
static int
match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
unsigned char eui64[8];
int i=0;
if ( !(skb->mac.raw >= skb->head
&& (skb->mac.raw + ETH_HLEN) <= skb->data)
&& offset != 0) {
*hotdrop = 1;
return 0;
}
memset(eui64, 0, sizeof(eui64));
if (skb->mac.ethernet->h_proto == ntohs(ETH_P_IPV6)) {
if (skb->nh.ipv6h->version == 0x6) {
memcpy(eui64, skb->mac.ethernet->h_source, 3);
memcpy(eui64 + 5, skb->mac.ethernet->h_source + 3, 3);
eui64[3]=0xff;
eui64[4]=0xfe;
eui64[0] |= 0x02;
i=0;
while ((skb->nh.ipv6h->saddr.in6_u.u6_addr8[8+i] ==
eui64[i]) && (i<8)) i++;
if ( i == 8 )
return 1;
}
}
return 0;
}
static int
ip6t_eui64_checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
if (hook_mask
& ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) |
(1 << NF_IP6_PRE_ROUTING) )) {
printk("ip6t_eui64: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n");
return 0;
}
if (matchsize != IP6T_ALIGN(sizeof(int)))
return 0;
return 1;
}
static struct ip6t_match eui64_match
= { { NULL, NULL }, "eui64", &match, &ip6t_eui64_checkentry, NULL, THIS_MODULE };
static int __init init(void)
{
return ip6t_register_match(&eui64_match);
}
static void __exit fini(void)
{
ip6t_unregister_match(&eui64_match);
}
module_init(init);
module_exit(fini);
MODULE_DESCRIPTION("IPv6 EUI64 address checking match");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
/* Length Match - IPv6 Port */
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv6/ip6t_length.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
static int
match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
const void *hdr,
u_int16_t datalen,
int *hotdrop)
{
const struct ip6t_length_info *info = matchinfo;
u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr);
return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
}
static int
checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_length_info)))
return 0;
return 1;
}
static struct ip6t_match length_match
= { { NULL, NULL }, "length", &match, &checkentry, NULL, THIS_MODULE };
static int __init init(void)
{
return ip6t_register_match(&length_match);
}
static void __exit fini(void)
{
ip6t_unregister_match(&length_match);
}
module_init(init);
module_exit(fini);
......@@ -27,7 +27,7 @@
static void llc_station_ack_tmr_callback(unsigned long timeout_data);
int llc_station_ac_start_ack_timer(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
del_timer(&station->ack_timer);
station->ack_timer.expires = jiffies + LLC_ACK_TIME * HZ;
......@@ -39,98 +39,94 @@ int llc_station_ac_start_ack_timer(struct llc_station *station,
}
int llc_station_ac_set_retry_cnt_0(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
station->retry_count = 0;
return 0;
}
int llc_station_ac_inc_retry_cnt_by_1(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
station->retry_count++;
return 0;
}
int llc_station_ac_set_xid_r_cnt_0(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
station->xid_r_count = 0;
return 0;
}
int llc_station_ac_inc_xid_r_cnt_by_1(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
station->xid_r_count++;
return 0;
}
int llc_station_ac_send_null_dsap_xid_c(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (!skb)
if (!nskb)
goto out;
rc = 0;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 127);
lan_hdrs_init(skb, station->mac_sa, station->mac_sa);
llc_station_send_pdu(station, skb);
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127);
lan_hdrs_init(nskb, station->mac_sa, station->mac_sa);
llc_station_send_pdu(station, nskb);
out:
return rc;
}
int llc_station_ac_send_xid_r(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
u8 mac_da[ETH_ALEN], dsap;
int rc = 1;
struct sk_buff *ev_skb;
struct sk_buff* skb = llc_alloc_frame();
struct sk_buff* nskb = llc_alloc_frame();
if (!skb)
if (!nskb)
goto out;
rc = 0;
ev_skb = ev->data.pdu.skb;
skb->dev = ev_skb->dev;
llc_pdu_decode_sa(ev_skb, mac_da);
llc_pdu_decode_ssap(ev_skb, &dsap);
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
llc_pdu_init_as_xid_rsp(skb, LLC_XID_NULL_CLASS_2, 127);
lan_hdrs_init(skb, station->mac_sa, mac_da);
llc_station_send_pdu(station, skb);
nskb->dev = skb->dev;
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);
lan_hdrs_init(nskb, station->mac_sa, mac_da);
llc_station_send_pdu(station, nskb);
out:
return rc;
}
int llc_station_ac_send_test_r(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
u8 mac_da[ETH_ALEN], dsap;
int rc = 1;
struct sk_buff *ev_skb;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (!skb)
if (!nskb)
goto out;
rc = 0;
ev_skb = ev->data.pdu.skb;
skb->dev = ev_skb->dev;
llc_pdu_decode_sa(ev_skb, mac_da);
llc_pdu_decode_ssap(ev_skb, &dsap);
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
llc_pdu_init_as_test_rsp(skb, ev_skb);
lan_hdrs_init(skb, station->mac_sa, mac_da);
llc_station_send_pdu(station, skb);
nskb->dev = skb->dev;
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);
lan_hdrs_init(nskb, station->mac_sa, mac_da);
llc_station_send_pdu(station, nskb);
out:
return rc;
}
int llc_station_ac_report_status(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
return 0;
}
......@@ -138,13 +134,14 @@ int llc_station_ac_report_status(struct llc_station *station,
static void llc_station_ack_tmr_callback(unsigned long timeout_data)
{
struct llc_station *station = (struct llc_station *)timeout_data;
struct llc_station_state_ev *ev;
struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC);
station->ack_tmr_running = 0;
ev = llc_station_alloc_ev(station);
if (ev) {
if (skb) {
struct llc_station_state_ev *ev = llc_station_ev(skb);
ev->type = LLC_STATION_EV_TYPE_ACK_TMR;
ev->data.tmr.timer_specific = NULL;
llc_station_send_ev(station, ev);
llc_station_send_ev(station, skb);
}
}
......@@ -32,22 +32,19 @@ static void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data);
static void llc_conn_ack_tmr_cb(unsigned long timeout_data);
static void llc_conn_rej_tmr_cb(unsigned long timeout_data);
static void llc_conn_busy_tmr_cb(unsigned long timeout_data);
static int llc_conn_ac_inc_vs_by_1(struct sock *sk,
struct llc_conn_state_ev *ev);
static void llc_process_tmr_ev(struct sock *sk, struct llc_conn_state_ev *ev);
static int llc_conn_ac_data_confirm(struct sock *sk,
struct llc_conn_state_ev *ev);
static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb);
static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb);
static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *ev);
#define INCORRECT 0
int llc_conn_ac_clear_remote_busy(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
if (llc->remote_busy_flag) {
u8 nr;
struct llc_pdu_sn *pdu =
(struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
llc->remote_busy_flag = 0;
del_timer(&llc->busy_state_timer.timer);
......@@ -58,16 +55,16 @@ int llc_conn_ac_clear_remote_busy(struct sock *sk, struct llc_conn_state_ev *ev)
return 0;
}
int llc_conn_ac_conn_ind(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
u8 dsap;
struct sk_buff *skb = ev->data.pdu.skb;
struct llc_sap *sap;
llc_pdu_decode_dsap(skb, &dsap);
sap = llc_sap_find(dsap);
if (sap) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_prim_if_block *prim = &sap->llc_ind_prim;
union llc_u_prim_data *prim_data = prim->data;
struct llc_opt *llc = llc_sk(sk);
......@@ -91,9 +88,9 @@ int llc_conn_ac_conn_ind(struct sock *sk, struct llc_conn_state_ev *ev)
return rc;
}
int llc_conn_ac_conn_confirm(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb)
{
struct sk_buff *skb = ev->data.pdu.skb;
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
struct llc_prim_if_block *prim = &sap->llc_cfm_prim;
......@@ -103,10 +100,7 @@ int llc_conn_ac_conn_confirm(struct sock *sk, struct llc_conn_state_ev *ev)
prim_data->conn.pri = 0;
prim_data->conn.status = ev->status;
prim_data->conn.link = llc->link;
if (skb)
prim_data->conn.dev = skb->dev;
else
printk(KERN_ERR "%s: ev->data.pdu.skb == NULL\n", __FUNCTION__);
prim_data->conn.dev = skb->dev;
prim->data = prim_data;
prim->prim = LLC_CONN_PRIM;
prim->sap = sap;
......@@ -115,9 +109,9 @@ int llc_conn_ac_conn_confirm(struct sock *sk, struct llc_conn_state_ev *ev)
return 0;
}
static int llc_conn_ac_data_confirm(struct sock *sk,
struct llc_conn_state_ev *ev)
static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
struct llc_prim_if_block *prim = &sap->llc_cfm_prim;
......@@ -136,19 +130,20 @@ static int llc_conn_ac_data_confirm(struct sock *sk,
return 0;
}
int llc_conn_ac_data_ind(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_data_ind(struct sock *sk, struct sk_buff *skb)
{
llc_conn_rtn_pdu(sk, ev->data.pdu.skb, ev);
llc_conn_rtn_pdu(sk, skb);
return 0;
}
int llc_conn_ac_disc_ind(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
u8 reason = 0;
int rc = 1;
if (ev->type == LLC_CONN_EV_TYPE_PDU) {
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.skb);
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
if (!LLC_PDU_IS_RSP(pdu) &&
!LLC_PDU_TYPE_IS_U(pdu) &&
......@@ -186,8 +181,9 @@ int llc_conn_ac_disc_ind(struct sock *sk, struct llc_conn_state_ev *ev)
return rc;
}
int llc_conn_ac_disc_confirm(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
struct llc_prim_if_block *prim = &sap->llc_cfm_prim;
......@@ -204,11 +200,12 @@ int llc_conn_ac_disc_confirm(struct sock *sk, struct llc_conn_state_ev *ev)
return 0;
}
int llc_conn_ac_rst_ind(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
{
u8 reason = 0;
int rc = 1;
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.skb);
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
struct llc_opt *llc = llc_sk(sk);
switch (ev->type) {
......@@ -257,8 +254,9 @@ int llc_conn_ac_rst_ind(struct sock *sk, struct llc_conn_state_ev *ev)
return rc;
}
int llc_conn_ac_rst_confirm(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_rst_confirm(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
struct llc_prim_if_block *prim = &sap->llc_cfm_prim;
......@@ -274,210 +272,201 @@ int llc_conn_ac_rst_confirm(struct sock *sk, struct llc_conn_state_ev *ev)
return 0;
}
int llc_conn_ac_report_status(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_report_status(struct sock *sk, struct sk_buff *skb)
{
return 0;
}
int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
if (!LLC_PDU_IS_RSP(pdu) &&
!LLC_PDU_TYPE_IS_I(pdu) &&
!LLC_I_PF_IS_1(pdu) && llc_sk(sk)->ack_pf)
llc_conn_ac_clear_remote_busy(sk, ev);
llc_conn_ac_clear_remote_busy(sk, skb);
return 0;
}
int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
if (llc_sk(sk)->data_flag == 2) {
del_timer(&llc_sk(sk)->rej_sent_timer.timer);
llc_sk(sk)->rej_sent_timer.running = 0;
struct llc_opt *llc = llc_sk(sk);
if (llc->data_flag == 2) {
del_timer(&llc->rej_sent_timer.timer);
llc->rej_sent_timer.running = 0;
}
return 0;
}
int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
u8 p_bit = 1;
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_disc_cmd(skb, p_bit);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_disc_cmd(nskb, p_bit);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
llc_conn_ac_set_p_flag_1(sk, ev);
llc_conn_ac_set_p_flag_1(sk, skb);
return rc;
}
int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
struct sk_buff *rx_skb = ev->data.pdu.skb;
u8 f_bit;
skb->dev = llc->dev;
llc_pdu_decode_pf_bit(rx_skb, &f_bit);
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_decode_pf_bit(skb, &f_bit);
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_dm_rsp(skb, f_bit);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_dm_rsp(nskb, f_bit);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit = 1;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_dm_rsp(skb, f_bit);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_dm_rsp(nskb, f_bit);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_dm_rsp_f_set_f_flag(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_dm_rsp_f_set_f_flag(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit = llc->f_flag;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_dm_rsp(skb, f_bit);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_dm_rsp(nskb, f_bit);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
{
u8 f_bit;
int rc = 1;
struct sk_buff *skb, *ev_skb = ev->data.pdu.skb;
struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev_skb->nh.raw;
struct sk_buff *nskb;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
struct llc_opt *llc = llc_sk(sk);
llc->rx_pdu_hdr = *((u32 *)pdu);
if (!LLC_PDU_IS_CMD(pdu))
llc_pdu_decode_pf_bit(ev_skb, &f_bit);
llc_pdu_decode_pf_bit(skb, &f_bit);
else
f_bit = 0;
skb = llc_alloc_frame();
if (skb) {
nskb = llc_alloc_frame();
if (nskb) {
struct llc_sap *sap = llc->sap;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_frmr_rsp(skb, pdu, f_bit, llc->vS,
llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
llc->vR, INCORRECT);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
u8 f_bit = 0;
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_frmr_rsp(skb, pdu, f_bit, llc->vS,
llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
llc->vR, INCORRECT);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
{
u8 f_bit;
int rc = 1;
struct sk_buff *skb;
struct sk_buff *nskb;
llc_pdu_decode_pf_bit(ev->data.pdu.skb, &f_bit);
skb = llc_alloc_frame();
if (skb) {
llc_pdu_decode_pf_bit(skb, &f_bit);
nskb = llc_alloc_frame();
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
struct llc_pdu_sn *pdu =
(struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_frmr_rsp(skb, pdu, f_bit, llc->vS,
llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
llc->vR, INCORRECT);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{
u8 p_bit = 1;
struct sk_buff *skb = ev->data.prim.data->data->data.skb;
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
......@@ -486,15 +475,13 @@ int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk,
llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_conn_send_pdu(sk, skb);
llc_conn_ac_inc_vs_by_1(sk, ev);
llc_conn_ac_inc_vs_by_1(sk, skb);
return 0;
}
int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
{
u8 p_bit = 0;
struct sk_buff *skb = ev->data.prim.data->data->data.skb;
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
......@@ -503,14 +490,13 @@ int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk,
llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_conn_send_pdu(sk, skb);
llc_conn_ac_inc_vs_by_1(sk, ev);
llc_conn_ac_inc_vs_by_1(sk, skb);
return 0;
}
int llc_conn_ac_resend_i_cmd_p_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_resend_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 nr = LLC_I_GET_NR(pdu);
llc_conn_resend_i_pdu_as_cmd(sk, nr, 1);
......@@ -518,22 +504,20 @@ int llc_conn_ac_resend_i_cmd_p_set_1(struct sock *sk,
}
int llc_conn_ac_resend_i_cmd_p_set_1_or_send_rr(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 nr = LLC_I_GET_NR(pdu);
int rc = llc_conn_ac_send_rr_cmd_p_set_1(sk, ev);
int rc = llc_conn_ac_send_rr_cmd_p_set_1(sk, skb);
if (!rc)
llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
return rc;
}
int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
u8 p_bit = 0;
struct sk_buff *skb = ev->data.prim.data->data->data.skb;
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
......@@ -542,14 +526,13 @@ int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk,
llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_conn_send_pdu(sk, skb);
llc_conn_ac_inc_vs_by_1(sk, ev);
llc_conn_ac_inc_vs_by_1(sk, skb);
return 0;
}
int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 nr = LLC_I_GET_NR(pdu);
llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
......@@ -557,25 +540,25 @@ int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk,
}
int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
u8 nr;
u8 f_bit = 0;
struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
if (rc) {
nr = LLC_I_GET_NR(pdu);
......@@ -585,149 +568,142 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
return rc;
}
int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 nr = LLC_I_GET_NR(pdu);
llc_conn_resend_i_pdu_as_rsp(sk, nr, 1);
return 0;
}
int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 p_bit = 1;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_rej_cmd(skb, p_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rej_cmd(nskb, p_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
u8 f_bit = 1;
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rej_rsp(skb, f_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit = 0;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rej_rsp(skb, f_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 p_bit = 1;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_rnr_cmd(skb, p_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rnr_cmd(nskb, p_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit = 1;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rnr_rsp(skb, f_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
u8 f_bit = 0;
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rnr_rsp(skb, f_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_set_remote_busy(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
......@@ -743,246 +719,234 @@ int llc_conn_ac_set_remote_busy(struct sock *sk, struct llc_conn_state_ev *ev)
return 0;
}
int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit = 0;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rnr_rsp(skb, f_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
u8 p_bit = 1;
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_rr_cmd(skb, p_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rr_cmd(nskb, p_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_ack_cmd_p_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_ack_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
u8 p_bit = 1;
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_rr_cmd(skb, p_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rr_cmd(nskb, p_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit = 1;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit = 1;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit = 0;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit = 0;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
struct llc_opt *llc = llc_sk(sk);
u8 p_bit = 1;
if (skb) {
if (nskb) {
struct llc_sap *sap = llc->sap;
u8 *dmac = llc->daddr.mac;
if (llc->dev->flags & IFF_LOOPBACK)
dmac = llc->dev->dev_addr;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_sabme_cmd(skb, p_bit);
lan_hdrs_init(skb, llc->dev->dev_addr, dmac);
llc_pdu_init_as_sabme_cmd(nskb, p_bit);
lan_hdrs_init(nskb, llc->dev->dev_addr, dmac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
llc->p_flag = p_bit;
return rc;
}
int llc_conn_ac_send_ua_rsp_f_set_f_flag(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_ua_rsp_f_set_f_flag(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit = llc->f_flag;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_ua_rsp(skb, f_bit);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_ua_rsp(nskb, f_bit);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
{
u8 f_bit;
int rc = 1;
struct sk_buff *rx_skb = ev->data.pdu.skb;
struct sk_buff *skb;
struct sk_buff *nskb = llc_alloc_frame();
llc_pdu_decode_pf_bit(rx_skb, &f_bit);
skb = llc_alloc_frame();
if (skb) {
llc_pdu_decode_pf_bit(skb, &f_bit);
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_ua_rsp(skb, f_bit);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_ua_rsp(nskb, f_bit);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
int llc_conn_ac_set_s_flag_0(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->s_flag = 0;
return 0;
}
int llc_conn_ac_set_s_flag_1(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_s_flag_1(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->s_flag = 1;
return 0;
}
int llc_conn_ac_start_p_timer(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
......@@ -1000,18 +964,16 @@ int llc_conn_ac_start_p_timer(struct sock *sk, struct llc_conn_state_ev *ev)
/**
* llc_conn_ac_send_ack_if_needed - check if ack is needed
* @sk: current connection structure
* @ev: current event
* @skb: current event
*
* Checks number of received PDUs which have not been acknowledged, yet,
* If number of them reaches to "npta"(Number of PDUs To Acknowledge) then
* sends an RR response as acknowledgement for them. Returns 0 for
* success, 1 otherwise.
*/
int llc_conn_ac_send_ack_if_needed(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_ack_if_needed(struct sock *sk, struct sk_buff *skb)
{
u8 pf_bit;
struct sk_buff *skb = ev->data.pdu.skb;
struct llc_opt *llc = llc_sk(sk);
llc_pdu_decode_pf_bit(skb, &pf_bit);
......@@ -1022,10 +984,10 @@ int llc_conn_ac_send_ack_if_needed(struct sock *sk,
llc->ack_pf = pf_bit & 1;
}
if (((llc->vR - llc->first_pdu_Ns + 129) % 128) >= llc->npta) {
llc_conn_ac_send_rr_rsp_f_set_ackpf(sk, ev);
llc_conn_ac_send_rr_rsp_f_set_ackpf(sk, skb);
llc->ack_must_be_send = 0;
llc->ack_pf = 0;
llc_conn_ac_inc_npta_value(sk, ev);
llc_conn_ac_inc_npta_value(sk, skb);
}
return 0;
}
......@@ -1033,14 +995,13 @@ int llc_conn_ac_send_ack_if_needed(struct sock *sk,
/**
* llc_conn_ac_rst_sendack_flag - resets ack_must_be_send flag
* @sk: current connection structure
* @ev: current event
* @skb: current event
*
* This action resets ack_must_be_send flag of given connection, this flag
* indicates if there is any PDU which has not been acknowledged yet.
* Returns 0 for success, 1 otherwise.
*/
int llc_conn_ac_rst_sendack_flag(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->ack_must_be_send = llc_sk(sk)->ack_pf = 0;
return 0;
......@@ -1049,17 +1010,15 @@ int llc_conn_ac_rst_sendack_flag(struct sock *sk,
/**
* llc_conn_ac_send_i_rsp_f_set_ackpf - acknowledge received PDUs
* @sk: current connection structure
* @ev: current event
* @skb: current event
*
* Sends an I response PDU with f-bit set to ack_pf flag as acknowledge to
* all received PDUs which have not been acknowledged, yet. ack_pf flag is
* set to one if one PDU with p-bit set to one is received. Returns 0 for
* success, 1 otherwise.
*/
int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk, struct sk_buff *skb)
{
struct sk_buff *skb = ev->data.prim.data->data->data.skb;
struct llc_opt *llc = llc_sk(sk);
u8 p_bit = llc->ack_pf;
struct llc_sap *sap = llc->sap;
......@@ -1069,61 +1028,60 @@ int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_conn_send_pdu(sk, skb);
llc_conn_ac_inc_vs_by_1(sk, ev);
llc_conn_ac_inc_vs_by_1(sk, skb);
return 0;
}
/**
* llc_conn_ac_send_i_as_ack - sends an I-format PDU to acknowledge rx PDUs
* @sk: current connection structure.
* @ev: current event.
* @skb: current event.
*
* This action sends an I-format PDU as acknowledge to received PDUs which
* have not been acknowledged, yet, if there is any. By using of this
* action number of acknowledgements decreases, this technic is called
* piggy backing. Returns 0 for success, 1 otherwise.
*/
int llc_conn_ac_send_i_as_ack(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
if (llc->ack_must_be_send) {
llc_conn_ac_send_i_rsp_f_set_ackpf(sk, ev);
llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
llc->ack_must_be_send = 0 ;
llc->ack_pf = 0;
} else
llc_conn_ac_send_i_cmd_p_set_0(sk, ev);
llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
return 0;
}
/**
* llc_conn_ac_send_rr_rsp_f_set_ackpf - ack all rx PDUs not yet acked
* @sk: current connection structure.
* @ev: current event.
* @skb: current event.
*
* This action sends an RR response with f-bit set to ack_pf flag as
* acknowledge to all received PDUs which have not been acknowledged, yet,
* if there is any. ack_pf flag indicates if a PDU has been received with
* p-bit set to one. Returns 0 for success, 1 otherwise.
*/
int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct sk_buff *skb = llc_alloc_frame();
struct sk_buff *nskb = llc_alloc_frame();
if (skb) {
if (nskb) {
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
u8 f_bit = llc->ack_pf;
skb->dev = llc->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
nskb->dev = llc->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
llc->daddr.lsap, LLC_PDU_RSP);
llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR);
lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
lan_hdrs_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
rc = 0;
llc_conn_send_pdu(sk, skb);
llc_conn_send_pdu(sk, nskb);
}
return rc;
}
......@@ -1131,14 +1089,14 @@ int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
/**
* llc_conn_ac_inc_npta_value - tries to make value of npta greater
* @sk: current connection structure.
* @ev: current event.
* @skb: current event.
*
* After "inc_cntr" times calling of this action, "npta" increase by one.
* this action tries to make vale of "npta" greater as possible; number of
* acknowledgements decreases by increasing of "npta". Returns 0 for
* success, 1 otherwise.
*/
int llc_conn_ac_inc_npta_value(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
......@@ -1156,12 +1114,12 @@ int llc_conn_ac_inc_npta_value(struct sock *sk, struct llc_conn_state_ev *ev)
/**
* llc_conn_ac_adjust_npta_by_rr - decreases "npta" by one
* @sk: current connection structure.
* @ev: current event.
* @skb: current event.
*
* After receiving "dec_cntr" times RR command, this action decreases
* "npta" by one. Returns 0 for success, 1 otherwise.
*/
int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
......@@ -1182,13 +1140,12 @@ int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct llc_conn_state_ev *ev)
/**
* llc_conn_ac_adjust_npta_by_rnr - decreases "npta" by one
* @sk: current connection structure.
* @ev: current event.
* @skb: current event.
*
* After receiving "dec_cntr" times RNR command, this action decreases
* "npta" by one. Returns 0 for success, 1 otherwise.
*/
int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
......@@ -1207,13 +1164,13 @@ int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk,
/**
* llc_conn_ac_dec_tx_win_size - decreases tx window size
* @sk: current connection structure.
* @ev: current event.
* @skb: current event.
*
* After receiving of a REJ command or response, transmit window size is
* decreased by number of PDUs which are outstanding yet. Returns 0 for
* success, 1 otherwise.
*/
int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
u8 unacked_pdu = skb_queue_len(&llc->pdu_unack_q);
......@@ -1227,12 +1184,12 @@ int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct llc_conn_state_ev *ev)
/**
* llc_conn_ac_inc_tx_win_size - tx window size is inc by 1
* @sk: current connection structure.
* @ev: current event.
* @skb: current event.
*
* After receiving an RR response with f-bit set to one, transmit window
* size is increased by one. Returns 0 for success, 1 otherwise.
*/
int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
......@@ -1242,7 +1199,7 @@ int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct llc_conn_state_ev *ev)
return 0;
}
int llc_conn_ac_stop_all_timers(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
......@@ -1259,7 +1216,7 @@ int llc_conn_ac_stop_all_timers(struct sock *sk, struct llc_conn_state_ev *ev)
return 0;
}
int llc_conn_ac_stop_other_timers(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_stop_other_timers(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
......@@ -1274,7 +1231,7 @@ int llc_conn_ac_stop_other_timers(struct sock *sk, struct llc_conn_state_ev *ev)
return 0;
}
int llc_conn_ac_start_ack_timer(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
......@@ -1287,7 +1244,7 @@ int llc_conn_ac_start_ack_timer(struct sock *sk, struct llc_conn_state_ev *ev)
return 0;
}
int llc_conn_ac_start_rej_timer(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
......@@ -1302,7 +1259,7 @@ int llc_conn_ac_start_rej_timer(struct sock *sk, struct llc_conn_state_ev *ev)
}
int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
......@@ -1317,14 +1274,14 @@ int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk,
return 0;
}
int llc_conn_ac_stop_ack_timer(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_stop_ack_timer(struct sock *sk, struct sk_buff *skb)
{
del_timer(&llc_sk(sk)->ack_timer.timer);
llc_sk(sk)->ack_timer.running = 0;
return 0;
}
int llc_conn_ac_stop_p_timer(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_stop_p_timer(struct sock *sk, struct sk_buff *skb)
{
struct llc_opt *llc = llc_sk(sk);
......@@ -1334,20 +1291,19 @@ int llc_conn_ac_stop_p_timer(struct sock *sk, struct llc_conn_state_ev *ev)
return 0;
}
int llc_conn_ac_stop_rej_timer(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_stop_rej_timer(struct sock *sk, struct sk_buff *skb)
{
del_timer(&llc_sk(sk)->rej_sent_timer.timer);
llc_sk(sk)->rej_sent_timer.running = 0;
return 0;
}
int llc_conn_ac_upd_nr_received(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb)
{
int acked;
u16 unacked = 0;
u8 fbit;
struct sk_buff *skb = ev->data.pdu.skb;
struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
struct llc_opt *llc = llc_sk(sk);
llc->last_nr = PDU_SUPV_GET_Nr(pdu);
......@@ -1363,7 +1319,7 @@ int llc_conn_ac_upd_nr_received(struct sock *sk, struct llc_conn_state_ev *ev)
* can send data and must inform to upper layer.
*/
llc->failed_data_req = 0;
llc_conn_ac_data_confirm(sk, ev);
llc_conn_ac_data_confirm(sk, skb);
}
if (unacked) {
llc->ack_timer.timer.expires = jiffies +
......@@ -1377,201 +1333,203 @@ int llc_conn_ac_upd_nr_received(struct sock *sk, struct llc_conn_state_ev *ev)
llc_pdu_decode_pf_bit(skb, &fbit);
if (fbit == 1) {
llc->failed_data_req = 0;
llc_conn_ac_data_confirm(sk, ev);
llc_conn_ac_data_confirm(sk, skb);
}
}
return 0;
}
int llc_conn_ac_upd_p_flag(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_upd_p_flag(struct sock *sk, struct sk_buff *skb)
{
struct sk_buff *skb = ev->data.pdu.skb;
struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 f_bit;
if (!LLC_PDU_IS_RSP(pdu) &&
!llc_pdu_decode_pf_bit(skb, &f_bit) && f_bit) {
llc_sk(sk)->p_flag = 0;
llc_conn_ac_stop_p_timer(sk, ev);
llc_conn_ac_stop_p_timer(sk, skb);
}
return 0;
}
int llc_conn_ac_set_data_flag_2(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_data_flag_2(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->data_flag = 2;
return 0;
}
int llc_conn_ac_set_data_flag_0(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_data_flag_0(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->data_flag = 0;
return 0;
}
int llc_conn_ac_set_data_flag_1(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_data_flag_1(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->data_flag = 1;
return 0;
}
int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
if (!llc_sk(sk)->data_flag)
llc_sk(sk)->data_flag = 1;
return 0;
}
int llc_conn_ac_set_p_flag_0(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_p_flag_0(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->p_flag = 0;
return 0;
}
int llc_conn_ac_set_p_flag_1(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->p_flag = 1;
return 0;
}
int llc_conn_ac_set_remote_busy_0(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_remote_busy_0(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->remote_busy_flag = 0;
return 0;
}
int llc_conn_ac_set_cause_flag_0(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_cause_flag_0(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->cause_flag = 0;
return 0;
}
int llc_conn_ac_set_cause_flag_1(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_cause_flag_1(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->cause_flag = 1;
return 0;
}
int llc_conn_ac_set_retry_cnt_0(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_retry_cnt_0(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->retry_count = 0;
return 0;
}
int llc_conn_ac_inc_retry_cnt_by_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ac_inc_retry_cnt_by_1(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->retry_count++;
return 0;
}
int llc_conn_ac_set_vr_0(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_vr_0(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->vR = 0;
return 0;
}
int llc_conn_ac_inc_vr_by_1(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_inc_vr_by_1(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->vR = PDU_GET_NEXT_Vr(llc_sk(sk)->vR);
return 0;
}
int llc_conn_ac_set_vs_0(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_vs_0(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->vS = 0;
return 0;
}
int llc_conn_ac_set_vs_nr(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_vs_nr(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->vS = llc_sk(sk)->last_nr;
return 0;
}
int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % 128;
return 0;
}
int llc_conn_ac_set_f_flag_p(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_set_f_flag_p(struct sock *sk, struct sk_buff *skb)
{
llc_pdu_decode_pf_bit(ev->data.pdu.skb, &llc_sk(sk)->f_flag);
llc_pdu_decode_pf_bit(skb, &llc_sk(sk)->f_flag);
return 0;
}
void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
{
struct sock *sk = (struct sock *)timeout_data;
struct llc_conn_state_ev *ev;
struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC);
llc_sk(sk)->pf_cycle_timer.running = 0;
ev = llc_conn_alloc_ev(sk);
if (ev) {
if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
ev->type = LLC_CONN_EV_TYPE_P_TMR;
ev->data.tmr.timer_specific = NULL;
llc_process_tmr_ev(sk, ev);
llc_process_tmr_ev(sk, skb);
}
}
static void llc_conn_busy_tmr_cb(unsigned long timeout_data)
{
struct sock *sk = (struct sock *)timeout_data;
struct llc_conn_state_ev *ev;
struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC);
llc_sk(sk)->busy_state_timer.running = 0;
ev = llc_conn_alloc_ev(sk);
if (ev) {
if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
ev->type = LLC_CONN_EV_TYPE_BUSY_TMR;
ev->data.tmr.timer_specific = NULL;
llc_process_tmr_ev(sk, ev);
llc_process_tmr_ev(sk, skb);
}
}
void llc_conn_ack_tmr_cb(unsigned long timeout_data)
{
struct sock* sk = (struct sock *)timeout_data;
struct llc_conn_state_ev *ev;
struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC);
llc_sk(sk)->ack_timer.running = 0;
ev = llc_conn_alloc_ev(sk);
if (ev) {
if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
ev->type = LLC_CONN_EV_TYPE_ACK_TMR;
ev->data.tmr.timer_specific = NULL;
llc_process_tmr_ev(sk, ev);
llc_process_tmr_ev(sk, skb);
}
}
static void llc_conn_rej_tmr_cb(unsigned long timeout_data)
{
struct sock *sk = (struct sock *)timeout_data;
struct llc_conn_state_ev *ev;
struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC);
llc_sk(sk)->rej_sent_timer.running = 0;
ev = llc_conn_alloc_ev(sk);
if (ev) {
if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
ev->type = LLC_CONN_EV_TYPE_REJ_TMR;
ev->data.tmr.timer_specific = NULL;
llc_process_tmr_ev(sk, ev);
llc_process_tmr_ev(sk, skb);
}
}
int llc_conn_ac_rst_vs(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb)
{
llc_sk(sk)->X = llc_sk(sk)->vS;
llc_conn_ac_set_vs_nr(sk, ev);
llc_conn_ac_set_vs_nr(sk, skb);
return 0;
}
int llc_conn_ac_upd_vs(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 nr = PDU_SUPV_GET_Nr(pdu);
if (llc_circular_between(llc_sk(sk)->vS, nr, llc_sk(sk)->X))
llc_conn_ac_set_vs_nr(sk, ev);
llc_conn_ac_set_vs_nr(sk, skb);
return 0;
}
......@@ -1582,11 +1540,11 @@ int llc_conn_ac_upd_vs(struct sock *sk, struct llc_conn_state_ev *ev)
/**
* llc_conn_disc - removes connection from SAP list and frees it
* @sk: closed connection
* @ev: occurred event
* @skb: occurred event
*
* Returns 2, to indicate the state machine that the connection was freed.
*/
int llc_conn_disc(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_disc(struct sock *sk, struct sk_buff *skb)
{
llc_sap_unassign_sock(llc_sk(sk)->sap, sk);
llc_sock_free(sk);
......@@ -1596,11 +1554,11 @@ int llc_conn_disc(struct sock *sk, struct llc_conn_state_ev *ev)
/**
* llc_conn_reset - resets connection
* @sk : reseting connection.
* @ev: occurred event.
* @skb: occurred event.
*
* Stop all timers, empty all queues and reset all flags.
*/
int llc_conn_reset(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_reset(struct sock *sk, struct sk_buff *skb)
{
llc_sock_reset(sk);
return 0;
......@@ -1626,7 +1584,7 @@ u8 llc_circular_between(u8 a, u8 b, u8 c)
/**
* llc_process_tmr_ev - timer backend
* @sk: active connection
* @ev: occurred event
* @skb: occurred event
*
* This function is called from timer callback functions. When connection
* is busy (during sending a data frame) timer expiration event must be
......@@ -1634,25 +1592,20 @@ u8 llc_circular_between(u8 a, u8 b, u8 c)
* Queued events will process by process_rxframes_events function after
* sending data frame. Returns 0 for success, 1 otherwise.
*/
static void llc_process_tmr_ev(struct sock *sk, struct llc_conn_state_ev *ev)
static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
{
bh_lock_sock(sk);
if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) {
printk(KERN_WARNING "timer called on closed connection\n");
llc_conn_free_ev(ev);
printk(KERN_WARNING "%s: timer called on closed connection\n",
__FUNCTION__);
llc_conn_free_ev(skb);
goto out;
}
if (!sk->lock.users)
llc_conn_send_ev(sk, ev);
llc_conn_send_ev(sk, skb);
else {
struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC);
if (skb) {
skb->cb[0] = LLC_EVENT;
skb->data = (void *)ev;
sk_add_backlog(sk, skb);
} else
llc_conn_free_ev(ev);
llc_set_backlog_type(skb, LLC_EVENT);
sk_add_backlog(sk, skb);
}
out:
bh_unlock_sock(sk);
......
......@@ -40,7 +40,7 @@
#include <net/llc_c_ev.h>
#include <net/llc_pdu.h>
#if 0
#if 1
#define dprintk(args...) printk(KERN_DEBUG args)
#else
#define dprintk(args...)
......@@ -97,102 +97,111 @@ static u16 llc_util_nr_inside_tx_window(struct sock *sk, u8 nr)
return rc;
}
int llc_conn_ev_conn_req(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->data.prim.prim == LLC_CONN_PRIM &&
ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_conn_ev_conn_resp(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ev_conn_resp(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->data.prim.prim == LLC_CONN_PRIM &&
ev->data.prim.type == LLC_PRIM_TYPE_RESP ? 0 : 1;
}
int llc_conn_ev_data_req(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->data.prim.prim == LLC_DATA_PRIM &&
ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_conn_ev_disc_req(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->data.prim.prim == LLC_DISC_PRIM &&
ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_conn_ev_rst_req(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->data.prim.prim == LLC_RESET_PRIM &&
ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_conn_ev_rst_resp(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ev_rst_resp(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->data.prim.prim == LLC_RESET_PRIM &&
ev->data.prim.type == LLC_PRIM_TYPE_RESP ? 0 : 1;
}
int llc_conn_ev_local_busy_detected(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
ev->data.a.ev == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
}
int llc_conn_ev_local_busy_cleared(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
ev->data.a.ev == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
}
int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.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_DM ? 0 : 1;
}
int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.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_FRMR ? 0 : 1;
}
int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return !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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
!LLC_I_PF_IS_1(pdu) &&
......@@ -200,9 +209,9 @@ int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk,
}
int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 vr = llc_sk(sk)->vR;
u8 ns = LLC_I_GET_NS(pdu);
......@@ -212,9 +221,9 @@ int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
}
int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 vr = llc_sk(sk)->vR;
u8 ns = LLC_I_GET_NS(pdu);
......@@ -224,9 +233,9 @@ int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
}
int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
u8 vr = llc_sk(sk)->vR;
u8 ns = LLC_I_GET_NS(pdu);
u16 rc = !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
......@@ -238,39 +247,36 @@ int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
return rc;
}
int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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_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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
return !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 llc_conn_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 vr = llc_sk(sk)->vR;
u8 ns = LLC_I_GET_NS(pdu);
......@@ -280,9 +286,9 @@ int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
}
int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 vr = llc_sk(sk)->vR;
u8 ns = LLC_I_GET_NS(pdu);
......@@ -292,9 +298,9 @@ int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
}
int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 vr = llc_sk(sk)->vR;
u8 ns = LLC_I_GET_NS(pdu);
......@@ -303,9 +309,9 @@ int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
}
int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 vr = llc_sk(sk)->vR;
u8 ns = LLC_I_GET_NS(pdu);
u16 rc = !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
......@@ -317,158 +323,142 @@ int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
return rc;
}
int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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_RR ? 0 : 1;
}
int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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_RR ? 0 : 1;
}
int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.skb);
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 llc_conn_state_ev *ev)
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(ev->data.pdu.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 llc_conn_state_ev *ev)
int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
{
u16 rc = 1;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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)) {
......@@ -480,11 +470,10 @@ int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk,
return rc;
}
int llc_conn_ev_rx_xxx_cmd_pbit_set_0(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_rx_xxx_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
{
u16 rc = 1;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
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)) {
......@@ -502,11 +491,10 @@ int llc_conn_ev_rx_xxx_cmd_pbit_set_0(struct sock *sk,
return rc;
}
int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
{
u16 rc = 1;
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.skb);
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))
......@@ -522,11 +510,10 @@ int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk,
return rc;
}
int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
{
u16 rc = 1;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
if (!LLC_PDU_IS_RSP(pdu)) {
if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
......@@ -545,11 +532,10 @@ int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk,
return rc;
}
int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
{
u16 rc = 1;
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.skb);
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))
......@@ -567,10 +553,10 @@ int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk,
return rc;
}
int llc_conn_ev_rx_xxx_yyy(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ev_rx_xxx_yyy(struct sock *sk, struct sk_buff *skb)
{
u16 rc = 1;
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.skb);
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu))
rc = 0;
......@@ -588,77 +574,79 @@ int llc_conn_ev_rx_xxx_yyy(struct sock *sk, struct llc_conn_state_ev *ev)
}
int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
u16 rc = 1;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 vs = llc_sk(sk)->vS;
u8 nr = LLC_I_GET_NR(pdu);
if (!LLC_PDU_IS_CMD(pdu)) {
if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
if (nr != vs &&
llc_util_nr_inside_tx_window(sk, nr)) {
dprintk(KERN_ERR "conn_ev_rx_zzz_cmd_inv_nr "
"matched, state = %d, vs = %d, "
"nr = %d\n", llc_sk(sk)->state, vs, nr);
rc = 0;
}
}
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(KERN_ERR "conn_ev_rx_zzz_cmd_inv_nr matched, state = "
"%d, vs = %d, nr = %d\n",
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 llc_conn_state_ev *ev)
struct sk_buff *skb)
{
u16 rc = 1;
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(ev->data.pdu.skb);
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
u8 vs = llc_sk(sk)->vS;
u8 nr = LLC_I_GET_NR(pdu);
if (!LLC_PDU_IS_RSP(pdu)) {
if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
if (nr != vs &&
llc_util_nr_inside_tx_window(sk, nr)) {
rc = 0;
dprintk(KERN_ERR "conn_ev_rx_zzz_fbit_set"
"_x_inval_nr matched, state = %d, "
"vs = %d, nr = %d\n",
llc_sk(sk)->state, vs, nr);
}
}
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(KERN_ERR "conn_ev_rx_zzz_fbit_set_x_inval_nr matched, "
"state = %d, vs = %d, nr = %d\n",
llc_sk(sk)->state, vs, nr);
}
return rc;
}
int llc_conn_ev_rx_any_frame(struct sock *sk, struct llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb)
{
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 llc_conn_state_ev *ev)
int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb)
{
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 llc_conn_state_ev *ev)
int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb)
{
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 llc_conn_state_ev *ev)
int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
}
int llc_conn_ev_any_tmr_exp(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_ev_any_tmr_exp(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type == LLC_CONN_EV_TYPE_P_TMR ||
ev->type == LLC_CONN_EV_TYPE_ACK_TMR ||
......@@ -666,13 +654,15 @@ int llc_conn_ev_any_tmr_exp(struct sock *sk, struct llc_conn_state_ev *ev)
ev->type == LLC_CONN_EV_TYPE_BUSY_TMR ? 0 : 1;
}
int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
ev->data.a.ev == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
}
......@@ -683,26 +673,22 @@ int llc_conn_ev_tx_buffer_full(struct sock *sk, struct llc_conn_state_ev *ev)
* 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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb)
{
return llc_sk(sk)->p_flag != 1;
}
......@@ -710,7 +696,7 @@ int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk,
/**
* conn_ev_qlfy_last_frame_eq_1 - checks if frame is last in tx window
* @sk: current connection structure.
* @ev: current event.
* @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
......@@ -718,8 +704,7 @@ int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk,
* 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 llc_conn_state_ev *ev)
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);
}
......@@ -727,147 +712,144 @@ int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk,
/**
* conn_ev_qlfy_last_frame_eq_0 - checks if frame isn't last in tx window
* @sk: current connection structure.
* @ev: current event.
* @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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb)
{
u8 f_bit;
struct sk_buff *skb;
if (ev->type == LLC_CONN_EV_TYPE_PDU)
skb = ev->data.pdu.skb;
else
skb = ev->data.prim.data->data->conn.skb;
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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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_init_p_f_cycle(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_qlfy_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
{
return 0;
}
int llc_conn_ev_qlfy_set_status_conn(struct sock *sk,
struct llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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_impossible(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_qlfy_set_status_impossible(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
ev->status = LLC_STATUS_IMPOSSIBLE;
return 0;
}
int llc_conn_ev_qlfy_set_status_failed(struct sock *sk,
struct llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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_received(struct sock *sk,
struct llc_conn_state_ev *ev)
int llc_conn_ev_qlfy_set_status_received(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
ev->status = LLC_STATUS_RECEIVED;
return 0;
}
int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk,
struct llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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 llc_conn_state_ev *ev)
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;
}
......@@ -347,7 +347,7 @@ static struct llc_conn_state_trans llc_common_state_trans_11d = {
* Common dummy state transition; must be last entry for all state
* transition groups - it'll be on .bss, so will be zeroed.
*/
static struct llc_conn_state_trans llc_common_state_trans_n;
static struct llc_conn_state_trans llc_common_state_trans_end;
/* LLC_CONN_STATE_ADM transitions */
/* State transitions for LLC_CONN_EV_CONN_REQ event */
......@@ -432,15 +432,15 @@ static struct llc_conn_state_trans llc_adm_state_trans_5 = {
*/
static struct llc_conn_state_trans *llc_adm_state_transitions[] = {
[0] = &llc_adm_state_trans_1, /* Request */
[1] = &llc_common_state_trans_n,
[2] = &llc_common_state_trans_n, /* local_busy */
[3] = &llc_common_state_trans_n, /* init_pf_cycle */
[4] = &llc_common_state_trans_n, /* timer */
[1] = &llc_common_state_trans_end,
[2] = &llc_common_state_trans_end, /* local_busy */
[3] = &llc_common_state_trans_end, /* init_pf_cycle */
[4] = &llc_common_state_trans_end, /* timer */
[5] = &llc_adm_state_trans_2, /* Receive frame */
[6] = &llc_adm_state_trans_3,
[7] = &llc_adm_state_trans_4,
[8] = &llc_adm_state_trans_5,
[9] = &llc_common_state_trans_n,
[9] = &llc_common_state_trans_end,
};
/* LLC_CONN_STATE_SETUP transitions */
......@@ -593,18 +593,18 @@ static struct llc_conn_state_trans llc_setup_state_trans_8 = {
* one to each transition
*/
static struct llc_conn_state_trans *llc_setup_state_transitions[] = {
[0] = &llc_common_state_trans_n, /* Request */
[1] = &llc_common_state_trans_n, /* local busy */
[2] = &llc_common_state_trans_n, /* init_pf_cycle */
[0] = &llc_common_state_trans_end, /* Request */
[1] = &llc_common_state_trans_end, /* local busy */
[2] = &llc_common_state_trans_end, /* init_pf_cycle */
[3] = &llc_setup_state_trans_3, /* Timer */
[4] = &llc_setup_state_trans_7,
[5] = &llc_setup_state_trans_8,
[6] = &llc_common_state_trans_n,
[6] = &llc_common_state_trans_end,
[7] = &llc_setup_state_trans_1, /* Receive frame */
[8] = &llc_setup_state_trans_2,
[9] = &llc_setup_state_trans_4,
[10] = &llc_setup_state_trans_5,
[11] = &llc_common_state_trans_n,
[11] = &llc_common_state_trans_end,
};
/* LLC_CONN_STATE_NORMAL transitions */
......@@ -1287,13 +1287,13 @@ static struct llc_conn_state_trans *llc_normal_state_transitions[] = {
[2] = &llc_normal_state_trans_2_1,
[3] = &llc_common_state_trans_1,
[4] = &llc_common_state_trans_2,
[5] = &llc_common_state_trans_n,
[5] = &llc_common_state_trans_end,
[6] = &llc_normal_state_trans_21,
[7] = &llc_normal_state_trans_3, /* Local busy */
[8] = &llc_normal_state_trans_4,
[9] = &llc_common_state_trans_n,
[9] = &llc_common_state_trans_end,
[10] = &llc_normal_state_trans_18, /* Init pf cycle */
[11] = &llc_common_state_trans_n,
[11] = &llc_common_state_trans_end,
[12] = &llc_common_state_trans_11a, /* Timers */
[13] = &llc_common_state_trans_11b,
[14] = &llc_common_state_trans_11c,
......@@ -1301,7 +1301,7 @@ static struct llc_conn_state_trans *llc_normal_state_transitions[] = {
[16] = &llc_normal_state_trans_19,
[17] = &llc_normal_state_trans_20a,
[18] = &llc_normal_state_trans_20b,
[19] = &llc_common_state_trans_n,
[19] = &llc_common_state_trans_end,
[20] = &llc_normal_state_trans_8b, /* Receive frames */
[21] = &llc_normal_state_trans_9b,
[22] = &llc_normal_state_trans_10,
......@@ -1337,7 +1337,7 @@ static struct llc_conn_state_trans *llc_normal_state_transitions[] = {
[52] = &llc_common_state_trans_8c,
[53] = &llc_common_state_trans_9,
/* [54] = &llc_common_state_trans_10, */
[54] = &llc_common_state_trans_n,
[54] = &llc_common_state_trans_end,
};
/* LLC_CONN_STATE_BUSY transitions */
......@@ -2096,16 +2096,16 @@ static struct llc_conn_state_trans *llc_busy_state_transitions[] = {
[2] = &llc_busy_state_trans_1,
[3] = &llc_busy_state_trans_2,
[4] = &llc_busy_state_trans_2_1,
[5] = &llc_common_state_trans_n,
[5] = &llc_common_state_trans_end,
[6] = &llc_busy_state_trans_3, /* Local busy */
[7] = &llc_busy_state_trans_4,
[8] = &llc_busy_state_trans_5,
[9] = &llc_busy_state_trans_6,
[10] = &llc_busy_state_trans_7,
[11] = &llc_busy_state_trans_8,
[12] = &llc_common_state_trans_n,
[12] = &llc_common_state_trans_end,
[13] = &llc_busy_state_trans_22, /* Initiate PF cycle */
[14] = &llc_common_state_trans_n,
[14] = &llc_common_state_trans_end,
[15] = &llc_common_state_trans_11a, /* Timer */
[16] = &llc_common_state_trans_11b,
[17] = &llc_common_state_trans_11c,
......@@ -2115,7 +2115,7 @@ static struct llc_conn_state_trans *llc_busy_state_transitions[] = {
[21] = &llc_busy_state_trans_24b,
[22] = &llc_busy_state_trans_25,
[23] = &llc_busy_state_trans_26,
[24] = &llc_common_state_trans_n,
[24] = &llc_common_state_trans_end,
[25] = &llc_busy_state_trans_9a, /* Receive frame */
[26] = &llc_busy_state_trans_9b,
[27] = &llc_busy_state_trans_10a,
......@@ -2150,7 +2150,7 @@ static struct llc_conn_state_trans *llc_busy_state_transitions[] = {
[56] = &llc_common_state_trans_8c,
[57] = &llc_common_state_trans_9,
/* [58] = &llc_common_state_trans_10, */
[58] = &llc_common_state_trans_n,
[58] = &llc_common_state_trans_end,
};
/* LLC_CONN_STATE_REJ transitions */
......@@ -2770,15 +2770,15 @@ static struct llc_conn_state_trans llc_reject_state_trans_20b = {
static struct llc_conn_state_trans *llc_reject_state_transitions[] = {
[0] = &llc_common_state_trans_1, /* Request */
[1] = &llc_common_state_trans_2,
[2] = &llc_common_state_trans_n,
[2] = &llc_common_state_trans_end,
[3] = &llc_reject_state_trans_1,
[4] = &llc_reject_state_trans_2,
[5] = &llc_reject_state_trans_2_1,
[6] = &llc_reject_state_trans_3, /* Local busy */
[7] = &llc_reject_state_trans_4,
[8] = &llc_common_state_trans_n,
[8] = &llc_common_state_trans_end,
[9] = &llc_reject_state_trans_17, /* Initiate PF cycle */
[10] = &llc_common_state_trans_n,
[10] = &llc_common_state_trans_end,
[11] = &llc_common_state_trans_11a, /* Timer */
[12] = &llc_common_state_trans_11b,
[13] = &llc_common_state_trans_11c,
......@@ -2787,7 +2787,7 @@ static struct llc_conn_state_trans *llc_reject_state_transitions[] = {
[16] = &llc_reject_state_trans_19,
[17] = &llc_reject_state_trans_20a,
[18] = &llc_reject_state_trans_20b,
[19] = &llc_common_state_trans_n,
[19] = &llc_common_state_trans_end,
[20] = &llc_common_state_trans_3, /* Receive frame */
[21] = &llc_common_state_trans_4,
[22] = &llc_common_state_trans_5,
......@@ -2821,7 +2821,7 @@ static struct llc_conn_state_trans *llc_reject_state_transitions[] = {
[49] = &llc_reject_state_trans_15a,
[50] = &llc_reject_state_trans_15b,
[51] = &llc_reject_state_trans_16,
[52] = &llc_common_state_trans_n,
[52] = &llc_common_state_trans_end,
};
/* LLC_CONN_STATE_AWAIT transitions */
......@@ -3209,16 +3209,16 @@ static struct llc_conn_state_trans *llc_await_state_transitions[] = {
[0] = &llc_common_state_trans_1, /* Request */
[1] = &llc_common_state_trans_2,
[2] = &llc_await_state_trans_1_0,
[3] = &llc_common_state_trans_n,
[3] = &llc_common_state_trans_end,
[4] = &llc_await_state_trans_1, /* Local busy */
[5] = &llc_common_state_trans_n,
[6] = &llc_common_state_trans_n, /* Initiate PF Cycle */
[5] = &llc_common_state_trans_end,
[6] = &llc_common_state_trans_end, /* Initiate PF Cycle */
[7] = &llc_common_state_trans_11a, /* Timer */
[8] = &llc_common_state_trans_11b,
[9] = &llc_common_state_trans_11c,
[10] = &llc_common_state_trans_11d,
[11] = &llc_await_state_trans_14,
[12] = &llc_common_state_trans_n,
[12] = &llc_common_state_trans_end,
[13] = &llc_common_state_trans_3, /* Receive frame */
[14] = &llc_common_state_trans_4,
[15] = &llc_common_state_trans_5,
......@@ -3250,7 +3250,7 @@ static struct llc_conn_state_trans *llc_await_state_transitions[] = {
[40] = &llc_await_state_trans_12a,
[41] = &llc_await_state_trans_12b,
[42] = &llc_await_state_trans_13,
[43] = &llc_common_state_trans_n,
[43] = &llc_common_state_trans_end,
};
/* LLC_CONN_STATE_AWAIT_BUSY transitions */
......@@ -3683,18 +3683,18 @@ static struct llc_conn_state_trans *llc_await_busy_state_transitions[] = {
[0] = &llc_common_state_trans_1, /* Request */
[1] = &llc_common_state_trans_2,
[2] = &llc_await_busy_state_trans_1_0,
[3] = &llc_common_state_trans_n,
[3] = &llc_common_state_trans_end,
[4] = &llc_await_busy_state_trans_1, /* Local busy */
[5] = &llc_await_busy_state_trans_2,
[6] = &llc_await_busy_state_trans_3,
[7] = &llc_common_state_trans_n,
[8] = &llc_common_state_trans_n, /* Initiate PF cycle */
[7] = &llc_common_state_trans_end,
[8] = &llc_common_state_trans_end, /* Initiate PF cycle */
[9] = &llc_common_state_trans_11a, /* Timer */
[10] = &llc_common_state_trans_11b,
[11] = &llc_common_state_trans_11c,
[12] = &llc_common_state_trans_11d,
[13] = &llc_await_busy_state_trans_16,
[14] = &llc_common_state_trans_n,
[14] = &llc_common_state_trans_end,
[15] = &llc_await_busy_state_trans_4, /* Receive frame */
[16] = &llc_await_busy_state_trans_5a,
[17] = &llc_await_busy_state_trans_5b,
......@@ -3726,7 +3726,7 @@ static struct llc_conn_state_trans *llc_await_busy_state_transitions[] = {
[43] = &llc_common_state_trans_8c,
[44] = &llc_common_state_trans_9,
/* [45] = &llc_common_state_trans_10, */
[45] = &llc_common_state_trans_n,
[45] = &llc_common_state_trans_end,
};
/* ----------------- LLC_CONN_STATE_AWAIT_REJ transitions --------------- */
......@@ -4110,16 +4110,16 @@ static struct llc_conn_state_trans *llc_await_rejct_state_transitions[] = {
[0] = &llc_await_reject_state_trans_1_0,
[1] = &llc_common_state_trans_1, /* requests */
[2] = &llc_common_state_trans_2,
[3] = &llc_common_state_trans_n,
[3] = &llc_common_state_trans_end,
[4] = &llc_await_rejct_state_trans_1, /* local busy */
[5] = &llc_common_state_trans_n,
[6] = &llc_common_state_trans_n, /* Initiate PF cycle */
[5] = &llc_common_state_trans_end,
[6] = &llc_common_state_trans_end, /* Initiate PF cycle */
[7] = &llc_await_rejct_state_trans_13, /* timers */
[8] = &llc_common_state_trans_11a,
[9] = &llc_common_state_trans_11b,
[10] = &llc_common_state_trans_11c,
[11] = &llc_common_state_trans_11d,
[12] = &llc_common_state_trans_n,
[12] = &llc_common_state_trans_end,
[13] = &llc_await_rejct_state_trans_2a, /* receive frames */
[14] = &llc_await_rejct_state_trans_2b,
[15] = &llc_await_rejct_state_trans_3,
......@@ -4151,7 +4151,7 @@ static struct llc_conn_state_trans *llc_await_rejct_state_transitions[] = {
[41] = &llc_common_state_trans_8c,
[42] = &llc_common_state_trans_9,
/* [43] = &llc_common_state_trans_10, */
[43] = &llc_common_state_trans_n,
[43] = &llc_common_state_trans_end,
};
/* LLC_CONN_STATE_D_CONN transitions */
......@@ -4392,13 +4392,13 @@ static struct llc_conn_state_trans llc_d_conn_state_trans_8 = {
*/
static struct llc_conn_state_trans *llc_d_conn_state_transitions[] = {
[0] = &llc_d_conn_state_trans_5, /* Request */
[1] = &llc_common_state_trans_n,
[2] = &llc_common_state_trans_n, /* Local busy */
[3] = &llc_common_state_trans_n, /* Initiate PF cycle */
[1] = &llc_common_state_trans_end,
[2] = &llc_common_state_trans_end, /* Local busy */
[3] = &llc_common_state_trans_end, /* Initiate PF cycle */
[4] = &llc_d_conn_state_trans_6, /* Timer */
[5] = &llc_d_conn_state_trans_7,
[6] = &llc_d_conn_state_trans_8,
[7] = &llc_common_state_trans_n,
[7] = &llc_common_state_trans_end,
[8] = &llc_d_conn_state_trans_1, /* Receive frame */
[9] = &llc_d_conn_state_trans_1_1,
[10] = &llc_d_conn_state_trans_2,
......@@ -4406,7 +4406,7 @@ static struct llc_conn_state_trans *llc_d_conn_state_transitions[] = {
[12] = &llc_d_conn_state_trans_3,
[13] = &llc_d_conn_state_trans_4,
[14] = &llc_d_conn_state_trans_4_1,
[15] = &llc_common_state_trans_n,
[15] = &llc_common_state_trans_end,
};
/* LLC_CONN_STATE_RESET transitions */
......@@ -4678,14 +4678,14 @@ static struct llc_conn_state_trans llc_rst_state_trans_8_1 = {
*/
static struct llc_conn_state_trans *llc_rst_state_transitions[] = {
[0] = &llc_rst_state_trans_6, /* Request */
[1] = &llc_common_state_trans_n,
[2] = &llc_common_state_trans_n, /* Local busy */
[3] = &llc_common_state_trans_n, /* Initiate PF cycle */
[1] = &llc_common_state_trans_end,
[2] = &llc_common_state_trans_end, /* Local busy */
[3] = &llc_common_state_trans_end, /* Initiate PF cycle */
[4] = &llc_rst_state_trans_3, /* Timer */
[5] = &llc_rst_state_trans_7,
[6] = &llc_rst_state_trans_8,
[7] = &llc_rst_state_trans_8_1,
[8] = &llc_common_state_trans_n,
[8] = &llc_common_state_trans_end,
[9] = &llc_rst_state_trans_1, /* Receive frame */
[10] = &llc_rst_state_trans_2,
[11] = &llc_rst_state_trans_2_1,
......@@ -4693,7 +4693,7 @@ static struct llc_conn_state_trans *llc_rst_state_transitions[] = {
[13] = &llc_rst_state_trans_4_1,
[14] = &llc_rst_state_trans_5,
[15] = &llc_rst_state_trans_5_1,
[16] = &llc_common_state_trans_n,
[16] = &llc_common_state_trans_end,
};
/* LLC_CONN_STATE_ERROR transitions */
......@@ -4849,19 +4849,19 @@ static struct llc_conn_state_trans llc_error_state_trans_9 = {
*/
static struct llc_conn_state_trans *llc_error_state_transitions[] = {
[0] = &llc_error_state_trans_9, /* Request */
[1] = &llc_common_state_trans_n,
[2] = &llc_common_state_trans_n, /* Local busy */
[3] = &llc_common_state_trans_n, /* Initiate PF cycle */
[1] = &llc_common_state_trans_end,
[2] = &llc_common_state_trans_end, /* Local busy */
[3] = &llc_common_state_trans_end, /* Initiate PF cycle */
[4] = &llc_error_state_trans_7, /* Timer */
[5] = &llc_error_state_trans_8,
[6] = &llc_common_state_trans_n,
[6] = &llc_common_state_trans_end,
[7] = &llc_error_state_trans_1, /* Receive frame */
[8] = &llc_error_state_trans_2,
[9] = &llc_error_state_trans_3,
[10] = &llc_error_state_trans_4,
[11] = &llc_error_state_trans_5,
[12] = &llc_error_state_trans_6,
[13] = &llc_common_state_trans_n,
[13] = &llc_common_state_trans_end,
};
/* LLC_CONN_STATE_TEMP transitions */
......@@ -4886,61 +4886,61 @@ static struct llc_conn_state_trans llc_temp_state_trans_1 = {
*/
static struct llc_conn_state_trans *llc_temp_state_transitions[] = {
[0] = &llc_temp_state_trans_1, /* requests */
[1] = &llc_common_state_trans_n,
[2] = &llc_common_state_trans_n, /* local busy */
[3] = &llc_common_state_trans_n, /* init_pf_cycle */
[4] = &llc_common_state_trans_n, /* timer */
[5] = &llc_common_state_trans_n, /* receive */
[1] = &llc_common_state_trans_end,
[2] = &llc_common_state_trans_end, /* local busy */
[3] = &llc_common_state_trans_end, /* init_pf_cycle */
[4] = &llc_common_state_trans_end, /* timer */
[5] = &llc_common_state_trans_end, /* receive */
};
/* Connection State Transition Table */
struct llc_conn_state llc_conn_state_table[] = {
{
.current_state =LLC_CONN_STATE_ADM,
.transitions = llc_adm_state_transitions,
struct llc_conn_state llc_conn_state_table[NBR_CONN_STATES] = {
[LLC_CONN_STATE_ADM - 1] = {
.current_state = LLC_CONN_STATE_ADM,
.transitions = llc_adm_state_transitions,
},
{
.current_state =LLC_CONN_STATE_SETUP,
.transitions = llc_setup_state_transitions,
[LLC_CONN_STATE_SETUP - 1] = {
.current_state = LLC_CONN_STATE_SETUP,
.transitions = llc_setup_state_transitions,
},
{
.current_state =LLC_CONN_STATE_NORMAL,
.transitions = llc_normal_state_transitions,
[LLC_CONN_STATE_NORMAL - 1] = {
.current_state = LLC_CONN_STATE_NORMAL,
.transitions = llc_normal_state_transitions,
},
{
.current_state =LLC_CONN_STATE_BUSY,
.transitions = llc_busy_state_transitions,
[LLC_CONN_STATE_BUSY - 1] = {
.current_state = LLC_CONN_STATE_BUSY,
.transitions = llc_busy_state_transitions,
},
{
.current_state =LLC_CONN_STATE_REJ,
.transitions = llc_reject_state_transitions,
[LLC_CONN_STATE_REJ - 1] = {
.current_state = LLC_CONN_STATE_REJ,
.transitions = llc_reject_state_transitions,
},
{
.current_state =LLC_CONN_STATE_AWAIT,
.transitions = llc_await_state_transitions,
[LLC_CONN_STATE_AWAIT - 1] = {
.current_state = LLC_CONN_STATE_AWAIT,
.transitions = llc_await_state_transitions,
},
{
.current_state =LLC_CONN_STATE_AWAIT_BUSY,
.transitions = llc_await_busy_state_transitions,
[LLC_CONN_STATE_AWAIT_BUSY - 1] = {
.current_state = LLC_CONN_STATE_AWAIT_BUSY,
.transitions = llc_await_busy_state_transitions,
},
{
.current_state =LLC_CONN_STATE_AWAIT_REJ,
.transitions = llc_await_rejct_state_transitions,
[LLC_CONN_STATE_AWAIT_REJ - 1] = {
.current_state = LLC_CONN_STATE_AWAIT_REJ,
.transitions = llc_await_rejct_state_transitions,
},
{
.current_state =LLC_CONN_STATE_D_CONN,
.transitions = llc_d_conn_state_transitions,
[LLC_CONN_STATE_D_CONN - 1] = {
.current_state = LLC_CONN_STATE_D_CONN,
.transitions = llc_d_conn_state_transitions,
},
{
.current_state =LLC_CONN_STATE_RESET,
.transitions = llc_rst_state_transitions,
[LLC_CONN_STATE_RESET - 1] = {
.current_state = LLC_CONN_STATE_RESET,
.transitions = llc_rst_state_transitions,
},
{
.current_state =LLC_CONN_STATE_ERROR,
.transitions = llc_error_state_transitions,
[LLC_CONN_STATE_ERROR - 1] = {
.current_state = LLC_CONN_STATE_ERROR,
.transitions = llc_error_state_transitions,
},
{
.current_state =LLC_CONN_STATE_TEMP,
.transitions = llc_temp_state_transitions,
[LLC_CONN_STATE_TEMP - 1] = {
.current_state = LLC_CONN_STATE_TEMP,
.transitions = llc_temp_state_transitions,
},
};
......@@ -28,56 +28,37 @@
static int llc_find_offset(int state, int ev_type);
static void llc_conn_send_pdus(struct sock *sk);
static int llc_conn_service(struct sock *sk, struct llc_conn_state_ev *ev);
static int llc_conn_service(struct sock *sk, struct sk_buff *skb);
static int llc_exec_conn_trans_actions(struct sock *sk,
struct llc_conn_state_trans *trans,
struct llc_conn_state_ev *ev);
static struct llc_conn_state_trans *
llc_qualify_conn_ev(struct sock *sk, struct llc_conn_state_ev *ev);
struct sk_buff *ev);
static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
struct sk_buff *skb);
/* Offset table on connection states transition diagram */
static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
/**
* llc_conn_alloc_event: allocates an event
* @sk: socket that event is associated
*
* Returns pointer to allocated connection on success, %NULL on failure.
*/
struct llc_conn_state_ev *llc_conn_alloc_ev(struct sock *sk)
{
struct llc_conn_state_ev *ev = NULL;
/* verify connection is valid, active and open */
if (llc_sk(sk)->state != LLC_CONN_OUT_OF_SVC) {
/* get event structure to build a station event */
ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
if (ev)
memset(ev, 0, sizeof(*ev));
}
return ev;
}
/**
* llc_conn_send_event - sends event to connection state machine
* @sk: connection
* @ev: occurred event
* @skb: occurred event
*
* Sends an event to connection state machine. after processing event
* (executing it's actions and changing state), upper layer will be
* indicated or confirmed, if needed. Returns 0 for success, 1 for
* failure. The socket lock has to be held before calling this function.
*/
int llc_conn_send_ev(struct sock *sk, struct llc_conn_state_ev *ev)
int llc_conn_send_ev(struct sock *sk, struct sk_buff *skb)
{
/* sending event to state machine */
int rc = llc_conn_service(sk, ev);
int rc = llc_conn_service(sk, skb);
struct llc_opt *llc = llc_sk(sk);
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
u8 flag = ev->flag;
struct llc_prim_if_block *ind_prim = ev->ind_prim;
struct llc_prim_if_block *cfm_prim = ev->cfm_prim;
llc_conn_free_ev(ev);
llc_conn_free_ev(skb);
#ifdef THIS_BREAKS_DISCONNECT_NOTIFICATION_BADLY
/* check if the connection was freed by the state machine by
* means of llc_conn_disc */
......@@ -125,15 +106,14 @@ void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
* llc_conn_rtn_pdu - sends received data pdu to upper layer
* @sk: Active connection
* @skb: Received data frame
* @ev: Occurred event
*
* Sends received data pdu to upper layer (by using indicate function).
* Prepares service parameters (prim and prim_data). calling indication
* function will be done in llc_conn_send_ev.
*/
void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb,
struct llc_conn_state_ev *ev)
void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap;
struct llc_prim_if_block *prim = &sap->llc_ind_prim;
......@@ -291,34 +271,37 @@ static void llc_conn_send_pdus(struct sock *sk)
/**
* llc_conn_free_ev - free event
* @ev: event to free
* @skb: event to free
*
* Free allocated event.
*/
void llc_conn_free_ev(struct llc_conn_state_ev *ev)
void llc_conn_free_ev(struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
if (ev->type == LLC_CONN_EV_TYPE_PDU) {
/* free the frame that binded to this event */
struct llc_pdu_sn *pdu =
(struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
/* free the frame that is bound to this event */
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
if (LLC_PDU_TYPE_IS_I(pdu) || !ev->flag || !ev->ind_prim)
kfree_skb(ev->data.pdu.skb);
}
/* free event structure to free list of the same */
kfree(ev);
kfree_skb(skb);
} else if (ev->type == LLC_CONN_EV_TYPE_PRIM &&
ev->data.prim.prim != LLC_DATA_PRIM)
kfree_skb(skb);
else if (ev->type == LLC_CONN_EV_TYPE_P_TMR)
kfree_skb(skb);
}
/**
* llc_conn_service - finds transition and changes state of connection
* @sk: connection
* @ev: happened event
* @skb: happened event
*
* This function finds transition that matches with happened event, then
* executes related actions and finally changes state of connection.
* Returns 0 for success, 1 for failure.
*/
static int llc_conn_service(struct sock *sk, struct llc_conn_state_ev *ev)
static int llc_conn_service(struct sock *sk, struct sk_buff *skb)
{
int rc = 1;
struct llc_conn_state_trans *trans;
......@@ -326,9 +309,9 @@ static int llc_conn_service(struct sock *sk, struct llc_conn_state_ev *ev)
if (llc_sk(sk)->state > NBR_CONN_STATES)
goto out;
rc = 0;
trans = llc_qualify_conn_ev(sk, ev);
trans = llc_qualify_conn_ev(sk, skb);
if (trans) {
rc = llc_exec_conn_trans_actions(sk, trans, ev);
rc = llc_exec_conn_trans_actions(sk, trans, skb);
if (!rc && trans->next_state != NO_STATE_CHANGE)
llc_sk(sk)->state = trans->next_state;
}
......@@ -339,26 +322,28 @@ static int llc_conn_service(struct sock *sk, struct llc_conn_state_ev *ev)
/**
* llc_qualify_conn_ev - finds transition for event
* @sk: connection
* @ev: happened event
* @skb: happened event
*
* This function finds transition that matches with happened event.
* Returns pointer to found transition on success, %NULL otherwise.
*/
static struct llc_conn_state_trans *
llc_qualify_conn_ev(struct sock *sk, struct llc_conn_state_ev *ev)
static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
struct sk_buff *skb)
{
struct llc_conn_state_trans **next_trans;
llc_conn_ev_qfyr_t *next_qualifier;
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_opt *llc = llc_sk(sk);
struct llc_conn_state *curr_state =
&llc_conn_state_table[llc_sk(sk)->state - 1];
&llc_conn_state_table[llc->state - 1];
/* search thru events for this state until
* list exhausted or until no more
*/
for (next_trans = curr_state->transitions +
llc_find_offset(llc_sk(sk)->state - 1, ev->type);
llc_find_offset(llc->state - 1, ev->type);
(*next_trans)->ev; next_trans++) {
if (!((*next_trans)->ev)(sk, ev)) {
if (!((*next_trans)->ev)(sk, skb)) {
/* got POSSIBLE event match; the event may require
* qualification based on the values of a number of
* state flags; if all qualifications are met (i.e.,
......@@ -367,7 +352,7 @@ static struct llc_conn_state_trans *
*/
for (next_qualifier = (*next_trans)->ev_qualifiers;
next_qualifier && *next_qualifier &&
!(*next_qualifier)(sk, ev); next_qualifier++)
!(*next_qualifier)(sk, skb); next_qualifier++)
/* nothing */;
if (!next_qualifier || !*next_qualifier)
/* all qualifiers executed successfully; this is
......@@ -384,7 +369,7 @@ static struct llc_conn_state_trans *
* llc_exec_conn_trans_actions - executes related actions
* @sk: connection
* @trans: transition that it's actions must be performed
* @ev: happened event
* @skb: happened event
*
* Executes actions that is related to happened event. Returns 0 for
* success, 1 to indicate failure of at least one action or 2 if the
......@@ -392,14 +377,14 @@ static struct llc_conn_state_trans *
*/
static int llc_exec_conn_trans_actions(struct sock *sk,
struct llc_conn_state_trans *trans,
struct llc_conn_state_ev *ev)
struct sk_buff *skb)
{
int rc = 0;
llc_conn_action_t *next_action;
for (next_action = trans->ev_actions;
next_action && *next_action; next_action++) {
int rc2 = (*next_action)(sk, ev);
int rc2 = (*next_action)(sk, skb);
if (rc2 == 2) {
rc = rc2;
......
......@@ -24,39 +24,48 @@
#include <net/llc_pdu.h>
int llc_stat_ev_enable_with_dup_addr_check(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
struct llc_station_state_ev *ev = llc_station_ev(skb);
return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
ev->data.a.ev ==
LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK ? 0 : 1;
}
int llc_stat_ev_enable_without_dup_addr_check(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
struct llc_station_state_ev *ev = llc_station_ev(skb);
return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
ev->data.a.ev ==
LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK ? 0 : 1;
}
int llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
struct llc_station_state_ev *ev = llc_station_ev(skb);
return ev->type == LLC_STATION_EV_TYPE_ACK_TMR &&
station->retry_count < station->maximum_retry ? 0 : 1;
}
int llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
struct llc_station_state_ev *ev = llc_station_ev(skb);
return ev->type == LLC_STATION_EV_TYPE_ACK_TMR &&
station->retry_count == station->maximum_retry ? 0 : 1;
}
int llc_stat_ev_rx_null_dsap_xid_c(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.skb);
struct llc_station_state_ev *ev = llc_station_ev(skb);
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
return ev->type == LLC_STATION_EV_TYPE_PDU &&
!LLC_PDU_IS_CMD(pdu) && /* command PDU */
......@@ -66,9 +75,10 @@ int llc_stat_ev_rx_null_dsap_xid_c(struct llc_station *station,
}
int llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.skb);
struct llc_station_state_ev *ev = llc_station_ev(skb);
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
return ev->type == LLC_STATION_EV_TYPE_PDU &&
!LLC_PDU_IS_RSP(pdu) && /* response PDU */
......@@ -79,9 +89,10 @@ int llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq(struct llc_station *station,
}
int llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.skb);
struct llc_station_state_ev *ev = llc_station_ev(skb);
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
return ev->type == LLC_STATION_EV_TYPE_PDU &&
!LLC_PDU_IS_RSP(pdu) && /* response PDU */
......@@ -92,9 +103,10 @@ int llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq(struct llc_station *station,
}
int llc_stat_ev_rx_null_dsap_test_c(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.skb);
struct llc_station_state_ev *ev = llc_station_ev(skb);
struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
return ev->type == LLC_STATION_EV_TYPE_PDU &&
!LLC_PDU_IS_CMD(pdu) && /* command PDU */
......@@ -103,9 +115,10 @@ int llc_stat_ev_rx_null_dsap_test_c(struct llc_station *station,
!pdu->dsap ? 0 : 1; /* NULL DSAP */
}
int llc_stat_ev_disable_req(struct llc_station *station,
struct llc_station_state_ev *ev)
int llc_stat_ev_disable_req(struct llc_station *station, struct sk_buff *skb)
{
struct llc_station_state_ev *ev = llc_station_ev(skb);
return ev->type == LLC_STATION_EV_TYPE_PRIM &&
ev->data.prim.prim == LLC_DISABLE_PRIM &&
ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
......
......@@ -168,15 +168,13 @@ static int llc_unitdata_req_handler(struct llc_prim_if_block *prim)
if (!sap)
goto out;
ev = llc_sap_alloc_ev(sap);
if (!ev)
goto out;
ev = llc_sap_ev(prim->data->udata.skb);
ev->type = LLC_SAP_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_DATAUNIT_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ;
ev->data.prim.data = prim;
rc = 0;
llc_sap_send_ev(sap, ev);
llc_sap_send_ev(sap, prim->data->udata.skb);
out:
return rc;
}
......@@ -196,15 +194,13 @@ static int llc_test_req_handler(struct llc_prim_if_block *prim)
struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap);
if (!sap)
goto out;
ev = llc_sap_alloc_ev(sap);
if (!ev)
goto out;
ev = llc_sap_ev(prim->data->udata.skb);
ev->type = LLC_SAP_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_TEST_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ;
ev->data.prim.data = prim;
rc = 0;
llc_sap_send_ev(sap, ev);
llc_sap_send_ev(sap, prim->data->udata.skb);
out:
return rc;
}
......@@ -225,15 +221,13 @@ static int llc_xid_req_handler(struct llc_prim_if_block *prim)
if (!sap)
goto out;
ev = llc_sap_alloc_ev(sap);
if (!ev)
goto out;
ev = llc_sap_ev(prim->data->udata.skb);
ev->type = LLC_SAP_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_XID_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ;
ev->data.prim.data = prim;
rc = 0;
llc_sap_send_ev(sap, ev);
llc_sap_send_ev(sap, prim->data->udata.skb);
out:
return rc;
}
......@@ -273,29 +267,26 @@ static int llc_data_req_handler(struct llc_prim_if_block *prim)
llc->failed_data_req = 1;
goto out;
}
rc = -ENOMEM;
ev = llc_conn_alloc_ev(sk);
if (ev) {
ev->type = LLC_CONN_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_DATA_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ;
ev->data.prim.data = prim;
prim->data->data.skb->dev = llc->dev;
rc = llc_conn_send_ev(sk, ev);
}
ev = llc_conn_ev(prim->data->data.skb);
ev->type = LLC_CONN_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_DATA_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ;
ev->data.prim.data = prim;
prim->data->data.skb->dev = llc->dev;
rc = llc_conn_send_ev(sk, prim->data->data.skb);
out:
release_sock(sk);
return rc;
}
/**
* confirm_impossible - Informs upper layer about failed connection
* llc_confirm_impossible - Informs upper layer about failed connection
* @prim: pointer to structure that contains confirmation data.
*
* Informs upper layer about failing in connection establishment. This
* function is called by llc_conn_req_handler.
*/
static void confirm_impossible(struct llc_prim_if_block *prim)
static void llc_confirm_impossible(struct llc_prim_if_block *prim)
{
prim->data->conn.status = LLC_STATUS_IMPOSSIBLE;
prim->sap->conf(prim);
......@@ -316,7 +307,7 @@ static int llc_conn_req_handler(struct llc_prim_if_block *prim)
int rc = -EBUSY;
struct llc_opt *llc;
struct llc_sap *sap = prim->sap;
struct llc_conn_state_ev *ev;
struct sk_buff *skb;
struct net_device *ddev = mac_dev_peer(prim->data->conn.dev,
prim->data->conn.dev->type,
prim->data->conn.daddr.mac),
......@@ -334,7 +325,7 @@ static int llc_conn_req_handler(struct llc_prim_if_block *prim)
daddr.lsap = prim->data->conn.daddr.lsap;
sk = llc_find_sock(sap, &daddr, &laddr);
if (sk) {
confirm_impossible(prim);
llc_confirm_impossible(prim);
goto out_put;
}
rc = -ENOMEM;
......@@ -345,7 +336,7 @@ static int llc_conn_req_handler(struct llc_prim_if_block *prim)
} else {
sk = llc_sock_alloc();
if (!sk) {
confirm_impossible(prim);
llc_confirm_impossible(prim);
goto out;
}
prim->data->conn.sk = sk;
......@@ -360,18 +351,20 @@ static int llc_conn_req_handler(struct llc_prim_if_block *prim)
llc->dev = ddev;
llc->link = prim->data->conn.link;
llc->handler = prim->data->conn.handler;
ev = llc_conn_alloc_ev(sk);
if (ev) {
skb = alloc_skb(1, GFP_ATOMIC);
if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
ev->type = LLC_CONN_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_CONN_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ;
ev->data.prim.data = prim;
rc = llc_conn_send_ev(sk, ev);
rc = llc_conn_send_ev(sk, skb);
}
if (rc) {
llc_sap_unassign_sock(sap, sk);
llc_sock_free(sk);
confirm_impossible(prim);
llc_confirm_impossible(prim);
}
release_sock(sk);
out_put:
......@@ -393,6 +386,7 @@ static int llc_disc_req_handler(struct llc_prim_if_block *prim)
{
u16 rc = 1;
struct llc_conn_state_ev *ev;
struct sk_buff *skb;
struct sock* sk = prim->data->disc.sk;
sock_hold(sk);
......@@ -400,17 +394,19 @@ static int llc_disc_req_handler(struct llc_prim_if_block *prim)
if (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
/*
* Postpone unassigning the connection from its SAP and returning the
* connection until all ACTIONs have been completely executed
*/
ev = llc_conn_alloc_ev(sk);
if (!ev)
skb = alloc_skb(1, GFP_ATOMIC);
if (!skb)
goto out;
ev->type = LLC_CONN_EV_TYPE_PRIM;
ev = llc_conn_ev(skb);
ev->type = LLC_CONN_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_DISC_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ;
ev->data.prim.data = prim;
rc = llc_conn_send_ev(sk, ev);
rc = llc_conn_send_ev(sk, skb);
out:
release_sock(sk);
sock_put(sk);
......@@ -428,18 +424,20 @@ static int llc_disc_req_handler(struct llc_prim_if_block *prim)
*/
static int llc_rst_req_handler(struct llc_prim_if_block *prim)
{
struct sk_buff *skb;
int rc = 1;
struct sock *sk = prim->data->res.sk;
struct llc_conn_state_ev *ev;
lock_sock(sk);
ev = llc_conn_alloc_ev(sk);
if (ev) {
skb = alloc_skb(1, GFP_ATOMIC);
if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
ev->type = LLC_CONN_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_RESET_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ;
ev->data.prim.data = prim;
rc = llc_conn_send_ev(sk, ev);
rc = llc_conn_send_ev(sk, skb);
}
release_sock(sk);
return rc;
......@@ -497,18 +495,21 @@ static int llc_conn_rsp_handler(struct llc_prim_if_block *prim)
static int llc_rst_rsp_handler(struct llc_prim_if_block *prim)
{
int rc = 1;
/* network layer supplies connection handle; map it to a connection;
/*
* Network layer supplies connection handle; map it to a connection;
* package as event and send it to connection event handler
*/
struct sock *sk = prim->data->res.sk;
struct llc_conn_state_ev *ev = llc_conn_alloc_ev(sk);
struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC);
if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
if (ev) {
ev->type = LLC_CONN_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_RESET_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_RESP;
ev->data.prim.data = prim;
rc = llc_conn_send_ev(sk, ev);
rc = llc_conn_send_ev(sk, skb);
}
return rc;
}
......
......@@ -27,6 +27,12 @@
#include <net/llc_s_ev.h>
#include <linux/trdevice.h>
#if 1
#define dprintk(args...) printk(KERN_DEBUG args)
#else
#define dprintk(args...)
#endif
/* function prototypes */
static void fix_up_incoming_skb(struct sk_buff *skb);
......@@ -46,7 +52,7 @@ int mac_send_pdu(struct sk_buff *skb)
int pri = GFP_ATOMIC, rc = -1;
if (!skb->dev) {
printk(KERN_ERR "%s: skb->dev == NULL!", __FUNCTION__);
dprintk(KERN_ERR "%s: skb->dev == NULL!", __FUNCTION__);
goto out;
}
if (skb->sk)
......@@ -83,7 +89,7 @@ int mac_indicate(struct sk_buff *skb, struct net_device *dev,
* receives, do not try to analyse it.
*/
if (skb->pkt_type == PACKET_OTHERHOST) {
printk(KERN_INFO "%s: PACKET_OTHERHOST\n", __FUNCTION__);
dprintk(KERN_INFO "%s: PACKET_OTHERHOST\n", __FUNCTION__);
goto drop;
}
skb = skb_share_check(skb, GFP_ATOMIC);
......@@ -140,7 +146,8 @@ int mac_indicate(struct sk_buff *skb, struct net_device *dev,
rc = llc_pdu_router(llc_sk(sk)->sap, sk, skb,
LLC_TYPE_2);
} else {
skb->cb[0] = LLC_PACKET;
dprintk(KERN_INFO "%s: add to backlog\n", __FUNCTION__);
llc_set_backlog_type(skb, LLC_PACKET);
sk_add_backlog(sk, skb);
rc = 0;
}
......@@ -207,38 +214,27 @@ int llc_pdu_router(struct llc_sap *sap, struct sock* sk,
if (!pdu->dsap) {
struct llc_station *station = llc_station_get();
struct llc_station_state_ev *stat_ev =
llc_station_alloc_ev(station);
if (stat_ev) {
stat_ev->type = LLC_STATION_EV_TYPE_PDU;
stat_ev->data.pdu.skb = skb;
stat_ev->data.pdu.reason = 0;
llc_station_send_ev(station, stat_ev);
} else
rc = -ENOMEM;
struct llc_station_state_ev *ev = llc_station_ev(skb);
ev->type = LLC_STATION_EV_TYPE_PDU;
ev->data.pdu.reason = 0;
llc_station_send_ev(station, skb);
} else if (type == LLC_TYPE_1) {
struct llc_sap_state_ev *sap_ev = llc_sap_alloc_ev(sap);
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
if (sap_ev) {
sap_ev->type = LLC_SAP_EV_TYPE_PDU;
sap_ev->data.pdu.skb = skb;
sap_ev->data.pdu.reason = 0;
llc_sap_send_ev(sap, sap_ev);
} else
rc = -ENOMEM;
ev->type = LLC_SAP_EV_TYPE_PDU;
ev->data.pdu.reason = 0;
llc_sap_send_ev(sap, skb);
} else if (type == LLC_TYPE_2) {
struct llc_conn_state_ev *conn_ev = llc_conn_alloc_ev(sk);
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_opt *llc = llc_sk(sk);
if (!llc->dev)
llc->dev = skb->dev;
if (conn_ev) {
conn_ev->type = LLC_CONN_EV_TYPE_PDU;
conn_ev->data.pdu.skb = skb;
conn_ev->data.pdu.reason = 0;
rc = llc_conn_send_ev(sk, conn_ev);
} else
rc = -ENOMEM;
ev->type = LLC_CONN_EV_TYPE_PDU;
ev->data.pdu.reason = 0;
rc = llc_conn_send_ev(sk, skb);
} else
rc = -EINVAL;
return rc;
......
......@@ -38,16 +38,16 @@
/* static function prototypes */
static void llc_station_service_events(struct llc_station *station);
static void llc_station_free_ev(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
static void llc_station_send_pdus(struct llc_station *station);
static u16 llc_station_next_state(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
static u16 llc_exec_station_trans_actions(struct llc_station *station,
struct llc_station_state_trans *trans,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
static struct llc_station_state_trans *
llc_find_station_trans(struct llc_station *station,
struct llc_station_state_ev *ev);
struct sk_buff *skb);
static int llc_rtn_all_conns(struct llc_sap *sap);
static struct llc_station llc_main_station; /* only one of its kind */
......@@ -144,21 +144,23 @@ static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
int rc = 0;
struct llc_opt *llc = llc_sk(sk);
if (skb->cb[0] == LLC_PACKET) {
if (llc_backlog_type(skb) == LLC_PACKET) {
if (llc->state > 1) /* not closed */
rc = llc_pdu_router(llc->sap, sk, skb, LLC_TYPE_2);
else
kfree_skb(skb);
} else if (skb->cb[0] == LLC_EVENT) {
struct llc_conn_state_ev *ev =
(struct llc_conn_state_ev *)skb->data;
} else if (llc_backlog_type(skb) == LLC_EVENT) {
/* timer expiration event */
if (llc->state > 1) /* not closed */
rc = llc_conn_send_ev(sk, ev);
rc = llc_conn_send_ev(sk, skb);
else
llc_conn_free_ev(ev);
llc_conn_free_ev(skb);
kfree_skb(skb);
} else {
printk(KERN_ERR "%s: invalid skb in backlog\n", __FUNCTION__);
kfree_skb(skb);
}
return rc;
}
......@@ -232,9 +234,11 @@ void __llc_sock_free(struct sock *sk, u8 free)
/* stop all (possibly) running timers */
llc_conn_ac_stop_all_timers(sk, NULL);
/* handle return of frames on lists */
#if 0
printk(KERN_INFO "%s: unackq=%d, txq=%d\n", __FUNCTION__,
skb_queue_len(&llc->pdu_unack_q),
skb_queue_len(&sk->write_queue));
#endif
skb_queue_purge(&sk->write_queue);
skb_queue_purge(&llc->pdu_unack_q);
if (free)
......@@ -315,35 +319,18 @@ struct llc_station *llc_station_get(void)
return &llc_main_station;
}
/**
* llc_station_alloc_ev - allocates an event
* @station: Address of the station
*
* Allocates an event in this station. Returns the allocated event on
* success, %NULL otherwise.
*/
struct llc_station_state_ev *llc_station_alloc_ev(struct llc_station *station)
{
struct llc_station_state_ev *ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
if (ev)
memset(ev, 0, sizeof(*ev));
return ev;
}
/**
* llc_station_send_ev: queue event and try to process queue.
* @station: Address of the station
* @ev: Address of the event
* @skb: Address of the event
*
* Queues an event (on the station event queue) for handling by the
* station state machine and attempts to process any queued-up events.
*/
void llc_station_send_ev(struct llc_station *station,
struct llc_station_state_ev *ev)
void llc_station_send_ev(struct llc_station *station, struct sk_buff *skb)
{
spin_lock_bh(&station->ev_q.lock);
list_add_tail(&ev->node, &station->ev_q.list);
skb_queue_tail(&station->ev_q.list, skb);
llc_station_service_events(station);
spin_unlock_bh(&station->ev_q.lock);
}
......@@ -384,18 +371,17 @@ static void llc_station_send_pdus(struct llc_station *station)
/**
* llc_station_free_ev - frees an event
* @station: Address of the station
* @event: Address of the event
* @skb: Address of the event
*
* Frees an event.
*/
static void llc_station_free_ev(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
struct sk_buff *skb = ev->data.pdu.skb;
struct llc_station_state_ev *ev = llc_station_ev(skb);
if (ev->type == LLC_STATION_EV_TYPE_PDU)
kfree_skb(skb);
kfree(ev);
}
/**
......@@ -412,39 +398,35 @@ static void llc_station_free_ev(struct llc_station *station,
*/
static void llc_station_service_events(struct llc_station *station)
{
struct llc_station_state_ev *ev;
struct list_head *entry, *tmp;
struct sk_buff *skb;
list_for_each_safe(entry, tmp, &station->ev_q.list) {
ev = list_entry(entry, struct llc_station_state_ev, node);
list_del(&ev->node);
llc_station_next_state(station, ev);
}
while ((skb = skb_dequeue(&station->ev_q.list)) != NULL)
llc_station_next_state(station, skb);
}
/**
* llc_station_next_state - processes event and goes to the next state
* @station: Address of the station
* @ev: Address of the event
* @skb: Address of the event
*
* Processes an event, executes any transitions related to that event and
* updates the state of the station.
*/
static u16 llc_station_next_state(struct llc_station *station,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
u16 rc = 1;
struct llc_station_state_trans *trans;
if (station->state > LLC_NBR_STATION_STATES)
goto out;
trans = llc_find_station_trans(station, ev);
trans = llc_find_station_trans(station, skb);
if (trans) {
/* 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_station_trans_actions(station, trans, ev);
rc = llc_exec_station_trans_actions(station, trans, skb);
if (!rc)
/* transition station to next state if all actions
* execute successfully; done; wait for next event
......@@ -456,22 +438,22 @@ static u16 llc_station_next_state(struct llc_station *station,
*/
rc = 0;
out:
llc_station_free_ev(station, ev);
llc_station_free_ev(station, skb);
return rc;
}
/**
* llc_find_station_trans - finds transition for this event
* @station: Address of the station
* @ev: Address of the event
* @skb: Address of the event
*
* Search thru events of the current state of the station until list
* exhausted or it's obvious that the event is not valid for the current
* state. Returns the address of the transition if cound, %NULL otherwise.
*/
static struct llc_station_state_trans *
llc_find_station_trans(struct llc_station *station,
struct llc_station_state_ev *ev)
llc_find_station_trans(struct llc_station *station,
struct sk_buff *skb)
{
int i = 0;
struct llc_station_state_trans *rc = NULL;
......@@ -480,7 +462,7 @@ static struct llc_station_state_trans *
&llc_station_state_table[station->state - 1];
for (next_trans = curr_state->transitions; next_trans[i]->ev; i++)
if (!next_trans[i]->ev(station, ev)) {
if (!next_trans[i]->ev(station, skb)) {
rc = next_trans[i];
break;
}
......@@ -491,21 +473,20 @@ static struct llc_station_state_trans *
* llc_exec_station_trans_actions - executes actions for transition
* @station: Address of the station
* @trans: Address of the transition
* @ev: Address of the event that caused the transition
* @skb: Address of the event that caused the transition
*
* Executes actions of a transition of the station state machine. Returns
* 0 if all actions complete successfully, nonzero otherwise.
*/
static u16 llc_exec_station_trans_actions(struct llc_station *station,
struct llc_station_state_trans *trans,
struct llc_station_state_ev *ev)
struct sk_buff *skb)
{
u16 rc = 0;
llc_station_action_t *next_action;
llc_station_action_t *next_action = trans->ev_actions;
for (next_action = trans->ev_actions;
next_action && *next_action; next_action++)
if ((*next_action)(station, ev))
for (; next_action && *next_action; next_action++)
if ((*next_action)(station, skb))
rc = 1;
return rc;
}
......@@ -595,21 +576,24 @@ static char llc_error_msg[] __initdata =
static int __init llc_init(void)
{
u16 rc = 0;
struct sk_buff *skb;
struct llc_station_state_ev *ev;
printk(llc_banner);
INIT_LIST_HEAD(&llc_main_station.ev_q.list);
spin_lock_init(&llc_main_station.ev_q.lock);
INIT_LIST_HEAD(&llc_main_station.sap_list.list);
spin_lock_init(&llc_main_station.sap_list.lock);
skb_queue_head_init(&llc_main_station.mac_pdu_q);
ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
if (!ev)
skb_queue_head_init(&llc_main_station.ev_q.list);
spin_lock_init(&llc_main_station.ev_q.lock);
skb = alloc_skb(1, GFP_ATOMIC);
if (!skb)
goto err;
llc_build_offset_table();
ev = llc_station_ev(skb);
memset(ev, 0, sizeof(*ev));
if(dev_base->next)
memcpy(llc_main_station.mac_sa, dev_base->next->dev_addr, ETH_ALEN);
if (dev_base->next)
memcpy(llc_main_station.mac_sa,
dev_base->next->dev_addr, ETH_ALEN);
else
memset(llc_main_station.mac_sa, 0, ETH_ALEN);
llc_main_station.ack_timer.expires = jiffies + 3 * HZ;
......@@ -617,7 +601,7 @@ static int __init llc_init(void)
llc_main_station.state = LLC_STATION_STATE_DOWN;
ev->type = LLC_STATION_EV_TYPE_SIMPLE;
ev->data.a.ev = LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
rc = llc_station_next_state(&llc_main_station, ev);
rc = llc_station_next_state(&llc_main_station, skb);
proc_net_create("802.2", 0, llc_proc_get_info);
llc_ui_init();
dev_add_pack(&llc_packet_type);
......
......@@ -28,32 +28,31 @@
/**
* llc_sap_action_unit_data_ind - forward UI PDU to network layer
* @sap: SAP
* @ev: the event to forward
* @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 llc_sap_state_ev *ev)
int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb)
{
llc_sap_rtn_pdu(sap, ev->data.pdu.skb, ev);
llc_sap_rtn_pdu(sap, skb);
return 0;
}
/**
* llc_sap_action_send_ui - sends UI PDU resp to UNITDATA REQ to MAC layer
* @sap: SAP
* @ev: the event to send
* @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 llc_sap_state_ev *ev)
int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
struct llc_prim_if_block *prim = ev->data.prim.data;
struct llc_prim_unit_data *prim_data = &prim->data->udata;
struct sk_buff *skb = prim->data->udata.skb;
int rc;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap,
......@@ -71,17 +70,17 @@ int llc_sap_action_send_ui(struct llc_sap *sap, struct llc_sap_state_ev *ev)
/**
* llc_sap_action_send_xid_c - send XID PDU as response to XID REQ
* @sap: SAP
* @ev: the event to send
* @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 llc_sap_state_ev *ev)
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);
struct llc_prim_if_block *prim = ev->data.prim.data;
struct llc_prim_xid *prim_data = &prim->data->xid;
struct sk_buff *skb = prim_data->skb;
int rc;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap,
......@@ -99,33 +98,32 @@ int llc_sap_action_send_xid_c(struct llc_sap *sap, struct llc_sap_state_ev *ev)
/**
* llc_sap_action_send_xid_r - send XID PDU resp to MAC for received XID
* @sap: SAP
* @ev: the event to send
* @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 llc_sap_state_ev *ev)
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 *ev_skb = ev->data.pdu.skb;
struct sk_buff *skb;
struct sk_buff *nskb;
llc_pdu_decode_sa(ev_skb, mac_da);
llc_pdu_decode_da(ev_skb, mac_sa);
llc_pdu_decode_ssap(ev_skb, &dsap);
skb = llc_alloc_frame();
if (!skb)
llc_pdu_decode_sa(skb, mac_da);
llc_pdu_decode_da(skb, mac_sa);
llc_pdu_decode_ssap(skb, &dsap);
nskb = llc_alloc_frame();
if (!nskb)
goto out;
skb->dev = ev_skb->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
nskb->dev = skb->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
LLC_PDU_RSP);
rc = llc_pdu_init_as_xid_rsp(skb, LLC_XID_NULL_CLASS_2, 0);
rc = llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0);
if (rc)
goto out;
rc = lan_hdrs_init(skb, mac_sa, mac_da);
rc = lan_hdrs_init(nskb, mac_sa, mac_da);
if (!rc)
llc_sap_send_pdu(sap, skb);
llc_sap_send_pdu(sap, nskb);
out:
return rc;
}
......@@ -133,17 +131,17 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct llc_sap_state_ev *ev)
/**
* llc_sap_action_send_test_c - send TEST PDU to MAC in resp to TEST REQ
* @sap: SAP
* @ev: the event to send
* @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 llc_sap_state_ev *ev)
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);
struct llc_prim_if_block *prim = ev->data.prim.data;
struct llc_prim_test *prim_data = &prim->data->test;
struct sk_buff *skb = prim_data->skb;
int rc;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap,
......@@ -158,28 +156,27 @@ int llc_sap_action_send_test_c(struct llc_sap *sap, struct llc_sap_state_ev *ev)
return rc;
}
int llc_sap_action_send_test_r(struct llc_sap *sap, struct llc_sap_state_ev *ev)
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;
struct sk_buff *ev_skb = ev->data.pdu.skb;
struct sk_buff *skb;
llc_pdu_decode_sa(ev_skb, mac_da);
llc_pdu_decode_da(ev_skb, mac_sa);
llc_pdu_decode_ssap(ev_skb, &dsap);
skb = llc_alloc_frame();
if (!skb)
llc_pdu_decode_sa(skb, mac_da);
llc_pdu_decode_da(skb, mac_sa);
llc_pdu_decode_ssap(skb, &dsap);
nskb = llc_alloc_frame();
if (!nskb)
goto out;
skb->dev = ev_skb->dev;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
nskb->dev = skb->dev;
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
LLC_PDU_RSP);
rc = llc_pdu_init_as_test_rsp(skb, ev_skb);
rc = llc_pdu_init_as_test_rsp(nskb, skb);
if (rc)
goto out;
rc = lan_hdrs_init(skb, mac_sa, mac_da);
rc = lan_hdrs_init(nskb, mac_sa, mac_da);
if (!rc)
llc_sap_send_pdu(sap, skb);
llc_sap_send_pdu(sap, nskb);
out:
return rc;
}
......@@ -187,13 +184,12 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct llc_sap_state_ev *ev)
/**
* llc_sap_action_report_status - report data link status to layer mgmt
* @sap: SAP
* @ev: the event to send
* @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 llc_sap_state_ev *ev)
int llc_sap_action_report_status(struct llc_sap *sap, struct sk_buff *skb)
{
return 0;
}
......@@ -201,27 +197,27 @@ int llc_sap_action_report_status(struct llc_sap *sap,
/**
* llc_sap_action_xid_ind - send XID PDU resp to net layer via XID IND
* @sap: SAP
* @ev: the event to send
* @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 llc_sap_state_ev *ev)
int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb)
{
llc_sap_rtn_pdu(sap, ev->data.pdu.skb, ev);
llc_sap_rtn_pdu(sap, skb);
return 0;
}
/**
* llc_sap_action_test_ind - send TEST PDU to net layer via TEST IND
* @sap: SAP
* @ev: the event to send
* @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 llc_sap_state_ev *ev)
int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb)
{
llc_sap_rtn_pdu(sap, ev->data.pdu.skb, ev);
llc_sap_rtn_pdu(sap, skb);
return 0;
}
......@@ -20,82 +20,96 @@
#include <net/llc_s_ev.h>
#include <net/llc_pdu.h>
int llc_sap_ev_activation_req(struct llc_sap *sap, struct llc_sap_state_ev *ev)
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->data.a.ev == LLC_SAP_EV_ACTIVATION_REQ ? 0 : 1;
}
int llc_sap_ev_rx_ui(struct llc_sap *sap, struct llc_sap_state_ev *ev)
int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.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 llc_sap_state_ev *ev)
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->data.prim.prim == LLC_DATAUNIT_PRIM &&
ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_sap_ev_xid_req(struct llc_sap *sap, struct llc_sap_state_ev *ev)
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->data.prim.prim == LLC_XID_PRIM &&
ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct llc_sap_state_ev *ev)
int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.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 llc_sap_state_ev *ev)
int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.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 llc_sap_state_ev *ev)
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->data.prim.prim == LLC_TEST_PRIM &&
ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct llc_sap_state_ev *ev)
int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.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 llc_sap_state_ev *ev)
int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_pdu_un *pdu = llc_pdu_un_hdr(ev->data.pdu.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 llc_sap_state_ev *ev)
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->data.a.ev == LLC_SAP_EV_DEACTIVATION_REQ ? 0 : 1;
}
......@@ -24,7 +24,7 @@
* last entry for this state
* all members are zeros, .bss zeroes it
*/
static struct llc_sap_state_trans llc_sap_state_trans_n;
static struct llc_sap_state_trans llc_sap_state_trans_end;
/* state LLC_SAP_STATE_INACTIVE transition for
* LLC_SAP_EV_ACTIVATION_REQ event
......@@ -43,7 +43,7 @@ static struct llc_sap_state_trans llc_sap_inactive_state_trans_1 = {
/* array of pointers; one to each transition */
static struct llc_sap_state_trans *llc_sap_inactive_state_transitions[] = {
[0] = &llc_sap_inactive_state_trans_1,
[1] = &llc_sap_state_trans_n,
[1] = &llc_sap_state_trans_end,
};
/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_UI event */
......@@ -167,17 +167,17 @@ static struct llc_sap_state_trans *llc_sap_active_state_transitions[] = {
[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_n,
[9] = &llc_sap_state_trans_end,
};
/* SAP state transition table */
struct llc_sap_state llc_sap_state_table[] = {
{
.curr_state = LLC_SAP_STATE_INACTIVE,
.transitions = llc_sap_inactive_state_transitions,
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,
},
{
.curr_state = LLC_SAP_STATE_ACTIVE,
.transitions = llc_sap_active_state_transitions,
[LLC_SAP_STATE_ACTIVE - 1] = {
.curr_state = LLC_SAP_STATE_ACTIVE,
.transitions = llc_sap_active_state_transitions,
},
};
......@@ -23,13 +23,13 @@
#include <net/llc_pdu.h>
#include <linux/if_tr.h>
static void llc_sap_free_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev);
static int llc_sap_next_state(struct llc_sap *sap, struct llc_sap_state_ev *ev);
static void llc_sap_free_ev(struct llc_sap *sap, struct sk_buff *skb);
static int llc_sap_next_state(struct llc_sap *sap, struct sk_buff *skb);
static int llc_exec_sap_trans_actions(struct llc_sap *sap,
struct llc_sap_state_trans *trans,
struct llc_sap_state_ev *ev);
struct sk_buff *skb);
static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
struct sk_buff *skb);
/**
* llc_sap_assign_sock - adds a connection to a SAP
......@@ -63,50 +63,35 @@ void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk)
spin_unlock_bh(&sap->sk_list.lock);
}
/**
* llc_sap_alloc_ev - allocates sap event
* @sap: pointer to SAP
* @ev: allocated event (output argument)
*
* Returns the allocated sap event or %NULL when out of memory.
*/
struct llc_sap_state_ev *llc_sap_alloc_ev(struct llc_sap *sap)
{
struct llc_sap_state_ev *ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
if (ev)
memset(ev, 0, sizeof(*ev));
return ev;
}
/**
* llc_sap_send_ev - sends event to SAP state machine
* @sap: pointer to SAP
* @ev: pointer to occurred event
* @skb: pointer to occurred event
*
* After executing actions of the event, upper layer will be indicated
* if needed(on receiving an UI frame).
*/
void llc_sap_send_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev)
void llc_sap_send_ev(struct llc_sap *sap, struct sk_buff *skb)
{
llc_sap_next_state(sap, ev);
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
llc_sap_next_state(sap, skb);
if (ev->ind_cfm_flag == LLC_IND) {
skb_get(ev->data.pdu.skb);
skb_get(skb);
sap->ind(ev->prim);
}
llc_sap_free_ev(sap, ev);
llc_sap_free_ev(sap, skb);
}
/**
* llc_sap_rtn_pdu - Informs upper layer on rx of an UI, XID or TEST pdu.
* @sap: pointer to SAP
* @skb: received pdu
* @ev: pointer to occurred event
*/
void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb,
struct llc_sap_state_ev *ev)
void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_pdu_un *pdu;
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
struct llc_prim_if_block *prim = &sap->llc_ind_prim;
union llc_u_prim_data *prim_data = prim->data;
u8 lfb;
......@@ -160,37 +145,38 @@ void llc_sap_send_pdu(struct llc_sap *sap, struct sk_buff *skb)
/**
* llc_sap_free_ev - frees an sap event
* @sap: pointer to SAP
* @ev: released event
* @skb: released event
*/
static void llc_sap_free_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev)
static void llc_sap_free_ev(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
if (ev->type == LLC_SAP_EV_TYPE_PDU)
kfree_skb(ev->data.pdu.skb);
kfree(ev);
kfree_skb(skb);
}
/**
* llc_sap_next_state - finds transition, execs actions & change SAP state
* @sap: pointer to SAP
* @ev: happened event
* @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 llc_sap_state_ev *ev)
static int llc_sap_next_state(struct llc_sap *sap, struct sk_buff *skb)
{
int rc = 1;
struct llc_sap_state_trans *trans;
if (sap->state <= LLC_NBR_SAP_STATES) {
trans = llc_find_sap_trans(sap, ev);
if (sap->state <= LLC_NR_SAP_STATES) {
trans = llc_find_sap_trans(sap, skb);
if (trans) {
/* 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, ev);
rc = llc_exec_sap_trans_actions(sap, trans, skb);
if (!rc)
/* transition SAP to next state if all actions
* execute successfully
......@@ -204,14 +190,14 @@ static int llc_sap_next_state(struct llc_sap *sap, struct llc_sap_state_ev *ev)
/**
* llc_find_sap_trans - finds transition for event
* @sap: pointer to SAP
* @ev: happened event
* @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 struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap,
struct llc_sap_state_ev* ev)
struct sk_buff* skb)
{
int i = 0;
struct llc_sap_state_trans *rc = NULL;
......@@ -221,7 +207,7 @@ static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap,
* 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, ev)) {
if (!next_trans[i]->ev(sap, skb)) {
/* got event match; return it */
rc = next_trans[i];
break;
......@@ -233,21 +219,20 @@ static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap,
* 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
* @ev: happened event.
* @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,
struct llc_sap_state_trans *trans,
struct llc_sap_state_ev *ev)
struct sk_buff *skb)
{
int rc = 0;
llc_sap_action_t *next_action;
llc_sap_action_t *next_action = trans->ev_actions;
for (next_action = trans->ev_actions;
next_action && *next_action; next_action++)
if ((*next_action)(sap, ev))
for (; next_action && *next_action; next_action++)
if ((*next_action)(sap, skb))
rc = 1;
return rc;
}
......@@ -1629,6 +1629,13 @@ static int llc_ui_confirm(struct llc_prim_if_block *prim)
}
#ifdef CONFIG_PROC_FS
#define MAC_FORMATTED_SIZE 17
static void llc_ui_format_mac(char *bf, unsigned char *mac)
{
sprintf(bf, "%02X:%02X:%02X:%02X:%02X:%02X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
/**
* llc_ui_get_info - return info to procfs
* @buffer: where to put the formatted output
......@@ -1656,41 +1663,25 @@ static int llc_ui_get_info(char *buffer, char **start, off_t offset, int length)
if (llc_ui->sap) {
if (llc_ui->dev &&
llc_ui_mac_null(llc_ui->addr.sllc_mmac))
len += sprintf(buffer + len,
"%02X:%02X:%02X:%02X:%02X:%02X",
llc_ui->dev->dev_addr[0],
llc_ui->dev->dev_addr[1],
llc_ui->dev->dev_addr[2],
llc_ui->dev->dev_addr[3],
llc_ui->dev->dev_addr[4],
llc_ui->dev->dev_addr[5]);
llc_ui_format_mac(buffer + len,
llc_ui->dev->dev_addr);
else {
if (!llc_ui_mac_null(llc_ui->addr.sllc_mmac))
len += sprintf(buffer + len,
"%02X:%02X:%02X:%02X:%02X:%02X",
llc_ui->addr.sllc_mmac[0],
llc_ui->addr.sllc_mmac[1],
llc_ui->addr.sllc_mmac[2],
llc_ui->addr.sllc_mmac[3],
llc_ui->addr.sllc_mmac[4],
llc_ui->addr.sllc_mmac[5]);
llc_ui_format_mac(buffer + len,
llc_ui->addr.sllc_mmac);
else
len += sprintf(buffer + len,
"00:00:00:00:00:00");
sprintf(buffer + len,
"00:00:00:00:00:00");
}
len += MAC_FORMATTED_SIZE;
len += sprintf(buffer + len, "@%02X ",
llc_ui->sap->laddr.lsap);
} else
len += sprintf(buffer + len, "00:00:00:00:00:00@00 ");
llc_ui_format_mac(buffer + len, llc_ui->addr.sllc_dmac);
len += MAC_FORMATTED_SIZE;
len += sprintf(buffer + len,
"%02X:%02X:%02X:%02X:%02X:%02X@%02X "
"%08X:%08X %02X %-3d ",
llc_ui->addr.sllc_dmac[0],
llc_ui->addr.sllc_dmac[1],
llc_ui->addr.sllc_dmac[2],
llc_ui->addr.sllc_dmac[3],
llc_ui->addr.sllc_dmac[4],
llc_ui->addr.sllc_dmac[5],
"@%02X %08d:%08d %02d %-3d ",
llc_ui->addr.sllc_dsap,
atomic_read(&s->wmem_alloc),
atomic_read(&s->rmem_alloc), s->state,
......
......@@ -24,7 +24,7 @@
* last entry for this state
* all members are zeros, .bss zeroes it
*/
static struct llc_station_state_trans llc_stat_state_trans_n;
static struct llc_station_state_trans llc_stat_state_trans_end;
/* DOWN STATE transitions */
......@@ -59,7 +59,7 @@ static struct llc_station_state_trans llc_stat_down_state_trans_2 = {
static struct llc_station_state_trans *llc_stat_dwn_state_trans[] = {
[0] = &llc_stat_down_state_trans_1,
[1] = &llc_stat_down_state_trans_2,
[2] = &llc_stat_state_trans_n,
[2] = &llc_stat_state_trans_end,
};
/* UP STATE transitions */
......@@ -104,7 +104,7 @@ static struct llc_station_state_trans *llc_stat_up_state_trans [] = {
[0] = &llc_stat_up_state_trans_1,
[1] = &llc_stat_up_state_trans_2,
[2] = &llc_stat_up_state_trans_3,
[3] = &llc_stat_state_trans_n,
[3] = &llc_stat_state_trans_end,
};
/* DUP ADDR CHK STATE transitions */
......@@ -162,7 +162,7 @@ static llc_station_action_t llc_stat_dupaddr_state_actions_4[] = {
static struct llc_station_state_trans llc_stat_dupaddr_state_trans_4 = {
.ev = llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry,
.next_state = LLC_STATION_STATE_DUP_ADDR_CHK,
.ev_actions = llc_stat_dupaddr_state_actions_4
.ev_actions = llc_stat_dupaddr_state_actions_4,
};
/* state transition for LLC_STATION_EV_ACK_TMR_EXP_EQ_RETRY_CNT_MAX_RETRY
......@@ -199,20 +199,20 @@ static struct llc_station_state_trans *llc_stat_dupaddr_state_trans[] = {
[3] = &llc_stat_dupaddr_state_trans_1, /* Receive frame */
[4] = &llc_stat_dupaddr_state_trans_2,
[5] = &llc_stat_dupaddr_state_trans_3,
[6] = &llc_stat_state_trans_n
[6] = &llc_stat_state_trans_end,
};
struct llc_station_state llc_station_state_table[LLC_NBR_STATION_STATES] = {
{
[LLC_STATION_STATE_DOWN - 1] = {
.curr_state = LLC_STATION_STATE_DOWN,
.transitions = llc_stat_dwn_state_trans,
},
{
[LLC_STATION_STATE_DUP_ADDR_CHK - 1] = {
.curr_state = LLC_STATION_STATE_DUP_ADDR_CHK,
.transitions = llc_stat_dupaddr_state_trans,
},
{
[LLC_STATION_STATE_UP - 1] = {
.curr_state = LLC_STATION_STATE_UP,
.transitions = llc_stat_up_state_trans,
}
},
};
......@@ -618,6 +618,9 @@ static unix_socket *unix_find_other(struct sockaddr_un *sunname, int len,
if (!u)
goto put_fail;
if (u->type == type)
UPDATE_ATIME(nd.dentry->d_inode);
path_release(&nd);
err=-EPROTOTYPE;
......@@ -628,7 +631,12 @@ static unix_socket *unix_find_other(struct sockaddr_un *sunname, int len,
} else {
err = -ECONNREFUSED;
u=unix_find_socket_byname(sunname, len, type, hash);
if (!u)
if (u) {
struct dentry *dentry;
dentry = u->protinfo.af_unix.dentry;
if (dentry)
UPDATE_ATIME(dentry->d_inode);
} else
goto fail;
}
return u;
......@@ -1400,7 +1408,7 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
{
struct unix_sock *u = unix_sk(sk);
msg->msg_namelen = sizeof(short);
msg->msg_namelen = 0;
if (u->addr) {
msg->msg_namelen = u->addr->len;
memcpy(msg->msg_name, u->addr->name, u->addr->len);
......@@ -1909,8 +1917,4 @@ static void __exit af_unix_exit(void)
module_init(af_unix_init);
module_exit(af_unix_exit);
/*
* Local variables:
* compile-command: "gcc -g -D__KERNEL__ -Wall -O6 -I/usr/src/linux/include -c af_unix.c"
* End:
*/
MODULE_LICENSE("GPL");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment