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
...@@ -149,6 +149,8 @@ csum_partial: ...@@ -149,6 +149,8 @@ csum_partial:
30: subl $2, %ecx 30: subl $2, %ecx
ja 20b ja 20b
je 32f je 32f
addl $2, %ecx
jz 80f
movzbl (%esi),%ebx # csumming 1 byte, 2-aligned movzbl (%esi),%ebx # csumming 1 byte, 2-aligned
addl %ebx, %eax addl %ebx, %eax
adcl $0, %eax adcl $0, %eax
......
...@@ -3337,8 +3337,10 @@ static int tg3_reset_hw(struct tg3 *tp) ...@@ -3337,8 +3337,10 @@ static int tg3_reset_hw(struct tg3 *tp)
/* Clear statistics/status block in chip, and status block in ram. */ /* Clear statistics/status block in chip, and status block in ram. */
for (i = NIC_SRAM_STATS_BLK; for (i = NIC_SRAM_STATS_BLK;
i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE; i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
i += sizeof(u32)) i += sizeof(u32)) {
tg3_write_mem(tp, i, 0); tg3_write_mem(tp, i, 0);
udelay(40);
}
memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
/* This value is determined during the probe time DMA /* This value is determined during the probe time DMA
......
...@@ -43,12 +43,57 @@ enum ip_conntrack_status { ...@@ -43,12 +43,57 @@ enum ip_conntrack_status {
IPS_ASSURED = (1 << IPS_ASSURED_BIT), 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__ #ifdef __KERNEL__
#include <linux/types.h> #include <linux/types.h>
#include <linux/skbuff.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 #ifdef CONFIG_NF_DEBUG
#define IP_NF_ASSERT(x) \ #define IP_NF_ASSERT(x) \
...@@ -63,19 +108,14 @@ do { \ ...@@ -63,19 +108,14 @@ do { \
#define IP_NF_ASSERT(x) #define IP_NF_ASSERT(x)
#endif #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 struct ip_conntrack_expect
{ {
/* Internal linked list (global expectation list) */ /* Internal linked list (global expectation list) */
struct list_head list; struct list_head list;
/* reference count */
atomic_t use;
/* expectation list for this master */ /* expectation list for this master */
struct list_head expected_list; struct list_head expected_list;
...@@ -103,19 +143,12 @@ struct ip_conntrack_expect ...@@ -103,19 +143,12 @@ struct ip_conntrack_expect
/* At which sequence number did this expectation occur */ /* At which sequence number did this expectation occur */
u_int32_t seq; u_int32_t seq;
union { union ip_conntrack_expect_proto proto;
/* insert conntrack helper private data (expect) here */
struct ip_ct_ftp_expect exp_ftp_info; union ip_conntrack_expect_help help;
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;
}; };
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
struct ip_conntrack struct ip_conntrack
{ {
/* Usage count in here is 1 for hash table/destruct timer, 1 per skb, /* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
...@@ -150,23 +183,14 @@ struct ip_conntrack ...@@ -150,23 +183,14 @@ struct ip_conntrack
/* Storage reserved for other modules: */ /* Storage reserved for other modules: */
union { union ip_conntrack_proto proto;
struct ip_ct_tcp tcp;
struct ip_ct_icmp icmp;
} proto;
union { union ip_conntrack_help help;
/* insert conntrack helper private data (master) here */
struct ip_ct_ftp_master ct_ftp_info;
struct ip_ct_irc_master ct_irc_info;
} help;
#ifdef CONFIG_IP_NF_NAT_NEEDED #ifdef CONFIG_IP_NF_NAT_NEEDED
struct { struct {
struct ip_nat_info info; struct ip_nat_info info;
union { union ip_conntrack_nat_help help;
/* insert nat helper private data here */
} help;
#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \ #if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE) defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
int masq_index; int masq_index;
...@@ -195,6 +219,16 @@ ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple, ...@@ -195,6 +219,16 @@ ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple,
extern struct ip_conntrack * extern struct ip_conntrack *
ip_conntrack_get(struct sk_buff *skb, enum ip_conntrack_info *ctinfo); 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 struct module *ip_conntrack_module;
extern int invert_tuplepr(struct ip_conntrack_tuple *inverse, extern int invert_tuplepr(struct ip_conntrack_tuple *inverse,
......
...@@ -45,7 +45,7 @@ static inline int ip_conntrack_confirm(struct sk_buff *skb) ...@@ -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 *ip_conntrack_hash;
extern struct list_head expect_list; extern struct list_head ip_conntrack_expect_list;
DECLARE_RWLOCK_EXTERN(ip_conntrack_lock); DECLARE_RWLOCK_EXTERN(ip_conntrack_lock);
#endif /* _IP_CONNTRACK_CORE_H */ #endif /* _IP_CONNTRACK_CORE_H */
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
#define _IP_CONNTRACK_FTP_H #define _IP_CONNTRACK_FTP_H
/* FTP tracking. */ /* FTP tracking. */
#ifndef __KERNEL__ #ifdef __KERNEL__
#error Only in kernel.
#endif
#include <linux/netfilter_ipv4/lockhelp.h> #include <linux/netfilter_ipv4/lockhelp.h>
...@@ -13,6 +11,8 @@ DECLARE_LOCK_EXTERN(ip_ftp_lock); ...@@ -13,6 +11,8 @@ DECLARE_LOCK_EXTERN(ip_ftp_lock);
#define FTP_PORT 21 #define FTP_PORT 21
#endif /* __KERNEL__ */
enum ip_ct_ftp_type enum ip_ct_ftp_type
{ {
/* PORT command from client */ /* PORT command from client */
......
...@@ -14,22 +14,6 @@ ...@@ -14,22 +14,6 @@
#ifndef _IP_CONNTRACK_IRC_H #ifndef _IP_CONNTRACK_IRC_H
#define _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 /* We record seq number and length of irc ip/port text here: all in
host order. */ host order. */
...@@ -46,4 +30,21 @@ struct ip_ct_irc_expect ...@@ -46,4 +30,21 @@ struct ip_ct_irc_expect
struct ip_ct_irc_master { 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 */ #endif /* _IP_CONNTRACK_IRC_H */
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
#define _IP_CONNTRACK_TCP_H #define _IP_CONNTRACK_TCP_H
/* TCP tracking. */ /* TCP tracking. */
#ifndef __KERNEL__
#error Only in kernel.
#endif
enum tcp_conntrack { enum tcp_conntrack {
TCP_CONNTRACK_NONE, TCP_CONNTRACK_NONE,
TCP_CONNTRACK_ESTABLISHED, TCP_CONNTRACK_ESTABLISHED,
......
...@@ -60,22 +60,6 @@ struct ip_nat_multi_range ...@@ -60,22 +60,6 @@ struct ip_nat_multi_range
struct ip_nat_range range[1]; 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. */ /* Worst case: local-out manip + 1 post-routing, and reverse dirn. */
#define IP_NAT_MAX_MANIPS (2*3) #define IP_NAT_MAX_MANIPS (2*3)
...@@ -93,7 +77,23 @@ struct ip_nat_info_manip ...@@ -93,7 +77,23 @@ struct ip_nat_info_manip
/* Manipulations to occur at each conntrack in this dirn. */ /* Manipulations to occur at each conntrack in this dirn. */
struct ip_conntrack_manip manip; 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. */ /* The structure embedded in the conntrack structure. */
struct ip_nat_info 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 @@ ...@@ -6,12 +6,14 @@
#define IPT_OWNER_GID 0x02 #define IPT_OWNER_GID 0x02
#define IPT_OWNER_PID 0x04 #define IPT_OWNER_PID 0x04
#define IPT_OWNER_SID 0x08 #define IPT_OWNER_SID 0x08
#define IPT_OWNER_COMM 0x10
struct ipt_owner_info { struct ipt_owner_info {
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
pid_t pid; pid_t pid;
pid_t sid; pid_t sid;
char comm[16];
u_int8_t match, invert; /* flags */ 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 @@ ...@@ -24,25 +24,25 @@
/* All station state event action functions look like this */ /* All station state event action functions look like this */
typedef int (*llc_station_action_t)(struct llc_station *station, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 */ #endif /* LLC_ACTN_H */
This diff is collapsed.
This diff is collapsed.
...@@ -136,12 +136,10 @@ extern void llc_sock_reset(struct sock *sk); ...@@ -136,12 +136,10 @@ extern void llc_sock_reset(struct sock *sk);
extern int llc_sock_init(struct sock *sk); extern int llc_sock_init(struct sock *sk);
/* Access to a connection */ /* 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 sk_buff *skb);
extern int llc_conn_send_ev(struct sock *sk, struct llc_conn_state_ev *ev);
extern void llc_conn_send_pdu(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, 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 sk_buff *skb);
extern void llc_conn_free_ev(struct llc_conn_state_ev *ev);
extern void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, extern void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr,
u8 first_p_bit); u8 first_p_bit);
extern void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, extern void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr,
......
...@@ -58,7 +58,7 @@ union llc_stat_ev_if { ...@@ -58,7 +58,7 @@ union llc_stat_ev_if {
struct llc_stat_ev_simple_if a; /* 'a' for simple, easy ... */ struct llc_stat_ev_simple_if a; /* 'a' for simple, easy ... */
struct llc_stat_ev_prim_if prim; struct llc_stat_ev_prim_if prim;
struct llc_stat_ev_pdu_if pdu; 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 */ struct llc_stat_ev_rpt_sts_if rsts; /* report status */
}; };
...@@ -68,26 +68,32 @@ struct llc_station_state_ev { ...@@ -68,26 +68,32 @@ struct llc_station_state_ev {
struct list_head node; /* node in station->ev_q.list */ 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, 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, 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, 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 * extern int llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry(struct llc_station *
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, 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, 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, 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, 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, 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, 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 */ #endif /* LLC_EVNT_H */
...@@ -20,4 +20,15 @@ extern struct net_device *mac_dev_peer(struct net_device *current_dev, ...@@ -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, extern int llc_pdu_router(struct llc_sap *sap, struct sock *sk,
struct sk_buff *skb, u8 type); struct sk_buff *skb, u8 type);
extern u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da); 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 */ #endif /* LLC_MAC_H */
...@@ -19,35 +19,40 @@ ...@@ -19,35 +19,40 @@
#define LLC_ACK_TIME 3 #define LLC_ACK_TIME 3
#define LLC_REJ_TIME 3 #define LLC_REJ_TIME 3
#define LLC_BUSY_TIME 3 #define LLC_BUSY_TIME 3
#define LLC_SENDACK_TIME 50
#define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */ #define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */
#define LLC_DEST_SAP 1 /* Type 1 goes here */ #define LLC_DEST_SAP 1 /* Type 1 goes here */
#define LLC_DEST_CONN 2 /* Type 2 goes here */ #define LLC_DEST_CONN 2 /* Type 2 goes here */
/* LLC Layer global default parameters */ /**
* struct llc_station - LLC station component
#define LLC_GLOBAL_DEFAULT_MAX_NBR_SAPS 4 *
#define LLC_GLOBAL_DEFAULT_MAX_NBR_CONNS 64 * SAP and connection resource manager, one per adapter.
*
/* LLC station component (SAP and connection resource manager) */ * @state - state of station
/* Station component; one per adapter */ * @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 { struct llc_station {
u8 state; /* state of station */ u8 state;
u8 xid_r_count; /* XID response PDU counter */ u8 xid_r_count;
struct timer_list ack_timer; struct timer_list ack_timer;
u8 ack_tmr_running; /* 1 or 0 */ u8 ack_tmr_running;
u8 retry_count; u8 retry_count;
u8 maximum_retry; u8 maximum_retry;
u8 mac_sa[6]; /* MAC source address */ u8 mac_sa[6];
struct { struct {
spinlock_t lock; spinlock_t lock;
struct list_head list; struct list_head list;
} sap_list; /* list of related SAPs */ } sap_list;
struct { struct {
spinlock_t lock; struct sk_buff_head list;
struct list_head list; spinlock_t lock;
} ev_q; /* events entering state mach. */ } ev_q;
struct sk_buff_head mac_pdu_q; /* PDUs ready to send to MAC */ struct sk_buff_head mac_pdu_q;
}; };
struct llc_station_state_ev; struct llc_station_state_ev;
...@@ -56,10 +61,8 @@ extern void llc_sap_save(struct llc_sap *sap); ...@@ -56,10 +61,8 @@ extern void llc_sap_save(struct llc_sap *sap);
extern void llc_free_sap(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_sap *llc_sap_find(u8 lsap);
extern struct llc_station *llc_station_get(void); 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, 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, extern void llc_station_send_pdu(struct llc_station *station,
struct sk_buff *skb); struct sk_buff *skb);
extern struct sk_buff *llc_alloc_frame(void); extern struct sk_buff *llc_alloc_frame(void);
......
...@@ -23,25 +23,17 @@ ...@@ -23,25 +23,17 @@
#define SAP_ACT_TEST_IND 9 #define SAP_ACT_TEST_IND 9
/* All action functions must look like this */ /* All action functions must look like this */
typedef int (*llc_sap_action_t)(struct llc_sap *sap, typedef int (*llc_sap_action_t)(struct llc_sap *sap, struct sk_buff *skb);
struct llc_sap_state_ev *ev);
extern int llc_sap_action_unitdata_ind(struct llc_sap *sap, extern int llc_sap_action_unitdata_ind(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, extern int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb);
struct llc_sap_state_ev *ev); extern int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_send_xid_c(struct llc_sap *sap, extern int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb);
struct llc_sap_state_ev *ev); extern int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_send_xid_r(struct llc_sap *sap, extern int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb);
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);
extern int llc_sap_action_report_status(struct llc_sap *sap, extern int llc_sap_action_report_status(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, extern int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb);
struct llc_sap_state_ev *ev); extern int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_action_test_ind(struct llc_sap *sap,
struct llc_sap_state_ev *ev);
#endif /* LLC_S_AC_H */ #endif /* LLC_S_AC_H */
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
* *
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
*/ */
#include <linux/skbuff.h>
/* Defines SAP component events */ /* Defines SAP component events */
/* Types of events (possible values in 'ev->type') */ /* Types of events (possible values in 'ev->type') */
#define LLC_SAP_EV_TYPE_SIMPLE 1 #define LLC_SAP_EV_TYPE_SIMPLE 1
...@@ -45,9 +48,8 @@ struct llc_sap_ev_prim_if { ...@@ -45,9 +48,8 @@ struct llc_sap_ev_prim_if {
}; };
struct llc_sap_ev_pdu_if { struct llc_sap_ev_pdu_if {
u8 ev; u8 ev;
u8 reason; u8 reason;
struct sk_buff *skb;
}; };
struct llc_sap_ev_tmr_if { struct llc_sap_ev_tmr_if {
...@@ -75,27 +77,24 @@ struct llc_sap_state_ev { ...@@ -75,27 +77,24 @@ struct llc_sap_state_ev {
union llc_sap_ev_if data; 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; struct llc_sap;
typedef int (*llc_sap_ev_t)(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, extern int llc_sap_ev_activation_req(struct llc_sap *sap, struct sk_buff *skb);
struct llc_sap_state_ev *ev); extern int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb);
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 sk_buff *skb);
extern int llc_sap_ev_unitdata_req(struct llc_sap *sap, extern int llc_sap_ev_xid_req(struct llc_sap *sap, struct sk_buff *skb);
struct llc_sap_state_ev *ev); extern int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_xid_req(struct llc_sap *sap, extern int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct sk_buff *skb);
struct llc_sap_state_ev *ev); extern int llc_sap_ev_test_req(struct llc_sap *sap, struct sk_buff *skb);
extern int llc_sap_ev_rx_xid_c(struct llc_sap *sap, extern int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb);
struct llc_sap_state_ev *ev); extern int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct sk_buff *skb);
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);
extern int llc_sap_ev_deactivation_req(struct llc_sap *sap, 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 */ #endif /* LLC_S_EV_H */
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
#define LLC_SAP_STATE_INACTIVE 1 #define LLC_SAP_STATE_INACTIVE 1
#define LLC_SAP_STATE_ACTIVE 2 #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 */ /* structures and types */
/* SAP state table structure */ /* SAP state table structure */
struct llc_sap_state_trans { struct llc_sap_state_trans {
...@@ -25,10 +26,10 @@ struct llc_sap_state_trans { ...@@ -25,10 +26,10 @@ struct llc_sap_state_trans {
}; };
struct llc_sap_state { struct llc_sap_state {
u8 curr_state; u8 curr_state;
struct llc_sap_state_trans **transitions; struct llc_sap_state_trans **transitions;
}; };
/* only access to SAP state table */ /* 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 */ #endif /* LLC_S_ST_H */
...@@ -49,9 +49,7 @@ struct llc_sap_state_ev; ...@@ -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_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_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_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_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
struct llc_sap_state_ev *ev);
extern void llc_sap_send_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 */ #endif /* LLC_SAP_H */
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
* *
* Merged changes from 2.2.19 into 2.4.3 * Merged changes from 2.2.19 into 2.4.3
* -- Eric Biederman <ebiederman@lnxi.com>, 22 April Aug 2001 * -- 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> #include <linux/config.h>
...@@ -91,6 +94,8 @@ ...@@ -91,6 +94,8 @@
#define CONF_TIMEOUT_RANDOM (HZ) /* Maximum amount of randomization */ #define CONF_TIMEOUT_RANDOM (HZ) /* Maximum amount of randomization */
#define CONF_TIMEOUT_MULT *7/4 /* Rate of timeout growth */ #define CONF_TIMEOUT_MULT *7/4 /* Rate of timeout growth */
#define CONF_TIMEOUT_MAX (HZ*30) /* Maximum allowed timeout */ #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 */ ...@@ -132,7 +137,7 @@ u8 root_server_path[256] __initdata = { 0, }; /* Path to mount as root */
/* Persistent data: */ /* Persistent data: */
int ic_proto_used; /* Protocol used, if any */ 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 */ u8 ic_domain[64]; /* DNS (not NIS) domain name */
/* /*
...@@ -625,6 +630,11 @@ static void __init ic_bootp_init_ext(u8 *e) ...@@ -625,6 +630,11 @@ static void __init ic_bootp_init_ext(u8 *e)
*/ */
static inline void ic_bootp_init(void) 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); dev_add_pack(&bootp_packet_type);
} }
...@@ -729,6 +739,9 @@ static int __init ic_bootp_string(char *dest, char *src, int len, int max) ...@@ -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) static void __init ic_do_bootp_ext(u8 *ext)
{ {
u8 servers;
int i;
#ifdef IPCONFIG_DEBUG #ifdef IPCONFIG_DEBUG
u8 *c; u8 *c;
...@@ -748,8 +761,13 @@ static void __init ic_do_bootp_ext(u8 *ext) ...@@ -748,8 +761,13 @@ static void __init ic_do_bootp_ext(u8 *ext)
memcpy(&ic_gateway, ext+1, 4); memcpy(&ic_gateway, ext+1, 4);
break; break;
case 6: /* DNS server */ case 6: /* DNS server */
if (ic_nameserver == INADDR_NONE) servers= *ext/4;
memcpy(&ic_nameserver, ext+1, 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; break;
case 12: /* Host name */ case 12: /* Host name */
ic_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN); 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 ...@@ -914,8 +932,8 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
ic_servaddr = b->server_ip; ic_servaddr = b->server_ip;
if (ic_gateway == INADDR_NONE && b->relay_ip) if (ic_gateway == INADDR_NONE && b->relay_ip)
ic_gateway = b->relay_ip; ic_gateway = b->relay_ip;
if (ic_nameserver == INADDR_NONE) if (ic_nameservers[0] == INADDR_NONE)
ic_nameserver = ic_servaddr; ic_nameservers[0] = ic_servaddr;
ic_got_reply = IC_BOOTP; ic_got_reply = IC_BOOTP;
drop: drop:
...@@ -1078,6 +1096,7 @@ static int pnp_get_info(char *buffer, char **start, ...@@ -1078,6 +1096,7 @@ static int pnp_get_info(char *buffer, char **start,
off_t offset, int length) off_t offset, int length)
{ {
int len; int len;
int i;
if (ic_proto_used & IC_PROTO) if (ic_proto_used & IC_PROTO)
sprintf(buffer, "#PROTO: %s\n", sprintf(buffer, "#PROTO: %s\n",
...@@ -1090,9 +1109,12 @@ static int pnp_get_info(char *buffer, char **start, ...@@ -1090,9 +1109,12 @@ static int pnp_get_info(char *buffer, char **start,
if (ic_domain[0]) if (ic_domain[0])
len += sprintf(buffer + len, len += sprintf(buffer + len,
"domain %s\n", ic_domain); "domain %s\n", ic_domain);
if (ic_nameserver != INADDR_NONE) for (i = 0; i < CONF_NAMESERVERS_MAX; i++) {
len += sprintf(buffer + len, if (ic_nameservers[i] != INADDR_NONE)
"nameserver %u.%u.%u.%u\n", NIPQUAD(ic_nameserver)); len += sprintf(buffer + len,
"nameserver %u.%u.%u.%u\n",
NIPQUAD(ic_nameservers[i]));
}
if (offset > len) if (offset > len)
offset = len; offset = len;
......
...@@ -56,6 +56,16 @@ CONFIG_IP_NF_MATCH_LIMIT ...@@ -56,6 +56,16 @@ CONFIG_IP_NF_MATCH_LIMIT
If you want to compile it as a module, say M here and read If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'. <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 CONFIG_IP_NF_MATCH_MAC
MAC matching allows you to match packets based on the source MAC matching allows you to match packets based on the source
Ethernet address of the packet. Ethernet address of the packet.
...@@ -100,6 +110,22 @@ CONFIG_IP_NF_MATCH_AH_ESP ...@@ -100,6 +110,22 @@ CONFIG_IP_NF_MATCH_AH_ESP
If you want to compile it as a module, say M here and read If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'. 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 CONFIG_IP_NF_MATCH_TOS
TOS matching allows you to match packets based on the Type Of TOS matching allows you to match packets based on the Type Of
Service fields of the IP packet. Service fields of the IP packet.
...@@ -107,6 +133,16 @@ CONFIG_IP_NF_MATCH_TOS ...@@ -107,6 +133,16 @@ CONFIG_IP_NF_MATCH_TOS
If you want to compile it as a module, say M here and read If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'. <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 CONFIG_IP_NF_MATCH_STATE
Connection state matching allows you to match packets based on their Connection state matching allows you to match packets based on their
relationship to a tracked connection (ie. previous packets). This relationship to a tracked connection (ie. previous packets). This
...@@ -211,6 +247,30 @@ CONFIG_IP_NF_MANGLE ...@@ -211,6 +247,30 @@ CONFIG_IP_NF_MANGLE
If you want to compile it as a module, say M here and read If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'. <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 CONFIG_IP_NF_TARGET_TOS
This option adds a `TOS' target, which allows you to create rules in 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 the `mangle' table which alter the Type Of Service field of an IP
...@@ -230,6 +290,13 @@ CONFIG_IP_NF_TARGET_MARK ...@@ -230,6 +290,13 @@ CONFIG_IP_NF_TARGET_MARK
If you want to compile it as a module, say M here and read If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'. <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 CONFIG_IP_NF_TARGET_TCPMSS
This option adds a `TCPMSS' target, which allows you to alter the 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 MSS value of TCP SYN packets, to control the maximum size for that
......
...@@ -18,15 +18,24 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then ...@@ -18,15 +18,24 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then
# The simple matches. # The simple matches.
dep_tristate ' limit match support' CONFIG_IP_NF_MATCH_LIMIT $CONFIG_IP_NF_IPTABLES 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 ' 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 ' 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 ' 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 ' 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 ' 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 ' 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 ' 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 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 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 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 fi
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_tristate ' Unclean match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_UNCLEAN $CONFIG_IP_NF_IPTABLES 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 ...@@ -73,6 +82,10 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then
dep_tristate ' Packet mangling' CONFIG_IP_NF_MANGLE $CONFIG_IP_NF_IPTABLES dep_tristate ' Packet mangling' CONFIG_IP_NF_MANGLE $CONFIG_IP_NF_IPTABLES
if [ "$CONFIG_IP_NF_MANGLE" != "n" ]; then if [ "$CONFIG_IP_NF_MANGLE" != "n" ]; then
dep_tristate ' TOS target support' CONFIG_IP_NF_TARGET_TOS $CONFIG_IP_NF_MANGLE 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 dep_tristate ' MARK target support' CONFIG_IP_NF_TARGET_MARK $CONFIG_IP_NF_MANGLE
fi fi
dep_tristate ' LOG target support' CONFIG_IP_NF_TARGET_LOG $CONFIG_IP_NF_IPTABLES dep_tristate ' LOG target support' CONFIG_IP_NF_TARGET_LOG $CONFIG_IP_NF_IPTABLES
......
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
# #
export-objs := ip_conntrack_standalone.o ip_fw_compat.o ip_nat_standalone.o \ 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_tables.o arp_tables.o
ip_conntrack_irc.o
# objects for the conntrack and NAT core (used by standalone and backw. compat) # 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 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 ...@@ -25,7 +24,13 @@ obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
# connection tracking helpers # connection tracking helpers
obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o 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 obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
ifdef CONFIG_IP_NF_NAT_IRC
export-objs += ip_conntrack_irc.o
endif
# NAT helpers # NAT helpers
obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
...@@ -40,18 +45,24 @@ obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o ...@@ -40,18 +45,24 @@ obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
# matches # matches
obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.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_MULTIPORT) += ipt_multiport.o
obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.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_AH_ESP) += ipt_ah.o ipt_esp.o
obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o
obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.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_UNCLEAN) += ipt_unclean.o
obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
...@@ -59,6 +70,8 @@ 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_REJECT) += ipt_REJECT.o
obj-$(CONFIG_IP_NF_TARGET_MIRROR) += ipt_MIRROR.o obj-$(CONFIG_IP_NF_TARGET_MIRROR) += ipt_MIRROR.o
obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.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_MARK) += ipt_MARK.o
obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
......
This diff is collapsed.
...@@ -16,7 +16,7 @@ struct module *ip_conntrack_ftp = THIS_MODULE; ...@@ -16,7 +16,7 @@ struct module *ip_conntrack_ftp = THIS_MODULE;
#define MAX_PORTS 8 #define MAX_PORTS 8
static int ports[MAX_PORTS]; static int ports[MAX_PORTS];
static int ports_c; static int ports_c = 0;
#ifdef MODULE_PARM #ifdef MODULE_PARM
MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i");
#endif #endif
...@@ -389,7 +389,7 @@ static char ftp_names[MAX_PORTS][10]; ...@@ -389,7 +389,7 @@ static char ftp_names[MAX_PORTS][10];
static void fini(void) static void fini(void)
{ {
int i; 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", DEBUGP("ip_ct_ftp: unregistering helper for port %d\n",
ports[i]); ports[i]);
ip_conntrack_helper_unregister(&ftp[i]); ip_conntrack_helper_unregister(&ftp[i]);
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#define MAX_PORTS 8 #define MAX_PORTS 8
static int ports[MAX_PORTS]; static int ports[MAX_PORTS];
static int ports_n_c = 0; static int ports_c = 0;
static int max_dcc_channels = 8; static int max_dcc_channels = 8;
static unsigned int dcc_timeout = 300; static unsigned int dcc_timeout = 300;
...@@ -288,7 +288,7 @@ static int __init init(void) ...@@ -288,7 +288,7 @@ static int __init init(void)
fini(); fini();
return -EBUSY; return -EBUSY;
} }
ports_n_c++; ports_c++;
} }
return 0; return 0;
} }
...@@ -298,7 +298,7 @@ static int __init init(void) ...@@ -298,7 +298,7 @@ static int __init init(void)
static void fini(void) static void fini(void)
{ {
int i; int i;
for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { for (i = 0; i < ports_c; i++) {
DEBUGP("unregistering port %d\n", DEBUGP("unregistering port %d\n",
ports[i]); ports[i]);
ip_conntrack_helper_unregister(&irc_helpers[i]); ip_conntrack_helper_unregister(&irc_helpers[i]);
......
...@@ -68,8 +68,8 @@ print_expect(char *buffer, const struct ip_conntrack_expect *expect) ...@@ -68,8 +68,8 @@ print_expect(char *buffer, const struct ip_conntrack_expect *expect)
? (expect->timeout.expires - jiffies)/HZ : 0); ? (expect->timeout.expires - jiffies)/HZ : 0);
else else
len = sprintf(buffer, "EXPECTING: - "); len = sprintf(buffer, "EXPECTING: - ");
len += sprintf(buffer + len, "proto=%u ", len += sprintf(buffer + len, "use=%u proto=%u ",
expect->tuple.dst.protonum); atomic_read(&expect->use), expect->tuple.dst.protonum);
len += print_tuple(buffer + len, &expect->tuple, len += print_tuple(buffer + len, &expect->tuple,
__find_proto(expect->tuple.dst.protonum)); __find_proto(expect->tuple.dst.protonum));
len += sprintf(buffer + len, "\n"); len += sprintf(buffer + len, "\n");
...@@ -153,7 +153,8 @@ list_conntracks(char *buffer, char **start, off_t offset, int length) ...@@ -153,7 +153,8 @@ list_conntracks(char *buffer, char **start, off_t offset, int length)
} }
/* Now iterate through expecteds. */ /* 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; unsigned int last_len;
struct ip_conntrack_expect *expect struct ip_conntrack_expect *expect
= (struct ip_conntrack_expect *)e; = (struct ip_conntrack_expect *)e;
...@@ -364,7 +365,13 @@ EXPORT_SYMBOL(ip_ct_find_helper); ...@@ -364,7 +365,13 @@ EXPORT_SYMBOL(ip_ct_find_helper);
EXPORT_SYMBOL(ip_conntrack_expect_related); EXPORT_SYMBOL(ip_conntrack_expect_related);
EXPORT_SYMBOL(ip_conntrack_change_expect); EXPORT_SYMBOL(ip_conntrack_change_expect);
EXPORT_SYMBOL(ip_conntrack_unexpect_related); 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_conntrack_tuple_taken);
EXPORT_SYMBOL(ip_ct_gather_frags); EXPORT_SYMBOL(ip_ct_gather_frags);
EXPORT_SYMBOL(ip_conntrack_htable_size); EXPORT_SYMBOL(ip_conntrack_htable_size);
EXPORT_SYMBOL(ip_conntrack_expect_list);
EXPORT_SYMBOL(ip_conntrack_lock); 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; ...@@ -18,6 +18,7 @@ struct notifier_block;
/* Theoretically, we could one day use 2.4 helpers, but for now it /* Theoretically, we could one day use 2.4 helpers, but for now it
just confuses depmod --RR */ just confuses depmod --RR */
EXPORT_NO_SYMBOLS;
static struct firewall_ops *fwops; static struct firewall_ops *fwops;
......
...@@ -738,11 +738,10 @@ static inline int exp_for_packet(struct ip_conntrack_expect *exp, ...@@ -738,11 +738,10 @@ static inline int exp_for_packet(struct ip_conntrack_expect *exp,
struct ip_conntrack_protocol *proto; struct ip_conntrack_protocol *proto;
int ret = 1; int ret = 1;
READ_LOCK(&ip_conntrack_lock); MUST_BE_READ_LOCKED(&ip_conntrack_lock);
proto = ip_ct_find_proto((*pskb)->nh.iph->protocol); proto = ip_ct_find_proto((*pskb)->nh.iph->protocol);
if (proto->exp_matches_pkt) if (proto->exp_matches_pkt)
ret = proto->exp_matches_pkt(exp, pskb); ret = proto->exp_matches_pkt(exp, pskb);
READ_UNLOCK(&ip_conntrack_lock);
return ret; return ret;
} }
...@@ -999,4 +998,5 @@ void ip_nat_cleanup(void) ...@@ -999,4 +998,5 @@ void ip_nat_cleanup(void)
{ {
ip_ct_selective_cleanup(&clean_nat, NULL); ip_ct_selective_cleanup(&clean_nat, NULL);
ip_conntrack_destroyed = NULL; ip_conntrack_destroyed = NULL;
vfree(bysource);
} }
...@@ -291,7 +291,7 @@ static void fini(void) ...@@ -291,7 +291,7 @@ static void fini(void)
{ {
int i; 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]); DEBUGP("ip_nat_ftp: unregistering port %d\n", ports[i]);
ip_nat_helper_unregister(&ftp[i]); ip_nat_helper_unregister(&ftp[i]);
} }
......
...@@ -52,11 +52,10 @@ ...@@ -52,11 +52,10 @@
#include <linux/netfilter_ipv4/ip_nat_helper.h> #include <linux/netfilter_ipv4/ip_nat_helper.h>
#include <linux/brlock.h> #include <linux/brlock.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/in.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <net/udp.h> #include <net/udp.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <net/checksum.h> #include <asm/checksum.h>
......
...@@ -122,8 +122,10 @@ ...@@ -122,8 +122,10 @@
#include <net/icmp.h> #include <net/icmp.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/netfilter_ipv4/ipfwadm_core.h> #include <linux/netfilter_ipv4/ipfwadm_core.h>
#include <linux/netfilter_ipv4/compat_firewall.h> #include <linux/netfilter_ipv4/compat_firewall.h>
#include <linux/netfilter_ipv4/lockhelp.h>
#include <net/checksum.h> #include <net/checksum.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
...@@ -154,6 +156,8 @@ ...@@ -154,6 +156,8 @@
#define dprint_ip(a) #define dprint_ip(a)
#endif #endif
static rwlock_t ip_fw_lock = RW_LOCK_UNLOCKED;
#if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL) #if defined(CONFIG_IP_ACCT) || defined(CONFIG_IP_FIREWALL)
struct ip_fw *ip_fw_fwd_chain; struct ip_fw *ip_fw_fwd_chain;
...@@ -442,6 +446,11 @@ int ip_fw_chk(struct iphdr *ip, struct net_device *rif, __u16 *redirport, ...@@ -442,6 +446,11 @@ int ip_fw_chk(struct iphdr *ip, struct net_device *rif, __u16 *redirport,
dprintf1("\n"); dprintf1("\n");
#endif #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) 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, ...@@ -646,7 +655,8 @@ int ip_fw_chk(struct iphdr *ip, struct net_device *rif, __u16 *redirport,
#ifdef CONFIG_IP_FIREWALL_NETLINK #ifdef CONFIG_IP_FIREWALL_NETLINK
if((policy&IP_FW_F_PRN) && (answer == FW_REJECT || answer == FW_BLOCK)) 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) if(skb)
{ {
int len = min_t(unsigned int, int len = min_t(unsigned int,
...@@ -659,29 +669,36 @@ int ip_fw_chk(struct iphdr *ip, struct net_device *rif, __u16 *redirport, ...@@ -659,29 +669,36 @@ int ip_fw_chk(struct iphdr *ip, struct net_device *rif, __u16 *redirport,
} }
} }
#endif #endif
return answer;
} else } else
/* we're doing accounting, always ok */ /* 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) static void zero_fw_chain(struct ip_fw *chainptr)
{ {
struct ip_fw *ctmp=chainptr; struct ip_fw *ctmp=chainptr;
WRITE_LOCK(&ip_fw_lock);
while(ctmp) while(ctmp)
{ {
ctmp->fw_pcnt=0L; ctmp->fw_pcnt=0L;
ctmp->fw_bcnt=0L; ctmp->fw_bcnt=0L;
ctmp=ctmp->fw_next; ctmp=ctmp->fw_next;
} }
WRITE_UNLOCK(&ip_fw_lock);
} }
static void free_fw_chain(struct ip_fw *volatile* chainptr) static void free_fw_chain(struct ip_fw *volatile* chainptr)
{ {
unsigned long flags; WRITE_LOCK(&ip_fw_lock);
save_flags(flags);
cli();
while ( *chainptr != NULL ) while ( *chainptr != NULL )
{ {
struct ip_fw *ftmp; struct ip_fw *ftmp;
...@@ -690,7 +707,7 @@ static void free_fw_chain(struct ip_fw *volatile* chainptr) ...@@ -690,7 +707,7 @@ static void free_fw_chain(struct ip_fw *volatile* chainptr)
kfree(ftmp); kfree(ftmp);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
restore_flags(flags); WRITE_UNLOCK(&ip_fw_lock);
} }
/* Volatiles to keep some of the compiler versions amused */ /* Volatiles to keep some of the compiler versions amused */
...@@ -698,11 +715,8 @@ static void free_fw_chain(struct ip_fw *volatile* chainptr) ...@@ -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) static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,int len)
{ {
struct ip_fw *ftmp; 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 ) if ( ftmp == NULL )
{ {
#ifdef DEBUG_IP_FIREWALL #ifdef DEBUG_IP_FIREWALL
...@@ -721,7 +735,7 @@ static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl, ...@@ -721,7 +735,7 @@ static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
ftmp->fw_pcnt=0L; ftmp->fw_pcnt=0L;
ftmp->fw_bcnt=0L; ftmp->fw_bcnt=0L;
cli(); WRITE_LOCK(&ip_fw_lock);
if ((ftmp->fw_vianame)[0]) { if ((ftmp->fw_vianame)[0]) {
if (!(ftmp->fw_viadev = dev_get_by_name(ftmp->fw_vianame))) 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, ...@@ -731,7 +745,7 @@ static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
ftmp->fw_next = *chainptr; ftmp->fw_next = *chainptr;
*chainptr=ftmp; *chainptr=ftmp;
restore_flags(flags); WRITE_UNLOCK(&ip_fw_lock);
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
return(0); return(0);
} }
...@@ -741,11 +755,8 @@ static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl, ...@@ -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 *ftmp;
struct ip_fw *chtmp=NULL; struct ip_fw *chtmp=NULL;
struct ip_fw *volatile chtmp_prev=NULL; struct ip_fw *volatile chtmp_prev=NULL;
unsigned long flags;
save_flags(flags); ftmp = kmalloc( sizeof(struct ip_fw), GFP_KERNEL );
ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
if ( ftmp == NULL ) if ( ftmp == NULL )
{ {
#ifdef DEBUG_IP_FIREWALL #ifdef DEBUG_IP_FIREWALL
...@@ -766,7 +777,7 @@ static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl, ...@@ -766,7 +777,7 @@ static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
ftmp->fw_next = NULL; ftmp->fw_next = NULL;
cli(); WRITE_LOCK(&ip_fw_lock);
if ((ftmp->fw_vianame)[0]) { if ((ftmp->fw_vianame)[0]) {
if (!(ftmp->fw_viadev = dev_get_by_name(ftmp->fw_vianame))) 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, ...@@ -782,7 +793,7 @@ static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
chtmp_prev->fw_next=ftmp; chtmp_prev->fw_next=ftmp;
else else
*chainptr=ftmp; *chainptr=ftmp;
restore_flags(flags); WRITE_UNLOCK(&ip_fw_lock);
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
return(0); return(0);
} }
...@@ -792,10 +803,8 @@ static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl) ...@@ -792,10 +803,8 @@ static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
struct ip_fw *ftmp,*ltmp; struct ip_fw *ftmp,*ltmp;
unsigned short tport1,tport2,tmpnum; unsigned short tport1,tport2,tmpnum;
char matches,was_found; char matches,was_found;
unsigned long flags;
save_flags(flags); WRITE_LOCK(&ip_fw_lock);
cli();
ftmp=*chainptr; ftmp=*chainptr;
...@@ -804,7 +813,7 @@ static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl) ...@@ -804,7 +813,7 @@ static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
#ifdef DEBUG_IP_FIREWALL #ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: chain is empty\n"); printk("ip_fw_ctl: chain is empty\n");
#endif #endif
restore_flags(flags); WRITE_UNLOCK(&ip_fw_lock);
return( EINVAL ); return( EINVAL );
} }
...@@ -856,7 +865,7 @@ static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl) ...@@ -856,7 +865,7 @@ static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
ftmp = ftmp->fw_next; ftmp = ftmp->fw_next;
} }
} }
restore_flags(flags); WRITE_UNLOCK(&ip_fw_lock);
if (was_found) { if (was_found) {
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return 0; return 0;
...@@ -1110,7 +1119,6 @@ static int ip_chain_procinfo(int stage, char *buffer, char **start, ...@@ -1110,7 +1119,6 @@ static int ip_chain_procinfo(int stage, char *buffer, char **start,
{ {
off_t pos=0, begin=0; off_t pos=0, begin=0;
struct ip_fw *i; struct ip_fw *i;
unsigned long flags;
int len, p; int len, p;
int last_len = 0; int last_len = 0;
...@@ -1147,8 +1155,7 @@ static int ip_chain_procinfo(int stage, char *buffer, char **start, ...@@ -1147,8 +1155,7 @@ static int ip_chain_procinfo(int stage, char *buffer, char **start,
break; break;
} }
save_flags(flags); READ_LOCK(&ip_fw_lock);
cli();
while(i!=NULL) while(i!=NULL)
{ {
...@@ -1177,16 +1184,19 @@ static int ip_chain_procinfo(int stage, char *buffer, char **start, ...@@ -1177,16 +1184,19 @@ static int ip_chain_procinfo(int stage, char *buffer, char **start,
len = last_len; len = last_len;
break; break;
} }
/* Not possible in 2.3.29+, also allowing read lock instead of write -- JM */
#if 0
else if(reset) else if(reset)
{ {
/* This needs to be done at this specific place! */ /* This needs to be done at this specific place! */
i->fw_pcnt=0L; i->fw_pcnt=0L;
i->fw_bcnt=0L; i->fw_bcnt=0L;
} }
#endif
last_len = len; last_len = len;
i=i->fw_next; i=i->fw_next;
} }
restore_flags(flags); READ_UNLOCK(&ip_fw_lock);
*start=buffer+(offset-begin); *start=buffer+(offset-begin);
len-=(offset-begin); len-=(offset-begin);
if(len>length) if(len>length)
...@@ -1329,12 +1339,10 @@ int ipfw_device_event(struct notifier_block *this, unsigned long event, void *pt ...@@ -1329,12 +1339,10 @@ int ipfw_device_event(struct notifier_block *this, unsigned long event, void *pt
{ {
struct net_device *dev=ptr; struct net_device *dev=ptr;
char *devname = dev->name; char *devname = dev->name;
unsigned long flags;
struct ip_fw *fw; struct ip_fw *fw;
int chn; int chn;
save_flags(flags); WRITE_LOCK(&ip_fw_lock);
cli();
if (event == NETDEV_UP) { if (event == NETDEV_UP) {
for (chn = 0; chn < IP_FW_CHAINS; chn++) 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 ...@@ -1351,7 +1359,7 @@ int ipfw_device_event(struct notifier_block *this, unsigned long event, void *pt
fw->fw_viadev = (struct net_device*)-1; fw->fw_viadev = (struct net_device*)-1;
} }
restore_flags(flags); WRITE_UNLOCK(&ip_fw_lock);
return NOTIFY_DONE; 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) ...@@ -39,7 +39,8 @@ static void send_reset(struct sk_buff *oldskb, int local)
struct tcphdr *otcph, *tcph; struct tcphdr *otcph, *tcph;
struct rtable *rt; struct rtable *rt;
unsigned int otcplen; unsigned int otcplen;
u_int16_t tmp; u_int16_t tmp_port;
u_int32_t tmp_addr;
int needs_ack; int needs_ack;
/* IP header checks: fragment, too short. */ /* IP header checks: fragment, too short. */
...@@ -74,14 +75,17 @@ static void send_reset(struct sk_buff *oldskb, int local) ...@@ -74,14 +75,17 @@ static void send_reset(struct sk_buff *oldskb, int local)
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
nskb->nf_debug = 0; nskb->nf_debug = 0;
#endif #endif
nskb->nfmark = 0;
tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl); tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
/* Swap source and dest */ /* Swap source and dest */
nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr); tmp_addr = nskb->nh.iph->saddr;
tmp = tcph->source; nskb->nh.iph->saddr = nskb->nh.iph->daddr;
nskb->nh.iph->daddr = tmp_addr;
tmp_port = tcph->source;
tcph->source = tcph->dest; tcph->source = tcph->dest;
tcph->dest = tmp; tcph->dest = tmp_port;
/* Truncate to length (no data) */ /* Truncate to length (no data) */
tcph->doff = sizeof(struct tcphdr)/4; tcph->doff = sizeof(struct tcphdr)/4;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/netfilter_ipv4/ipt_ah.h> #include <linux/netfilter_ipv4/ipt_ah.h>
#include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ip_tables.h>
EXPORT_NO_SYMBOLS;
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#ifdef DEBUG_CONNTRACK #ifdef DEBUG_CONNTRACK
...@@ -90,12 +91,12 @@ checkentry(const char *tablename, ...@@ -90,12 +91,12 @@ checkentry(const char *tablename,
static struct ipt_match ah_match static struct ipt_match ah_match
= { { NULL, NULL }, "ah", &match, &checkentry, NULL, THIS_MODULE }; = { { NULL, NULL }, "ah", &match, &checkentry, NULL, THIS_MODULE };
int __init init(void) static int __init init(void)
{ {
return ipt_register_match(&ah_match); return ipt_register_match(&ah_match);
} }
void __exit cleanup(void) static void __exit cleanup(void)
{ {
ipt_unregister_match(&ah_match); 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 @@ ...@@ -5,6 +5,7 @@
#include <linux/netfilter_ipv4/ipt_esp.h> #include <linux/netfilter_ipv4/ipt_esp.h>
#include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ip_tables.h>
EXPORT_NO_SYMBOLS;
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#ifdef DEBUG_CONNTRACK #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 @@ ...@@ -11,6 +11,38 @@
#include <linux/netfilter_ipv4/ipt_owner.h> #include <linux/netfilter_ipv4/ipt_owner.h>
#include <linux/netfilter_ipv4/ip_tables.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 static int
match_pid(const struct sk_buff *skb, pid_t pid) match_pid(const struct sk_buff *skb, pid_t pid)
{ {
...@@ -115,6 +147,12 @@ match(const struct sk_buff *skb, ...@@ -115,6 +147,12 @@ match(const struct sk_buff *skb,
return 0; return 0;
} }
if(info->match & IPT_OWNER_COMM) {
if (!match_comm(skb, info->comm) ^
!!(info->invert & IPT_OWNER_COMM))
return 0;
}
return 1; 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, ...@@ -66,7 +66,8 @@ static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
r->tcpdiag_retrans = 0; r->tcpdiag_retrans = 0;
r->id.tcpdiag_if = sk->bound_dev_if; 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) { if (r->tcpdiag_state == TCP_TIME_WAIT) {
struct tcp_tw_bucket *tw = (struct tcp_tw_bucket*)sk; 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) ...@@ -237,7 +238,8 @@ static int tcpdiag_get_exact(struct sk_buff *in_skb, struct nlmsghdr *nlh)
err = -ESTALE; err = -ESTALE;
if ((req->id.tcpdiag_cookie[0] != TCPDIAG_NOCOOKIE || if ((req->id.tcpdiag_cookie[0] != TCPDIAG_NOCOOKIE ||
req->id.tcpdiag_cookie[1] != 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; goto out;
err = -ENOMEM; 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 CONFIG_IP6_NF_MATCH_MAC
mac matching allows you to match packets based on the source mac matching allows you to match packets based on the source
Ethernet address of the packet. Ethernet address of the packet.
...@@ -5,6 +13,13 @@ CONFIG_IP6_NF_MATCH_MAC ...@@ -5,6 +13,13 @@ CONFIG_IP6_NF_MATCH_MAC
If you want to compile it as a module, say M here and read If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'. <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 CONFIG_IP6_NF_MATCH_MARK
Netfilter mark matching allows you to match packets based on the Netfilter mark matching allows you to match packets based on the
`nfmark' value in the packet. This can be set by the MARK target `nfmark' value in the packet. This can be set by the MARK target
......
...@@ -24,6 +24,10 @@ if [ "$CONFIG_IP6_NF_IPTABLES" != "n" ]; then ...@@ -24,6 +24,10 @@ if [ "$CONFIG_IP6_NF_IPTABLES" != "n" ]; then
fi fi
# dep_tristate ' MAC address match support' CONFIG_IP6_NF_MATCH_MAC $CONFIG_IP6_NF_IPTABLES # 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 ' 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 ' 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 # dep_tristate ' TOS match support' CONFIG_IP6_NF_MATCH_TOS $CONFIG_IP6_NF_IPTABLES
# if [ "$CONFIG_IP6_NF_CONNTRACK" != "n" ]; then # if [ "$CONFIG_IP6_NF_CONNTRACK" != "n" ]; then
......
...@@ -8,7 +8,9 @@ export-objs := ip6_tables.o ...@@ -8,7 +8,9 @@ export-objs := ip6_tables.o
obj-$(CONFIG_IP6_NF_IPTABLES) += 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_LIMIT) += ip6t_limit.o
obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.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_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_MULTIPORT) += ip6t_multiport.o
obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
* 19 Jan 2002 Harald Welte <laforge@gnumonks.org> * 19 Jan 2002 Harald Welte <laforge@gnumonks.org>
* - increase module usage count as soon as we have rules inside * - increase module usage count as soon as we have rules inside
* a table * a table
* 06 Jun 2002 Andras Kis-Szabo <kisza@sch.bme.hu>
* - new extension header parser code
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
...@@ -25,6 +27,7 @@ ...@@ -25,6 +27,7 @@
#include <linux/netfilter_ipv6/ip6_tables.h> #include <linux/netfilter_ipv6/ip6_tables.h>
#define IPV6_HDR_LEN (sizeof(struct ipv6hdr)) #define IPV6_HDR_LEN (sizeof(struct ipv6hdr))
#define IPV6_OPTHDR_LEN (sizeof(struct ipv6_opt_hdr))
/*#define DEBUG_IP_FIREWALL*/ /*#define DEBUG_IP_FIREWALL*/
/*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */ /*#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, ...@@ -133,43 +136,23 @@ static int ip6_masked_addrcmp(struct in6_addr addr1, struct in6_addr mask,
return 0; return 0;
} }
/* takes in current header and pointer to the header */ /* Check for an extension */
/* if another header exists, sets hdrptr to the next header int
and returns the new header value, else returns 0 */ ip6t_ext_hdr(u8 nexthdr)
static u_int8_t ip6_nexthdr(u_int8_t currenthdr, u_int8_t *hdrptr)
{ {
int i; return ( (nexthdr == IPPROTO_HOPOPTS) ||
u_int8_t hdrlen, nexthdr = 0; (nexthdr == IPPROTO_ROUTING) ||
switch(currenthdr){ (nexthdr == IPPROTO_FRAGMENT) ||
case IPPROTO_AH: (nexthdr == IPPROTO_ESP) ||
/* whoever decided to do the length of AUTH for ipv6 (nexthdr == IPPROTO_AH) ||
in 32bit units unlike other headers should be beaten... (nexthdr == IPPROTO_NONE) ||
repeatedly...with a large stick...no, an even LARGER (nexthdr == IPPROTO_DSTOPTS) );
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;
} }
/* Returns whether matches rule or not. */ /* Returns whether matches rule or not. */
static inline int 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 *indev,
const char *outdev, const char *outdev,
const struct ip6t_ip6 *ip6info, const struct ip6t_ip6 *ip6info,
...@@ -227,17 +210,58 @@ ip6_packet_match(const struct ipv6hdr *ipv6, ...@@ -227,17 +210,58 @@ ip6_packet_match(const struct ipv6hdr *ipv6,
/* look for the desired protocol header */ /* look for the desired protocol header */
if((ip6info->flags & IP6T_F_PROTO)) { if((ip6info->flags & IP6T_F_PROTO)) {
u_int8_t currenthdr = ipv6->nexthdr; u_int8_t currenthdr = ipv6->nexthdr;
u_int8_t *hdrptr; struct ipv6_opt_hdr *hdrptr;
hdrptr = (u_int8_t *)(ipv6 + 1); u_int16_t ptr; /* Header offset in skb */
do { u_int16_t hdrlen; /* Header */
if (ip6info->proto == currenthdr) {
if(ip6info->invflags & IP6T_INV_PROTO) ptr = IPV6_HDR_LEN;
return 0;
return 1; 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); return 1;
} while(currenthdr); }
if (!(ip6info->invflags & IP6T_INV_PROTO))
/* We need match for the '-p all', too! */
if ((ip6info->proto != 0) &&
!(ip6info->invflags & IP6T_INV_PROTO))
return 0; return 0;
} }
return 1; return 1;
...@@ -359,7 +383,8 @@ ip6t_do_table(struct sk_buff **pskb, ...@@ -359,7 +383,8 @@ ip6t_do_table(struct sk_buff **pskb,
IP_NF_ASSERT(e); IP_NF_ASSERT(e);
IP_NF_ASSERT(back); IP_NF_ASSERT(back);
(*pskb)->nfcache |= e->nfcache; (*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; struct ip6t_entry_target *t;
if (IP6T_MATCH_ITERATE(e, do_match, if (IP6T_MATCH_ITERATE(e, do_match,
...@@ -1826,6 +1851,7 @@ EXPORT_SYMBOL(ip6t_register_match); ...@@ -1826,6 +1851,7 @@ EXPORT_SYMBOL(ip6t_register_match);
EXPORT_SYMBOL(ip6t_unregister_match); EXPORT_SYMBOL(ip6t_unregister_match);
EXPORT_SYMBOL(ip6t_register_target); EXPORT_SYMBOL(ip6t_register_target);
EXPORT_SYMBOL(ip6t_unregister_target); EXPORT_SYMBOL(ip6t_unregister_target);
EXPORT_SYMBOL(ip6t_ext_hdr);
module_init(init); module_init(init);
module_exit(fini); 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 @@ ...@@ -27,7 +27,7 @@
static void llc_station_ack_tmr_callback(unsigned long timeout_data); static void llc_station_ack_tmr_callback(unsigned long timeout_data);
int llc_station_ac_start_ack_timer(struct llc_station *station, 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); del_timer(&station->ack_timer);
station->ack_timer.expires = jiffies + LLC_ACK_TIME * HZ; station->ack_timer.expires = jiffies + LLC_ACK_TIME * HZ;
...@@ -39,98 +39,94 @@ int llc_station_ac_start_ack_timer(struct llc_station *station, ...@@ -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, 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; station->retry_count = 0;
return 0; return 0;
} }
int llc_station_ac_inc_retry_cnt_by_1(struct llc_station *station, 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++; station->retry_count++;
return 0; return 0;
} }
int llc_station_ac_set_xid_r_cnt_0(struct llc_station *station, 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; station->xid_r_count = 0;
return 0; return 0;
} }
int llc_station_ac_inc_xid_r_cnt_by_1(struct llc_station *station, 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++; station->xid_r_count++;
return 0; return 0;
} }
int llc_station_ac_send_null_dsap_xid_c(struct llc_station *station, 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; int rc = 1;
struct sk_buff *skb = llc_alloc_frame(); struct sk_buff *nskb = llc_alloc_frame();
if (!skb) if (!nskb)
goto out; goto out;
rc = 0; rc = 0;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD); llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 127); llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127);
lan_hdrs_init(skb, station->mac_sa, station->mac_sa); lan_hdrs_init(nskb, station->mac_sa, station->mac_sa);
llc_station_send_pdu(station, skb); llc_station_send_pdu(station, nskb);
out: out:
return rc; return rc;
} }
int llc_station_ac_send_xid_r(struct llc_station *station, 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; u8 mac_da[ETH_ALEN], dsap;
int rc = 1; int rc = 1;
struct sk_buff *ev_skb; struct sk_buff* nskb = llc_alloc_frame();
struct sk_buff* skb = llc_alloc_frame();
if (!skb) if (!nskb)
goto out; goto out;
rc = 0; rc = 0;
ev_skb = ev->data.pdu.skb; nskb->dev = skb->dev;
skb->dev = ev_skb->dev; llc_pdu_decode_sa(skb, mac_da);
llc_pdu_decode_sa(ev_skb, mac_da); llc_pdu_decode_ssap(skb, &dsap);
llc_pdu_decode_ssap(ev_skb, &dsap); llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP); llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127);
llc_pdu_init_as_xid_rsp(skb, LLC_XID_NULL_CLASS_2, 127); lan_hdrs_init(nskb, station->mac_sa, mac_da);
lan_hdrs_init(skb, station->mac_sa, mac_da); llc_station_send_pdu(station, nskb);
llc_station_send_pdu(station, skb);
out: out:
return rc; return rc;
} }
int llc_station_ac_send_test_r(struct llc_station *station, 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; u8 mac_da[ETH_ALEN], dsap;
int rc = 1; int rc = 1;
struct sk_buff *ev_skb; struct sk_buff *nskb = llc_alloc_frame();
struct sk_buff *skb = llc_alloc_frame();
if (!skb) if (!nskb)
goto out; goto out;
rc = 0; rc = 0;
ev_skb = ev->data.pdu.skb; nskb->dev = skb->dev;
skb->dev = ev_skb->dev; llc_pdu_decode_sa(skb, mac_da);
llc_pdu_decode_sa(ev_skb, mac_da); llc_pdu_decode_ssap(skb, &dsap);
llc_pdu_decode_ssap(ev_skb, &dsap); llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP); llc_pdu_init_as_test_rsp(nskb, skb);
llc_pdu_init_as_test_rsp(skb, ev_skb); lan_hdrs_init(nskb, station->mac_sa, mac_da);
lan_hdrs_init(skb, station->mac_sa, mac_da); llc_station_send_pdu(station, nskb);
llc_station_send_pdu(station, skb);
out: out:
return rc; return rc;
} }
int llc_station_ac_report_status(struct llc_station *station, int llc_station_ac_report_status(struct llc_station *station,
struct llc_station_state_ev *ev) struct sk_buff *skb)
{ {
return 0; return 0;
} }
...@@ -138,13 +134,14 @@ int llc_station_ac_report_status(struct llc_station *station, ...@@ -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) static void llc_station_ack_tmr_callback(unsigned long timeout_data)
{ {
struct llc_station *station = (struct llc_station *)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; station->ack_tmr_running = 0;
ev = llc_station_alloc_ev(station); if (skb) {
if (ev) { struct llc_station_state_ev *ev = llc_station_ev(skb);
ev->type = LLC_STATION_EV_TYPE_ACK_TMR; ev->type = LLC_STATION_EV_TYPE_ACK_TMR;
ev->data.tmr.timer_specific = NULL; ev->data.tmr.timer_specific = NULL;
llc_station_send_ev(station, ev); llc_station_send_ev(station, skb);
} }
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -28,56 +28,37 @@ ...@@ -28,56 +28,37 @@
static int llc_find_offset(int state, int ev_type); static int llc_find_offset(int state, int ev_type);
static void llc_conn_send_pdus(struct sock *sk); 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, static int llc_exec_conn_trans_actions(struct sock *sk,
struct llc_conn_state_trans *trans, struct llc_conn_state_trans *trans,
struct llc_conn_state_ev *ev); struct sk_buff *ev);
static struct llc_conn_state_trans * static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
llc_qualify_conn_ev(struct sock *sk, struct llc_conn_state_ev *ev); struct sk_buff *skb);
/* Offset table on connection states transition diagram */ /* Offset table on connection states transition diagram */
static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV]; 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 * llc_conn_send_event - sends event to connection state machine
* @sk: connection * @sk: connection
* @ev: occurred event * @skb: occurred event
* *
* Sends an event to connection state machine. after processing event * Sends an event to connection state machine. after processing event
* (executing it's actions and changing state), upper layer will be * (executing it's actions and changing state), upper layer will be
* indicated or confirmed, if needed. Returns 0 for success, 1 for * indicated or confirmed, if needed. Returns 0 for success, 1 for
* failure. The socket lock has to be held before calling this function. * 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 */ /* 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_opt *llc = llc_sk(sk);
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
u8 flag = ev->flag; u8 flag = ev->flag;
struct llc_prim_if_block *ind_prim = ev->ind_prim; struct llc_prim_if_block *ind_prim = ev->ind_prim;
struct llc_prim_if_block *cfm_prim = ev->cfm_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 #ifdef THIS_BREAKS_DISCONNECT_NOTIFICATION_BADLY
/* check if the connection was freed by the state machine by /* check if the connection was freed by the state machine by
* means of llc_conn_disc */ * means of llc_conn_disc */
...@@ -125,15 +106,14 @@ void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb) ...@@ -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 * llc_conn_rtn_pdu - sends received data pdu to upper layer
* @sk: Active connection * @sk: Active connection
* @skb: Received data frame * @skb: Received data frame
* @ev: Occurred event
* *
* Sends received data pdu to upper layer (by using indicate function). * Sends received data pdu to upper layer (by using indicate function).
* Prepares service parameters (prim and prim_data). calling indication * Prepares service parameters (prim and prim_data). calling indication
* function will be done in llc_conn_send_ev. * function will be done in llc_conn_send_ev.
*/ */
void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb, void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb)
struct llc_conn_state_ev *ev)
{ {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_opt *llc = llc_sk(sk); struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap; struct llc_sap *sap = llc->sap;
struct llc_prim_if_block *prim = &sap->llc_ind_prim; struct llc_prim_if_block *prim = &sap->llc_ind_prim;
...@@ -291,34 +271,37 @@ static void llc_conn_send_pdus(struct sock *sk) ...@@ -291,34 +271,37 @@ static void llc_conn_send_pdus(struct sock *sk)
/** /**
* llc_conn_free_ev - free event * llc_conn_free_ev - free event
* @ev: event to free * @skb: event to free
* *
* Free allocated event. * 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) { if (ev->type == LLC_CONN_EV_TYPE_PDU) {
/* free the frame that binded to this event */ /* free the frame that is bound to this event */
struct llc_pdu_sn *pdu = struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
(struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
if (LLC_PDU_TYPE_IS_I(pdu) || !ev->flag || !ev->ind_prim) if (LLC_PDU_TYPE_IS_I(pdu) || !ev->flag || !ev->ind_prim)
kfree_skb(ev->data.pdu.skb); kfree_skb(skb);
} } else if (ev->type == LLC_CONN_EV_TYPE_PRIM &&
/* free event structure to free list of the same */ ev->data.prim.prim != LLC_DATA_PRIM)
kfree(ev); 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 * llc_conn_service - finds transition and changes state of connection
* @sk: connection * @sk: connection
* @ev: happened event * @skb: happened event
* *
* This function finds transition that matches with happened event, then * This function finds transition that matches with happened event, then
* executes related actions and finally changes state of connection. * executes related actions and finally changes state of connection.
* Returns 0 for success, 1 for failure. * 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; int rc = 1;
struct llc_conn_state_trans *trans; struct llc_conn_state_trans *trans;
...@@ -326,9 +309,9 @@ static int llc_conn_service(struct sock *sk, struct llc_conn_state_ev *ev) ...@@ -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) if (llc_sk(sk)->state > NBR_CONN_STATES)
goto out; goto out;
rc = 0; rc = 0;
trans = llc_qualify_conn_ev(sk, ev); trans = llc_qualify_conn_ev(sk, skb);
if (trans) { 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) if (!rc && trans->next_state != NO_STATE_CHANGE)
llc_sk(sk)->state = trans->next_state; 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) ...@@ -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 * llc_qualify_conn_ev - finds transition for event
* @sk: connection * @sk: connection
* @ev: happened event * @skb: happened event
* *
* This function finds transition that matches with happened event. * This function finds transition that matches with happened event.
* Returns pointer to found transition on success, %NULL otherwise. * Returns pointer to found transition on success, %NULL otherwise.
*/ */
static struct llc_conn_state_trans * static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
llc_qualify_conn_ev(struct sock *sk, struct llc_conn_state_ev *ev) struct sk_buff *skb)
{ {
struct llc_conn_state_trans **next_trans; struct llc_conn_state_trans **next_trans;
llc_conn_ev_qfyr_t *next_qualifier; 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 = 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 /* search thru events for this state until
* list exhausted or until no more * list exhausted or until no more
*/ */
for (next_trans = curr_state->transitions + 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++) { (*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 /* got POSSIBLE event match; the event may require
* qualification based on the values of a number of * qualification based on the values of a number of
* state flags; if all qualifications are met (i.e., * state flags; if all qualifications are met (i.e.,
...@@ -367,7 +352,7 @@ static struct llc_conn_state_trans * ...@@ -367,7 +352,7 @@ static struct llc_conn_state_trans *
*/ */
for (next_qualifier = (*next_trans)->ev_qualifiers; for (next_qualifier = (*next_trans)->ev_qualifiers;
next_qualifier && *next_qualifier && next_qualifier && *next_qualifier &&
!(*next_qualifier)(sk, ev); next_qualifier++) !(*next_qualifier)(sk, skb); next_qualifier++)
/* nothing */; /* nothing */;
if (!next_qualifier || !*next_qualifier) if (!next_qualifier || !*next_qualifier)
/* all qualifiers executed successfully; this is /* all qualifiers executed successfully; this is
...@@ -384,7 +369,7 @@ static struct llc_conn_state_trans * ...@@ -384,7 +369,7 @@ static struct llc_conn_state_trans *
* llc_exec_conn_trans_actions - executes related actions * llc_exec_conn_trans_actions - executes related actions
* @sk: connection * @sk: connection
* @trans: transition that it's actions must be performed * @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 * 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 * success, 1 to indicate failure of at least one action or 2 if the
...@@ -392,14 +377,14 @@ static struct llc_conn_state_trans * ...@@ -392,14 +377,14 @@ static struct llc_conn_state_trans *
*/ */
static int llc_exec_conn_trans_actions(struct sock *sk, static int llc_exec_conn_trans_actions(struct sock *sk,
struct llc_conn_state_trans *trans, struct llc_conn_state_trans *trans,
struct llc_conn_state_ev *ev) struct sk_buff *skb)
{ {
int rc = 0; int rc = 0;
llc_conn_action_t *next_action; llc_conn_action_t *next_action;
for (next_action = trans->ev_actions; for (next_action = trans->ev_actions;
next_action && *next_action; next_action++) { next_action && *next_action; next_action++) {
int rc2 = (*next_action)(sk, ev); int rc2 = (*next_action)(sk, skb);
if (rc2 == 2) { if (rc2 == 2) {
rc = rc2; rc = rc2;
......
This diff is collapsed.
This diff is collapsed.
...@@ -27,6 +27,12 @@ ...@@ -27,6 +27,12 @@
#include <net/llc_s_ev.h> #include <net/llc_s_ev.h>
#include <linux/trdevice.h> #include <linux/trdevice.h>
#if 1
#define dprintk(args...) printk(KERN_DEBUG args)
#else
#define dprintk(args...)
#endif
/* function prototypes */ /* function prototypes */
static void fix_up_incoming_skb(struct sk_buff *skb); static void fix_up_incoming_skb(struct sk_buff *skb);
...@@ -46,7 +52,7 @@ int mac_send_pdu(struct sk_buff *skb) ...@@ -46,7 +52,7 @@ int mac_send_pdu(struct sk_buff *skb)
int pri = GFP_ATOMIC, rc = -1; int pri = GFP_ATOMIC, rc = -1;
if (!skb->dev) { if (!skb->dev) {
printk(KERN_ERR "%s: skb->dev == NULL!", __FUNCTION__); dprintk(KERN_ERR "%s: skb->dev == NULL!", __FUNCTION__);
goto out; goto out;
} }
if (skb->sk) if (skb->sk)
...@@ -83,7 +89,7 @@ int mac_indicate(struct sk_buff *skb, struct net_device *dev, ...@@ -83,7 +89,7 @@ int mac_indicate(struct sk_buff *skb, struct net_device *dev,
* receives, do not try to analyse it. * receives, do not try to analyse it.
*/ */
if (skb->pkt_type == PACKET_OTHERHOST) { if (skb->pkt_type == PACKET_OTHERHOST) {
printk(KERN_INFO "%s: PACKET_OTHERHOST\n", __FUNCTION__); dprintk(KERN_INFO "%s: PACKET_OTHERHOST\n", __FUNCTION__);
goto drop; goto drop;
} }
skb = skb_share_check(skb, GFP_ATOMIC); skb = skb_share_check(skb, GFP_ATOMIC);
...@@ -140,7 +146,8 @@ int mac_indicate(struct sk_buff *skb, struct net_device *dev, ...@@ -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, rc = llc_pdu_router(llc_sk(sk)->sap, sk, skb,
LLC_TYPE_2); LLC_TYPE_2);
} else { } 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); sk_add_backlog(sk, skb);
rc = 0; rc = 0;
} }
...@@ -207,38 +214,27 @@ int llc_pdu_router(struct llc_sap *sap, struct sock* sk, ...@@ -207,38 +214,27 @@ int llc_pdu_router(struct llc_sap *sap, struct sock* sk,
if (!pdu->dsap) { if (!pdu->dsap) {
struct llc_station *station = llc_station_get(); struct llc_station *station = llc_station_get();
struct llc_station_state_ev *stat_ev = struct llc_station_state_ev *ev = llc_station_ev(skb);
llc_station_alloc_ev(station);
if (stat_ev) { ev->type = LLC_STATION_EV_TYPE_PDU;
stat_ev->type = LLC_STATION_EV_TYPE_PDU; ev->data.pdu.reason = 0;
stat_ev->data.pdu.skb = skb; llc_station_send_ev(station, skb);
stat_ev->data.pdu.reason = 0;
llc_station_send_ev(station, stat_ev);
} else
rc = -ENOMEM;
} else if (type == LLC_TYPE_1) { } 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) { ev->type = LLC_SAP_EV_TYPE_PDU;
sap_ev->type = LLC_SAP_EV_TYPE_PDU; ev->data.pdu.reason = 0;
sap_ev->data.pdu.skb = skb; llc_sap_send_ev(sap, skb);
sap_ev->data.pdu.reason = 0;
llc_sap_send_ev(sap, sap_ev);
} else
rc = -ENOMEM;
} else if (type == LLC_TYPE_2) { } 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); struct llc_opt *llc = llc_sk(sk);
if (!llc->dev) if (!llc->dev)
llc->dev = skb->dev; llc->dev = skb->dev;
if (conn_ev) {
conn_ev->type = LLC_CONN_EV_TYPE_PDU; ev->type = LLC_CONN_EV_TYPE_PDU;
conn_ev->data.pdu.skb = skb; ev->data.pdu.reason = 0;
conn_ev->data.pdu.reason = 0; rc = llc_conn_send_ev(sk, skb);
rc = llc_conn_send_ev(sk, conn_ev);
} else
rc = -ENOMEM;
} else } else
rc = -EINVAL; rc = -EINVAL;
return rc; return rc;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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