Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: [NET]: Fully fix the memory leaks in sys_accept(). [NETFILTER]: iptables 32bit compat layer [NETFILTER]: {ip,nf}_conntrack_netlink: fix expectation notifier unregistration [NETFILTER]: fix ifdef for connmark support in nf_conntrack_netlink [NETFILTER]: x_tables: unify IPv4/IPv6 multiport match [NETFILTER]: x_tables: unify IPv4/IPv6 esp match [NET]: Fix dentry leak in sys_accept(). [IPSEC]: Kill unused decap state structure [IPSEC]: Kill unused decap state argument [NET]: com90xx kmalloc fix [TG3]: Update driver version and reldate. [TG3]: Revert "Speed up SRAM access"
This commit is contained in:
commit
bacd3add08
41 changed files with 1748 additions and 783 deletions
|
@ -125,11 +125,11 @@ static void __init com90xx_probe(void)
|
|||
if (!io && !irq && !shmem && !*device && com90xx_skip_probe)
|
||||
return;
|
||||
|
||||
shmems = kzalloc(((0x10000-0xa0000) / 0x800) * sizeof(unsigned long),
|
||||
shmems = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(unsigned long),
|
||||
GFP_KERNEL);
|
||||
if (!shmems)
|
||||
return;
|
||||
iomem = kzalloc(((0x10000-0xa0000) / 0x800) * sizeof(void __iomem *),
|
||||
iomem = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(void __iomem *),
|
||||
GFP_KERNEL);
|
||||
if (!iomem) {
|
||||
kfree(shmems);
|
||||
|
|
|
@ -69,8 +69,8 @@
|
|||
|
||||
#define DRV_MODULE_NAME "tg3"
|
||||
#define PFX DRV_MODULE_NAME ": "
|
||||
#define DRV_MODULE_VERSION "3.55"
|
||||
#define DRV_MODULE_RELDATE "Mar 27, 2006"
|
||||
#define DRV_MODULE_VERSION "3.56"
|
||||
#define DRV_MODULE_RELDATE "Apr 1, 2006"
|
||||
|
||||
#define TG3_DEF_MAC_MODE 0
|
||||
#define TG3_DEF_RX_MODE 0
|
||||
|
@ -497,40 +497,33 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
|
|||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tp->indirect_lock, flags);
|
||||
if (tp->write32 != tg3_write_indirect_reg32) {
|
||||
tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off);
|
||||
tw32_f(TG3PCI_MEM_WIN_DATA, val);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
|
||||
|
||||
/* Always leave this as zero. */
|
||||
tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0);
|
||||
} else {
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
|
||||
|
||||
/* Always leave this as zero. */
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
|
||||
}
|
||||
/* Always leave this as zero. */
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
|
||||
spin_unlock_irqrestore(&tp->indirect_lock, flags);
|
||||
}
|
||||
|
||||
static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val)
|
||||
{
|
||||
/* If no workaround is needed, write to mem space directly */
|
||||
if (tp->write32 != tg3_write_indirect_reg32)
|
||||
tw32(NIC_SRAM_WIN_BASE + off, val);
|
||||
else
|
||||
tg3_write_mem(tp, off, val);
|
||||
}
|
||||
|
||||
static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tp->indirect_lock, flags);
|
||||
if (tp->write32 != tg3_write_indirect_reg32) {
|
||||
tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off);
|
||||
*val = tr32(TG3PCI_MEM_WIN_DATA);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
|
||||
pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
|
||||
|
||||
/* Always leave this as zero. */
|
||||
tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0);
|
||||
} else {
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
|
||||
pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
|
||||
|
||||
/* Always leave this as zero. */
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
|
||||
}
|
||||
/* Always leave this as zero. */
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
|
||||
spin_unlock_irqrestore(&tp->indirect_lock, flags);
|
||||
}
|
||||
|
||||
|
@ -1374,12 +1367,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
|
|||
}
|
||||
}
|
||||
|
||||
tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
|
||||
|
||||
/* Finally, set the new power state. */
|
||||
pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
|
||||
udelay(100); /* Delay after power state change */
|
||||
|
||||
tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6547,11 +6540,11 @@ static void tg3_timer(unsigned long __opaque)
|
|||
if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
|
||||
u32 val;
|
||||
|
||||
tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
|
||||
FWCMD_NICDRV_ALIVE2);
|
||||
tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
|
||||
tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX,
|
||||
FWCMD_NICDRV_ALIVE2);
|
||||
tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
|
||||
/* 5 seconds timeout */
|
||||
tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
|
||||
tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
|
||||
val = tr32(GRC_RX_CPU_EVENT);
|
||||
val |= (1 << 14);
|
||||
tw32(GRC_RX_CPU_EVENT, val);
|
||||
|
|
|
@ -142,6 +142,12 @@ struct xt_counters_info
|
|||
#define ASSERT_WRITE_LOCK(x)
|
||||
#include <linux/netfilter_ipv4/listhelp.h>
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define COMPAT_TO_USER 1
|
||||
#define COMPAT_FROM_USER -1
|
||||
#define COMPAT_CALC_SIZE 0
|
||||
#endif
|
||||
|
||||
struct xt_match
|
||||
{
|
||||
struct list_head list;
|
||||
|
@ -175,6 +181,9 @@ struct xt_match
|
|||
void (*destroy)(const struct xt_match *match, void *matchinfo,
|
||||
unsigned int matchinfosize);
|
||||
|
||||
/* Called when userspace align differs from kernel space one */
|
||||
int (*compat)(void *match, void **dstptr, int *size, int convert);
|
||||
|
||||
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
|
||||
struct module *me;
|
||||
|
||||
|
@ -220,6 +229,9 @@ struct xt_target
|
|||
void (*destroy)(const struct xt_target *target, void *targinfo,
|
||||
unsigned int targinfosize);
|
||||
|
||||
/* Called when userspace align differs from kernel space one */
|
||||
int (*compat)(void *target, void **dstptr, int *size, int convert);
|
||||
|
||||
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
|
||||
struct module *me;
|
||||
|
||||
|
@ -314,6 +326,61 @@ extern void xt_proto_fini(int af);
|
|||
extern struct xt_table_info *xt_alloc_table_info(unsigned int size);
|
||||
extern void xt_free_table_info(struct xt_table_info *info);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <net/compat.h>
|
||||
|
||||
struct compat_xt_entry_match
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
u_int16_t match_size;
|
||||
char name[XT_FUNCTION_MAXNAMELEN - 1];
|
||||
u_int8_t revision;
|
||||
} user;
|
||||
u_int16_t match_size;
|
||||
} u;
|
||||
unsigned char data[0];
|
||||
};
|
||||
|
||||
struct compat_xt_entry_target
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
u_int16_t target_size;
|
||||
char name[XT_FUNCTION_MAXNAMELEN - 1];
|
||||
u_int8_t revision;
|
||||
} user;
|
||||
u_int16_t target_size;
|
||||
} u;
|
||||
unsigned char data[0];
|
||||
};
|
||||
|
||||
/* FIXME: this works only on 32 bit tasks
|
||||
* need to change whole approach in order to calculate align as function of
|
||||
* current task alignment */
|
||||
|
||||
struct compat_xt_counters
|
||||
{
|
||||
u_int32_t cnt[4];
|
||||
};
|
||||
|
||||
struct compat_xt_counters_info
|
||||
{
|
||||
char name[XT_TABLE_MAXNAMELEN];
|
||||
compat_uint_t num_counters;
|
||||
struct compat_xt_counters counters[0];
|
||||
};
|
||||
|
||||
#define COMPAT_XT_ALIGN(s) (((s) + (__alignof__(struct compat_xt_counters)-1)) \
|
||||
& ~(__alignof__(struct compat_xt_counters)-1))
|
||||
|
||||
extern void xt_compat_lock(int af);
|
||||
extern void xt_compat_unlock(int af);
|
||||
extern int xt_compat_match(void *match, void **dstptr, int *size, int convert);
|
||||
extern int xt_compat_target(void *target, void **dstptr, int *size,
|
||||
int convert);
|
||||
|
||||
#endif /* CONFIG_COMPAT */
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _X_TABLES_H */
|
||||
|
|
14
include/linux/netfilter/xt_esp.h
Normal file
14
include/linux/netfilter/xt_esp.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef _XT_ESP_H
|
||||
#define _XT_ESP_H
|
||||
|
||||
struct xt_esp
|
||||
{
|
||||
u_int32_t spis[2]; /* Security Parameter Index */
|
||||
u_int8_t invflags; /* Inverse flags */
|
||||
};
|
||||
|
||||
/* Values for "invflags" field in struct xt_esp. */
|
||||
#define XT_ESP_INV_SPI 0x01 /* Invert the sense of spi. */
|
||||
#define XT_ESP_INV_MASK 0x01 /* All possible flags. */
|
||||
|
||||
#endif /*_XT_ESP_H*/
|
30
include/linux/netfilter/xt_multiport.h
Normal file
30
include/linux/netfilter/xt_multiport.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef _XT_MULTIPORT_H
|
||||
#define _XT_MULTIPORT_H
|
||||
|
||||
enum xt_multiport_flags
|
||||
{
|
||||
XT_MULTIPORT_SOURCE,
|
||||
XT_MULTIPORT_DESTINATION,
|
||||
XT_MULTIPORT_EITHER
|
||||
};
|
||||
|
||||
#define XT_MULTI_PORTS 15
|
||||
|
||||
/* Must fit inside union xt_matchinfo: 16 bytes */
|
||||
struct xt_multiport
|
||||
{
|
||||
u_int8_t flags; /* Type of comparison */
|
||||
u_int8_t count; /* Number of ports */
|
||||
u_int16_t ports[XT_MULTI_PORTS]; /* Ports */
|
||||
};
|
||||
|
||||
struct xt_multiport_v1
|
||||
{
|
||||
u_int8_t flags; /* Type of comparison */
|
||||
u_int8_t count; /* Number of ports */
|
||||
u_int16_t ports[XT_MULTI_PORTS]; /* Ports */
|
||||
u_int8_t pflags[XT_MULTI_PORTS]; /* Port flags */
|
||||
u_int8_t invert; /* Invert flag */
|
||||
};
|
||||
|
||||
#endif /*_XT_MULTIPORT_H*/
|
|
@ -316,5 +316,23 @@ extern unsigned int ipt_do_table(struct sk_buff **pskb,
|
|||
void *userdata);
|
||||
|
||||
#define IPT_ALIGN(s) XT_ALIGN(s)
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <net/compat.h>
|
||||
|
||||
struct compat_ipt_entry
|
||||
{
|
||||
struct ipt_ip ip;
|
||||
compat_uint_t nfcache;
|
||||
u_int16_t target_offset;
|
||||
u_int16_t next_offset;
|
||||
compat_uint_t comefrom;
|
||||
struct compat_xt_counters counters;
|
||||
unsigned char elems[0];
|
||||
};
|
||||
|
||||
#define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s)
|
||||
|
||||
#endif /* CONFIG_COMPAT */
|
||||
#endif /*__KERNEL__*/
|
||||
#endif /* _IPTABLES_H */
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
#ifndef _IPT_ESP_H
|
||||
#define _IPT_ESP_H
|
||||
|
||||
struct ipt_esp
|
||||
{
|
||||
u_int32_t spis[2]; /* Security Parameter Index */
|
||||
u_int8_t invflags; /* Inverse flags */
|
||||
};
|
||||
#include <linux/netfilter/xt_esp.h>
|
||||
|
||||
|
||||
|
||||
/* Values for "invflags" field in struct ipt_esp. */
|
||||
#define IPT_ESP_INV_SPI 0x01 /* Invert the sense of spi. */
|
||||
#define IPT_ESP_INV_MASK 0x01 /* All possible flags. */
|
||||
#define ipt_esp xt_esp
|
||||
#define IPT_ESP_INV_SPI XT_ESP_INV_SPI
|
||||
#define IPT_ESP_INV_MASK XT_ESP_INV_MASK
|
||||
|
||||
#endif /*_IPT_ESP_H*/
|
||||
|
|
|
@ -1,30 +1,15 @@
|
|||
#ifndef _IPT_MULTIPORT_H
|
||||
#define _IPT_MULTIPORT_H
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
|
||||
enum ipt_multiport_flags
|
||||
{
|
||||
IPT_MULTIPORT_SOURCE,
|
||||
IPT_MULTIPORT_DESTINATION,
|
||||
IPT_MULTIPORT_EITHER
|
||||
};
|
||||
#include <linux/netfilter/xt_multiport.h>
|
||||
|
||||
#define IPT_MULTI_PORTS 15
|
||||
#define IPT_MULTIPORT_SOURCE XT_MULTIPORT_SOURCE
|
||||
#define IPT_MULTIPORT_DESTINATION XT_MULTIPORT_DESTINATION
|
||||
#define IPT_MULTIPORT_EITHER XT_MULTIPORT_EITHER
|
||||
|
||||
/* Must fit inside union ipt_matchinfo: 16 bytes */
|
||||
struct ipt_multiport
|
||||
{
|
||||
u_int8_t flags; /* Type of comparison */
|
||||
u_int8_t count; /* Number of ports */
|
||||
u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */
|
||||
};
|
||||
#define IPT_MULTI_PORTS XT_MULTI_PORTS
|
||||
|
||||
#define ipt_multiport xt_multiport
|
||||
#define ipt_multiport_v1 xt_multiport_v1
|
||||
|
||||
struct ipt_multiport_v1
|
||||
{
|
||||
u_int8_t flags; /* Type of comparison */
|
||||
u_int8_t count; /* Number of ports */
|
||||
u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */
|
||||
u_int8_t pflags[IPT_MULTI_PORTS]; /* Port flags */
|
||||
u_int8_t invert; /* Invert flag */
|
||||
};
|
||||
#endif /*_IPT_MULTIPORT_H*/
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
#ifndef _IP6T_ESP_H
|
||||
#define _IP6T_ESP_H
|
||||
|
||||
struct ip6t_esp
|
||||
{
|
||||
u_int32_t spis[2]; /* Security Parameter Index */
|
||||
u_int8_t invflags; /* Inverse flags */
|
||||
};
|
||||
#include <linux/netfilter/xt_esp.h>
|
||||
|
||||
/* Values for "invflags" field in struct ip6t_esp. */
|
||||
#define IP6T_ESP_INV_SPI 0x01 /* Invert the sense of spi. */
|
||||
#define IP6T_ESP_INV_MASK 0x01 /* All possible flags. */
|
||||
#define ip6t_esp xt_esp
|
||||
#define IP6T_ESP_INV_SPI XT_ESP_INV_SPI
|
||||
#define IP6T_ESP_INV_MASK XT_ESP_INV_MASK
|
||||
|
||||
#endif /*_IP6T_ESP_H*/
|
||||
|
|
|
@ -1,21 +1,14 @@
|
|||
#ifndef _IP6T_MULTIPORT_H
|
||||
#define _IP6T_MULTIPORT_H
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
|
||||
enum ip6t_multiport_flags
|
||||
{
|
||||
IP6T_MULTIPORT_SOURCE,
|
||||
IP6T_MULTIPORT_DESTINATION,
|
||||
IP6T_MULTIPORT_EITHER
|
||||
};
|
||||
#include <linux/netfilter/xt_multiport.h>
|
||||
|
||||
#define IP6T_MULTI_PORTS 15
|
||||
#define IP6T_MULTIPORT_SOURCE XT_MULTIPORT_SOURCE
|
||||
#define IP6T_MULTIPORT_DESTINATION XT_MULTIPORT_DESTINATION
|
||||
#define IP6T_MULTIPORT_EITHER XT_MULTIPORT_EITHER
|
||||
|
||||
/* Must fit inside union ip6t_matchinfo: 16 bytes */
|
||||
struct ip6t_multiport
|
||||
{
|
||||
u_int8_t flags; /* Type of comparison */
|
||||
u_int8_t count; /* Number of ports */
|
||||
u_int16_t ports[IP6T_MULTI_PORTS]; /* Ports */
|
||||
};
|
||||
#endif /*_IPT_MULTIPORT_H*/
|
||||
#define IP6T_MULTI_PORTS XT_MULTI_PORTS
|
||||
|
||||
#define ip6t_multiport xt_multiport
|
||||
|
||||
#endif /*_IP6T_MULTIPORT_H*/
|
||||
|
|
|
@ -242,7 +242,6 @@ extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
|
|||
|
||||
extern void xfrm_state_delete_tunnel(struct xfrm_state *x);
|
||||
|
||||
struct xfrm_decap_state;
|
||||
struct xfrm_type
|
||||
{
|
||||
char *description;
|
||||
|
@ -251,7 +250,7 @@ struct xfrm_type
|
|||
|
||||
int (*init_state)(struct xfrm_state *x);
|
||||
void (*destructor)(struct xfrm_state *);
|
||||
int (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
|
||||
int (*input)(struct xfrm_state *, struct sk_buff *skb);
|
||||
int (*output)(struct xfrm_state *, struct sk_buff *pskb);
|
||||
/* Estimate maximal size of result of transformation of a dgram */
|
||||
u32 (*get_max_size)(struct xfrm_state *, int size);
|
||||
|
@ -606,25 +605,11 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
|
|||
|
||||
extern void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
|
||||
|
||||
/* Decapsulation state, used by the input to store data during
|
||||
* decapsulation procedure, to be used later (during the policy
|
||||
* check
|
||||
*/
|
||||
struct xfrm_decap_state {
|
||||
char decap_data[20];
|
||||
__u16 decap_type;
|
||||
};
|
||||
|
||||
struct sec_decap_state {
|
||||
struct xfrm_state *xvec;
|
||||
struct xfrm_decap_state decap;
|
||||
};
|
||||
|
||||
struct sec_path
|
||||
{
|
||||
atomic_t refcnt;
|
||||
int len;
|
||||
struct sec_decap_state x[XFRM_MAX_DEPTH];
|
||||
struct xfrm_state *xvec[XFRM_MAX_DEPTH];
|
||||
};
|
||||
|
||||
static inline struct sec_path *
|
||||
|
|
|
@ -476,8 +476,7 @@ asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
|
|||
int err;
|
||||
struct socket *sock;
|
||||
|
||||
/* SO_SET_REPLACE seems to be the same in all levels */
|
||||
if (optname == IPT_SO_SET_REPLACE)
|
||||
if (level == SOL_IPV6 && optname == IPT_SO_SET_REPLACE)
|
||||
return do_netfilter_replace(fd, level, optname,
|
||||
optval, optlen);
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ error:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int ah_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
|
||||
static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
{
|
||||
int ah_hlen;
|
||||
struct iphdr *iph;
|
||||
|
|
|
@ -133,7 +133,7 @@ error:
|
|||
* expensive, so we only support truncated data, which is the recommended
|
||||
* and common case.
|
||||
*/
|
||||
static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
|
||||
static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
{
|
||||
struct iphdr *iph;
|
||||
struct ip_esp_hdr *esph;
|
||||
|
@ -208,9 +208,6 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc
|
|||
struct xfrm_encap_tmpl *encap = x->encap;
|
||||
struct udphdr *uh;
|
||||
|
||||
if (encap->encap_type != decap->decap_type)
|
||||
goto out;
|
||||
|
||||
uh = (struct udphdr *)(iph + 1);
|
||||
encap_len = (void*)esph - (void*)uh;
|
||||
|
||||
|
|
|
@ -81,8 +81,7 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int ipcomp_input(struct xfrm_state *x,
|
||||
struct xfrm_decap_state *decap, struct sk_buff *skb)
|
||||
static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
{
|
||||
u8 nexthdr;
|
||||
int err = 0;
|
||||
|
|
|
@ -221,16 +221,6 @@ config IP_NF_MATCH_IPRANGE
|
|||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_MULTIPORT
|
||||
tristate "Multiple port match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
help
|
||||
Multiport matching allows you to match TCP or UDP packets based on
|
||||
a series of source or destination ports: normally a rule can only
|
||||
match a single range of ports.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_TOS
|
||||
tristate "TOS match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
|
@ -272,12 +262,12 @@ config IP_NF_MATCH_DSCP
|
|||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP_NF_MATCH_AH_ESP
|
||||
tristate "AH/ESP match support"
|
||||
config IP_NF_MATCH_AH
|
||||
tristate "AH match support"
|
||||
depends on IP_NF_IPTABLES
|
||||
help
|
||||
These two match extensions (`ah' and `esp') allow you to match a
|
||||
range of SPIs inside AH or ESP headers of IPSec packets.
|
||||
This match extension allows you to match a range of SPIs
|
||||
inside AH header of IPSec packets.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
|
|
|
@ -53,13 +53,12 @@ obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
|
|||
# matches
|
||||
obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.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) += ipt_ah.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
|
||||
obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
|
||||
|
||||
|
|
|
@ -1658,7 +1658,7 @@ static void __exit ctnetlink_exit(void)
|
|||
printk("ctnetlink: unregistering from nfnetlink.\n");
|
||||
|
||||
#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
|
||||
ip_conntrack_unregister_notifier(&ctnl_notifier_exp);
|
||||
ip_conntrack_expect_unregister_notifier(&ctnl_notifier_exp);
|
||||
ip_conntrack_unregister_notifier(&ctnl_notifier);
|
||||
#endif
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,195 +0,0 @@
|
|||
/* Kernel module to match one of a list of TCP/UDP ports: ports are in
|
||||
the same place so we can treat them as equal. */
|
||||
|
||||
/* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ipt_multiport.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
|
||||
MODULE_DESCRIPTION("iptables multiple port match module");
|
||||
|
||||
#if 0
|
||||
#define duprintf(format, args...) printk(format , ## args)
|
||||
#else
|
||||
#define duprintf(format, args...)
|
||||
#endif
|
||||
|
||||
/* Returns 1 if the port is matched by the test, 0 otherwise. */
|
||||
static inline int
|
||||
ports_match(const u_int16_t *portlist, enum ipt_multiport_flags flags,
|
||||
u_int8_t count, u_int16_t src, u_int16_t dst)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i=0; i<count; i++) {
|
||||
if (flags != IPT_MULTIPORT_DESTINATION
|
||||
&& portlist[i] == src)
|
||||
return 1;
|
||||
|
||||
if (flags != IPT_MULTIPORT_SOURCE
|
||||
&& portlist[i] == dst)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns 1 if the port is matched by the test, 0 otherwise. */
|
||||
static inline int
|
||||
ports_match_v1(const struct ipt_multiport_v1 *minfo,
|
||||
u_int16_t src, u_int16_t dst)
|
||||
{
|
||||
unsigned int i;
|
||||
u_int16_t s, e;
|
||||
|
||||
for (i=0; i < minfo->count; i++) {
|
||||
s = minfo->ports[i];
|
||||
|
||||
if (minfo->pflags[i]) {
|
||||
/* range port matching */
|
||||
e = minfo->ports[++i];
|
||||
duprintf("src or dst matches with %d-%d?\n", s, e);
|
||||
|
||||
if (minfo->flags == IPT_MULTIPORT_SOURCE
|
||||
&& src >= s && src <= e)
|
||||
return 1 ^ minfo->invert;
|
||||
if (minfo->flags == IPT_MULTIPORT_DESTINATION
|
||||
&& dst >= s && dst <= e)
|
||||
return 1 ^ minfo->invert;
|
||||
if (minfo->flags == IPT_MULTIPORT_EITHER
|
||||
&& ((dst >= s && dst <= e)
|
||||
|| (src >= s && src <= e)))
|
||||
return 1 ^ minfo->invert;
|
||||
} else {
|
||||
/* exact port matching */
|
||||
duprintf("src or dst matches with %d?\n", s);
|
||||
|
||||
if (minfo->flags == IPT_MULTIPORT_SOURCE
|
||||
&& src == s)
|
||||
return 1 ^ minfo->invert;
|
||||
if (minfo->flags == IPT_MULTIPORT_DESTINATION
|
||||
&& dst == s)
|
||||
return 1 ^ minfo->invert;
|
||||
if (minfo->flags == IPT_MULTIPORT_EITHER
|
||||
&& (src == s || dst == s))
|
||||
return 1 ^ minfo->invert;
|
||||
}
|
||||
}
|
||||
|
||||
return minfo->invert;
|
||||
}
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const struct xt_match *match,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
u16 _ports[2], *pptr;
|
||||
const struct ipt_multiport *multiinfo = matchinfo;
|
||||
|
||||
if (offset)
|
||||
return 0;
|
||||
|
||||
pptr = skb_header_pointer(skb, protoff,
|
||||
sizeof(_ports), _ports);
|
||||
if (pptr == NULL) {
|
||||
/* We've been asked to examine this packet, and we
|
||||
* can't. Hence, no choice but to drop.
|
||||
*/
|
||||
duprintf("ipt_multiport:"
|
||||
" Dropping evil offset=0 tinygram.\n");
|
||||
*hotdrop = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ports_match(multiinfo->ports,
|
||||
multiinfo->flags, multiinfo->count,
|
||||
ntohs(pptr[0]), ntohs(pptr[1]));
|
||||
}
|
||||
|
||||
static int
|
||||
match_v1(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const struct xt_match *match,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
u16 _ports[2], *pptr;
|
||||
const struct ipt_multiport_v1 *multiinfo = matchinfo;
|
||||
|
||||
if (offset)
|
||||
return 0;
|
||||
|
||||
pptr = skb_header_pointer(skb, protoff,
|
||||
sizeof(_ports), _ports);
|
||||
if (pptr == NULL) {
|
||||
/* We've been asked to examine this packet, and we
|
||||
* can't. Hence, no choice but to drop.
|
||||
*/
|
||||
duprintf("ipt_multiport:"
|
||||
" Dropping evil offset=0 tinygram.\n");
|
||||
*hotdrop = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1]));
|
||||
}
|
||||
|
||||
static struct ipt_match multiport_match = {
|
||||
.name = "multiport",
|
||||
.revision = 0,
|
||||
.match = match,
|
||||
.matchsize = sizeof(struct ipt_multiport),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct ipt_match multiport_match_v1 = {
|
||||
.name = "multiport",
|
||||
.revision = 1,
|
||||
.match = match_v1,
|
||||
.matchsize = sizeof(struct ipt_multiport_v1),
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init ipt_multiport_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = ipt_register_match(&multiport_match);
|
||||
if (!err) {
|
||||
err = ipt_register_match(&multiport_match_v1);
|
||||
if (err)
|
||||
ipt_unregister_match(&multiport_match);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit ipt_multiport_fini(void)
|
||||
{
|
||||
ipt_unregister_match(&multiport_match);
|
||||
ipt_unregister_match(&multiport_match_v1);
|
||||
}
|
||||
|
||||
module_init(ipt_multiport_init);
|
||||
module_exit(ipt_multiport_fini);
|
|
@ -68,7 +68,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
|
|||
{
|
||||
int err;
|
||||
u32 spi, seq;
|
||||
struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH];
|
||||
struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
|
||||
struct xfrm_state *x;
|
||||
int xfrm_nr = 0;
|
||||
int decaps = 0;
|
||||
|
@ -90,14 +90,16 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
|
|||
if (unlikely(x->km.state != XFRM_STATE_VALID))
|
||||
goto drop_unlock;
|
||||
|
||||
if (x->encap->encap_type != encap_type)
|
||||
goto drop_unlock;
|
||||
|
||||
if (x->props.replay_window && xfrm_replay_check(x, seq))
|
||||
goto drop_unlock;
|
||||
|
||||
if (xfrm_state_check_expire(x))
|
||||
goto drop_unlock;
|
||||
|
||||
xfrm_vec[xfrm_nr].decap.decap_type = encap_type;
|
||||
if (x->type->input(x, &(xfrm_vec[xfrm_nr].decap), skb))
|
||||
if (x->type->input(x, skb))
|
||||
goto drop_unlock;
|
||||
|
||||
/* only the first xfrm gets the encap type */
|
||||
|
@ -111,7 +113,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
|
|||
|
||||
spin_unlock(&x->lock);
|
||||
|
||||
xfrm_vec[xfrm_nr++].xvec = x;
|
||||
xfrm_vec[xfrm_nr++] = x;
|
||||
|
||||
iph = skb->nh.iph;
|
||||
|
||||
|
@ -153,7 +155,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
|
|||
if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
|
||||
goto drop;
|
||||
|
||||
memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state));
|
||||
memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
|
||||
xfrm_nr * sizeof(xfrm_vec[0]));
|
||||
skb->sp->len += xfrm_nr;
|
||||
|
||||
nf_reset(skb);
|
||||
|
@ -184,7 +187,7 @@ drop_unlock:
|
|||
xfrm_state_put(x);
|
||||
drop:
|
||||
while (--xfrm_nr >= 0)
|
||||
xfrm_state_put(xfrm_vec[xfrm_nr].xvec);
|
||||
xfrm_state_put(xfrm_vec[xfrm_nr]);
|
||||
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
|
|
|
@ -21,7 +21,7 @@ static int ipip_output(struct xfrm_state *x, struct sk_buff *skb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
|
||||
static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -229,7 +229,7 @@ error:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
|
||||
static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
{
|
||||
/*
|
||||
* Before process AH
|
||||
|
|
|
@ -130,7 +130,7 @@ error:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
|
||||
static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
{
|
||||
struct ipv6hdr *iph;
|
||||
struct ipv6_esp_hdr *esph;
|
||||
|
|
|
@ -63,7 +63,7 @@ static void **ipcomp6_scratches;
|
|||
static int ipcomp6_scratch_users;
|
||||
static LIST_HEAD(ipcomp6_tfms_list);
|
||||
|
||||
static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
|
||||
static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
{
|
||||
int err = 0;
|
||||
u8 nexthdr = 0;
|
||||
|
|
|
@ -87,16 +87,6 @@ config IP6_NF_MATCH_HL
|
|||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_MATCH_MULTIPORT
|
||||
tristate "Multiple port match support"
|
||||
depends on IP6_NF_IPTABLES
|
||||
help
|
||||
Multiport matching allows you to match TCP or UDP packets based on
|
||||
a series of source or destination ports: normally a rule can only
|
||||
match a single range of ports.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_MATCH_OWNER
|
||||
tristate "Owner match support"
|
||||
depends on IP6_NF_IPTABLES
|
||||
|
@ -115,11 +105,11 @@ config IP6_NF_MATCH_IPV6HEADER
|
|||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config IP6_NF_MATCH_AHESP
|
||||
tristate "AH/ESP match support"
|
||||
config IP6_NF_MATCH_AH
|
||||
tristate "AH match support"
|
||||
depends on IP6_NF_IPTABLES
|
||||
help
|
||||
This module allows one to match AH and ESP packets.
|
||||
This module allows one to match AH packets.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
|
|
|
@ -8,9 +8,8 @@ obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
|
|||
obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_AHESP) += ip6t_esp.o ip6t_ah.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o
|
||||
obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
|
||||
obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
|
||||
obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
/* Kernel module to match ESP parameters. */
|
||||
/* (C) 2001-2002 Andras Kis-Szabo <kisza@sch.bme.hu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <linux/types.h>
|
||||
#include <net/checksum.h>
|
||||
#include <net/ipv6.h>
|
||||
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
#include <linux/netfilter_ipv6/ip6t_esp.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("IPv6 ESP match");
|
||||
MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
|
||||
|
||||
#if 0
|
||||
#define DEBUGP printk
|
||||
#else
|
||||
#define DEBUGP(format, args...)
|
||||
#endif
|
||||
|
||||
/* Returns 1 if the spi is matched by the range, 0 otherwise */
|
||||
static inline int
|
||||
spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
|
||||
{
|
||||
int r=0;
|
||||
DEBUGP("esp spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
|
||||
min,spi,max);
|
||||
r=(spi >= min && spi <= max) ^ invert;
|
||||
DEBUGP(" result %s\n",r? "PASS\n" : "FAILED\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const struct xt_match *match,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
struct ip_esp_hdr _esp, *eh;
|
||||
const struct ip6t_esp *espinfo = matchinfo;
|
||||
unsigned int ptr;
|
||||
|
||||
/* Make sure this isn't an evil packet */
|
||||
/*DEBUGP("ipv6_esp entered \n");*/
|
||||
|
||||
if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ESP, NULL) < 0)
|
||||
return 0;
|
||||
|
||||
eh = skb_header_pointer(skb, ptr, sizeof(_esp), &_esp);
|
||||
if (eh == NULL) {
|
||||
*hotdrop = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUGP("IPv6 ESP SPI %u %08X\n", ntohl(eh->spi), ntohl(eh->spi));
|
||||
|
||||
return (eh != NULL)
|
||||
&& spi_match(espinfo->spis[0], espinfo->spis[1],
|
||||
ntohl(eh->spi),
|
||||
!!(espinfo->invflags & IP6T_ESP_INV_SPI));
|
||||
}
|
||||
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const void *ip,
|
||||
const struct xt_match *match,
|
||||
void *matchinfo,
|
||||
unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ip6t_esp *espinfo = matchinfo;
|
||||
|
||||
if (espinfo->invflags & ~IP6T_ESP_INV_MASK) {
|
||||
DEBUGP("ip6t_esp: unknown flags %X\n",
|
||||
espinfo->invflags);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ip6t_match esp_match = {
|
||||
.name = "esp",
|
||||
.match = match,
|
||||
.matchsize = sizeof(struct ip6t_esp),
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init ip6t_esp_init(void)
|
||||
{
|
||||
return ip6t_register_match(&esp_match);
|
||||
}
|
||||
|
||||
static void __exit ip6t_esp_fini(void)
|
||||
{
|
||||
ip6t_unregister_match(&esp_match);
|
||||
}
|
||||
|
||||
module_init(ip6t_esp_init);
|
||||
module_exit(ip6t_esp_fini);
|
|
@ -1,125 +0,0 @@
|
|||
/* Kernel module to match one of a list of TCP/UDP ports: ports are in
|
||||
the same place so we can treat them as equal. */
|
||||
|
||||
/* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/in.h>
|
||||
|
||||
#include <linux/netfilter_ipv6/ip6t_multiport.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
|
||||
MODULE_DESCRIPTION("ip6tables match for multiple ports");
|
||||
|
||||
#if 0
|
||||
#define duprintf(format, args...) printk(format , ## args)
|
||||
#else
|
||||
#define duprintf(format, args...)
|
||||
#endif
|
||||
|
||||
/* Returns 1 if the port is matched by the test, 0 otherwise. */
|
||||
static inline int
|
||||
ports_match(const u_int16_t *portlist, enum ip6t_multiport_flags flags,
|
||||
u_int8_t count, u_int16_t src, u_int16_t dst)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i=0; i<count; i++) {
|
||||
if (flags != IP6T_MULTIPORT_DESTINATION
|
||||
&& portlist[i] == src)
|
||||
return 1;
|
||||
|
||||
if (flags != IP6T_MULTIPORT_SOURCE
|
||||
&& portlist[i] == dst)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const struct xt_match *match,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
u16 _ports[2], *pptr;
|
||||
const struct ip6t_multiport *multiinfo = matchinfo;
|
||||
|
||||
/* Must not be a fragment. */
|
||||
if (offset)
|
||||
return 0;
|
||||
|
||||
/* Must be big enough to read ports (both UDP and TCP have
|
||||
them at the start). */
|
||||
pptr = skb_header_pointer(skb, protoff, sizeof(_ports), &_ports[0]);
|
||||
if (pptr == NULL) {
|
||||
/* We've been asked to examine this packet, and we
|
||||
* can't. Hence, no choice but to drop.
|
||||
*/
|
||||
duprintf("ip6t_multiport:"
|
||||
" Dropping evil offset=0 tinygram.\n");
|
||||
*hotdrop = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ports_match(multiinfo->ports,
|
||||
multiinfo->flags, multiinfo->count,
|
||||
ntohs(pptr[0]), ntohs(pptr[1]));
|
||||
}
|
||||
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const void *info,
|
||||
const struct xt_match *match,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ip6t_ip6 *ip = info;
|
||||
const struct ip6t_multiport *multiinfo = matchinfo;
|
||||
|
||||
/* Must specify proto == TCP/UDP, no unknown flags or bad count */
|
||||
return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
|
||||
&& !(ip->invflags & IP6T_INV_PROTO)
|
||||
&& (multiinfo->flags == IP6T_MULTIPORT_SOURCE
|
||||
|| multiinfo->flags == IP6T_MULTIPORT_DESTINATION
|
||||
|| multiinfo->flags == IP6T_MULTIPORT_EITHER)
|
||||
&& multiinfo->count <= IP6T_MULTI_PORTS;
|
||||
}
|
||||
|
||||
static struct ip6t_match multiport_match = {
|
||||
.name = "multiport",
|
||||
.match = match,
|
||||
.matchsize = sizeof(struct ip6t_multiport),
|
||||
.checkentry = checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init ip6t_multiport_init(void)
|
||||
{
|
||||
return ip6t_register_match(&multiport_match);
|
||||
}
|
||||
|
||||
static void __exit ip6t_multiport_fini(void)
|
||||
{
|
||||
ip6t_unregister_match(&multiport_match);
|
||||
}
|
||||
|
||||
module_init(ip6t_multiport_init);
|
||||
module_exit(ip6t_multiport_fini);
|
|
@ -32,7 +32,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
|
|||
{
|
||||
int err;
|
||||
u32 seq;
|
||||
struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH];
|
||||
struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
|
||||
struct xfrm_state *x;
|
||||
int xfrm_nr = 0;
|
||||
int decaps = 0;
|
||||
|
@ -65,7 +65,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
|
|||
if (xfrm_state_check_expire(x))
|
||||
goto drop_unlock;
|
||||
|
||||
nexthdr = x->type->input(x, &(xfrm_vec[xfrm_nr].decap), skb);
|
||||
nexthdr = x->type->input(x, skb);
|
||||
if (nexthdr <= 0)
|
||||
goto drop_unlock;
|
||||
|
||||
|
@ -79,7 +79,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
|
|||
|
||||
spin_unlock(&x->lock);
|
||||
|
||||
xfrm_vec[xfrm_nr++].xvec = x;
|
||||
xfrm_vec[xfrm_nr++] = x;
|
||||
|
||||
if (x->props.mode) { /* XXX */
|
||||
if (nexthdr != IPPROTO_IPV6)
|
||||
|
@ -118,7 +118,8 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
|
|||
if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
|
||||
goto drop;
|
||||
|
||||
memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state));
|
||||
memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
|
||||
xfrm_nr * sizeof(xfrm_vec[0]));
|
||||
skb->sp->len += xfrm_nr;
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
|
||||
|
@ -149,7 +150,7 @@ drop_unlock:
|
|||
xfrm_state_put(x);
|
||||
drop:
|
||||
while (--xfrm_nr >= 0)
|
||||
xfrm_state_put(xfrm_vec[xfrm_nr].xvec);
|
||||
xfrm_state_put(xfrm_vec[xfrm_nr]);
|
||||
kfree_skb(skb);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -351,7 +351,7 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int xfrm6_tunnel_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
|
||||
static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -231,6 +231,15 @@ config NETFILTER_XT_MATCH_DCCP
|
|||
If you want to compile it as a module, say M here and read
|
||||
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||
|
||||
config NETFILTER_XT_MATCH_ESP
|
||||
tristate '"ESP" match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
This match extension allows you to match a range of SPIs
|
||||
inside ESP header of IPSec packets.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_HELPER
|
||||
tristate '"helper" match support'
|
||||
depends on NETFILTER_XTABLES
|
||||
|
@ -289,6 +298,16 @@ config NETFILTER_XT_MATCH_POLICY
|
|||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_MULTIPORT
|
||||
tristate "Multiple port match support"
|
||||
depends on NETFILTER_XTABLES
|
||||
help
|
||||
Multiport matching allows you to match TCP or UDP packets based on
|
||||
a series of source or destination ports: normally a rule can only
|
||||
match a single range of ports.
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_PHYSDEV
|
||||
tristate '"physdev" match support'
|
||||
depends on NETFILTER_XTABLES && BRIDGE_NETFILTER
|
||||
|
|
|
@ -35,11 +35,13 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o
|
|||
obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
|
||||
|
|
|
@ -1022,7 +1022,7 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[])
|
|||
return err;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
|
||||
#if defined(CONFIG_NF_CONNTRACK_MARK)
|
||||
if (cda[CTA_MARK-1])
|
||||
ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
|
||||
#endif
|
||||
|
@ -1062,7 +1062,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
|
|||
return err;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
|
||||
#if defined(CONFIG_NF_CONNTRACK_MARK)
|
||||
if (cda[CTA_MARK-1])
|
||||
ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
|
||||
#endif
|
||||
|
@ -1687,7 +1687,7 @@ static void __exit ctnetlink_exit(void)
|
|||
printk("ctnetlink: unregistering from nfnetlink.\n");
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_EVENTS
|
||||
nf_conntrack_unregister_notifier(&ctnl_notifier_exp);
|
||||
nf_conntrack_expect_unregister_notifier(&ctnl_notifier_exp);
|
||||
nf_conntrack_unregister_notifier(&ctnl_notifier);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ struct xt_af {
|
|||
struct list_head match;
|
||||
struct list_head target;
|
||||
struct list_head tables;
|
||||
struct mutex compat_mutex;
|
||||
};
|
||||
|
||||
static struct xt_af *xt;
|
||||
|
@ -272,6 +273,54 @@ int xt_check_match(const struct xt_match *match, unsigned short family,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(xt_check_match);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
int xt_compat_match(void *match, void **dstptr, int *size, int convert)
|
||||
{
|
||||
struct xt_match *m;
|
||||
struct compat_xt_entry_match *pcompat_m;
|
||||
struct xt_entry_match *pm;
|
||||
u_int16_t msize;
|
||||
int off, ret;
|
||||
|
||||
ret = 0;
|
||||
m = ((struct xt_entry_match *)match)->u.kernel.match;
|
||||
off = XT_ALIGN(m->matchsize) - COMPAT_XT_ALIGN(m->matchsize);
|
||||
switch (convert) {
|
||||
case COMPAT_TO_USER:
|
||||
pm = (struct xt_entry_match *)match;
|
||||
msize = pm->u.user.match_size;
|
||||
if (__copy_to_user(*dstptr, pm, msize)) {
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
msize -= off;
|
||||
if (put_user(msize, (u_int16_t *)*dstptr))
|
||||
ret = -EFAULT;
|
||||
*size -= off;
|
||||
*dstptr += msize;
|
||||
break;
|
||||
case COMPAT_FROM_USER:
|
||||
pcompat_m = (struct compat_xt_entry_match *)match;
|
||||
pm = (struct xt_entry_match *)*dstptr;
|
||||
msize = pcompat_m->u.user.match_size;
|
||||
memcpy(pm, pcompat_m, msize);
|
||||
msize += off;
|
||||
pm->u.user.match_size = msize;
|
||||
*size += off;
|
||||
*dstptr += msize;
|
||||
break;
|
||||
case COMPAT_CALC_SIZE:
|
||||
*size += off;
|
||||
break;
|
||||
default:
|
||||
ret = -ENOPROTOOPT;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_compat_match);
|
||||
#endif
|
||||
|
||||
int xt_check_target(const struct xt_target *target, unsigned short family,
|
||||
unsigned int size, const char *table, unsigned int hook_mask,
|
||||
unsigned short proto, int inv_proto)
|
||||
|
@ -301,6 +350,54 @@ int xt_check_target(const struct xt_target *target, unsigned short family,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(xt_check_target);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
int xt_compat_target(void *target, void **dstptr, int *size, int convert)
|
||||
{
|
||||
struct xt_target *t;
|
||||
struct compat_xt_entry_target *pcompat;
|
||||
struct xt_entry_target *pt;
|
||||
u_int16_t tsize;
|
||||
int off, ret;
|
||||
|
||||
ret = 0;
|
||||
t = ((struct xt_entry_target *)target)->u.kernel.target;
|
||||
off = XT_ALIGN(t->targetsize) - COMPAT_XT_ALIGN(t->targetsize);
|
||||
switch (convert) {
|
||||
case COMPAT_TO_USER:
|
||||
pt = (struct xt_entry_target *)target;
|
||||
tsize = pt->u.user.target_size;
|
||||
if (__copy_to_user(*dstptr, pt, tsize)) {
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
tsize -= off;
|
||||
if (put_user(tsize, (u_int16_t *)*dstptr))
|
||||
ret = -EFAULT;
|
||||
*size -= off;
|
||||
*dstptr += tsize;
|
||||
break;
|
||||
case COMPAT_FROM_USER:
|
||||
pcompat = (struct compat_xt_entry_target *)target;
|
||||
pt = (struct xt_entry_target *)*dstptr;
|
||||
tsize = pcompat->u.user.target_size;
|
||||
memcpy(pt, pcompat, tsize);
|
||||
tsize += off;
|
||||
pt->u.user.target_size = tsize;
|
||||
*size += off;
|
||||
*dstptr += tsize;
|
||||
break;
|
||||
case COMPAT_CALC_SIZE:
|
||||
*size += off;
|
||||
break;
|
||||
default:
|
||||
ret = -ENOPROTOOPT;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_compat_target);
|
||||
#endif
|
||||
|
||||
struct xt_table_info *xt_alloc_table_info(unsigned int size)
|
||||
{
|
||||
struct xt_table_info *newinfo;
|
||||
|
@ -371,6 +468,19 @@ void xt_table_unlock(struct xt_table *table)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(xt_table_unlock);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
void xt_compat_lock(int af)
|
||||
{
|
||||
mutex_lock(&xt[af].compat_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_compat_lock);
|
||||
|
||||
void xt_compat_unlock(int af)
|
||||
{
|
||||
mutex_unlock(&xt[af].compat_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_compat_unlock);
|
||||
#endif
|
||||
|
||||
struct xt_table_info *
|
||||
xt_replace_table(struct xt_table *table,
|
||||
|
@ -671,6 +781,9 @@ static int __init xt_init(void)
|
|||
|
||||
for (i = 0; i < NPROTO; i++) {
|
||||
mutex_init(&xt[i].mutex);
|
||||
#ifdef CONFIG_COMPAT
|
||||
mutex_init(&xt[i].compat_mutex);
|
||||
#endif
|
||||
INIT_LIST_HEAD(&xt[i].target);
|
||||
INIT_LIST_HEAD(&xt[i].match);
|
||||
INIT_LIST_HEAD(&xt[i].tables);
|
||||
|
|
|
@ -9,16 +9,22 @@
|
|||
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ipt_esp.h>
|
||||
#include <linux/netfilter/xt_esp.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>");
|
||||
MODULE_DESCRIPTION("iptables ESP SPI match module");
|
||||
MODULE_DESCRIPTION("x_tables ESP SPI match module");
|
||||
MODULE_ALIAS("ipt_esp");
|
||||
MODULE_ALIAS("ip6t_esp");
|
||||
|
||||
#ifdef DEBUG_CONNTRACK
|
||||
#if 0
|
||||
#define duprintf(format, args...) printk(format , ## args)
|
||||
#else
|
||||
#define duprintf(format, args...)
|
||||
|
@ -28,11 +34,11 @@ MODULE_DESCRIPTION("iptables ESP SPI match module");
|
|||
static inline int
|
||||
spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
|
||||
{
|
||||
int r=0;
|
||||
duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
|
||||
min,spi,max);
|
||||
r=(spi >= min && spi <= max) ^ invert;
|
||||
duprintf(" result %s\n",r? "PASS" : "FAILED");
|
||||
int r = 0;
|
||||
duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
|
||||
min, spi, max);
|
||||
r = (spi >= min && spi <= max) ^ invert;
|
||||
duprintf(" result %s\n", r ? "PASS" : "FAILED");
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -47,14 +53,13 @@ match(const struct sk_buff *skb,
|
|||
int *hotdrop)
|
||||
{
|
||||
struct ip_esp_hdr _esp, *eh;
|
||||
const struct ipt_esp *espinfo = matchinfo;
|
||||
const struct xt_esp *espinfo = matchinfo;
|
||||
|
||||
/* Must not be a fragment. */
|
||||
if (offset)
|
||||
return 0;
|
||||
|
||||
eh = skb_header_pointer(skb, protoff,
|
||||
sizeof(_esp), &_esp);
|
||||
eh = skb_header_pointer(skb, protoff, sizeof(_esp), &_esp);
|
||||
if (eh == NULL) {
|
||||
/* We've been asked to examine this packet, and we
|
||||
* can't. Hence, no choice but to drop.
|
||||
|
@ -64,9 +69,8 @@ match(const struct sk_buff *skb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
return spi_match(espinfo->spis[0], espinfo->spis[1],
|
||||
ntohl(eh->spi),
|
||||
!!(espinfo->invflags & IPT_ESP_INV_SPI));
|
||||
return spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi),
|
||||
!!(espinfo->invflags & XT_ESP_INV_SPI));
|
||||
}
|
||||
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
|
@ -78,34 +82,55 @@ checkentry(const char *tablename,
|
|||
unsigned int matchinfosize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_esp *espinfo = matchinfo;
|
||||
const struct xt_esp *espinfo = matchinfo;
|
||||
|
||||
/* Must specify no unknown invflags */
|
||||
if (espinfo->invflags & ~IPT_ESP_INV_MASK) {
|
||||
duprintf("ipt_esp: unknown flags %X\n", espinfo->invflags);
|
||||
if (espinfo->invflags & ~XT_ESP_INV_MASK) {
|
||||
duprintf("xt_esp: unknown flags %X\n", espinfo->invflags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct ipt_match esp_match = {
|
||||
static struct xt_match esp_match = {
|
||||
.name = "esp",
|
||||
.match = match,
|
||||
.matchsize = sizeof(struct ipt_esp),
|
||||
.family = AF_INET,
|
||||
.proto = IPPROTO_ESP,
|
||||
.checkentry = checkentry,
|
||||
.match = &match,
|
||||
.matchsize = sizeof(struct xt_esp),
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init ipt_esp_init(void)
|
||||
static struct xt_match esp6_match = {
|
||||
.name = "esp",
|
||||
.family = AF_INET6,
|
||||
.proto = IPPROTO_ESP,
|
||||
.match = &match,
|
||||
.matchsize = sizeof(struct xt_esp),
|
||||
.checkentry = &checkentry,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init xt_esp_init(void)
|
||||
{
|
||||
return ipt_register_match(&esp_match);
|
||||
int ret;
|
||||
ret = xt_register_match(&esp_match);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = xt_register_match(&esp6_match);
|
||||
if (ret)
|
||||
xt_unregister_match(&esp_match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit ipt_esp_fini(void)
|
||||
static void __exit xt_esp_cleanup(void)
|
||||
{
|
||||
ipt_unregister_match(&esp_match);
|
||||
xt_unregister_match(&esp_match);
|
||||
xt_unregister_match(&esp6_match);
|
||||
}
|
||||
|
||||
module_init(ipt_esp_init);
|
||||
module_exit(ipt_esp_fini);
|
||||
module_init(xt_esp_init);
|
||||
module_exit(xt_esp_cleanup);
|
314
net/netfilter/xt_multiport.c
Normal file
314
net/netfilter/xt_multiport.c
Normal file
|
@ -0,0 +1,314 @@
|
|||
/* Kernel module to match one of a list of TCP/UDP ports: ports are in
|
||||
the same place so we can treat them as equal. */
|
||||
|
||||
/* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/in.h>
|
||||
|
||||
#include <linux/netfilter/xt_multiport.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||
#include <linux/netfilter_ipv6/ip6_tables.h>
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
|
||||
MODULE_DESCRIPTION("x_tables multiple port match module");
|
||||
MODULE_ALIAS("ipt_multiport");
|
||||
MODULE_ALIAS("ip6t_multiport");
|
||||
|
||||
#if 0
|
||||
#define duprintf(format, args...) printk(format , ## args)
|
||||
#else
|
||||
#define duprintf(format, args...)
|
||||
#endif
|
||||
|
||||
/* Returns 1 if the port is matched by the test, 0 otherwise. */
|
||||
static inline int
|
||||
ports_match(const u_int16_t *portlist, enum xt_multiport_flags flags,
|
||||
u_int8_t count, u_int16_t src, u_int16_t dst)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (flags != XT_MULTIPORT_DESTINATION && portlist[i] == src)
|
||||
return 1;
|
||||
|
||||
if (flags != XT_MULTIPORT_SOURCE && portlist[i] == dst)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns 1 if the port is matched by the test, 0 otherwise. */
|
||||
static inline int
|
||||
ports_match_v1(const struct xt_multiport_v1 *minfo,
|
||||
u_int16_t src, u_int16_t dst)
|
||||
{
|
||||
unsigned int i;
|
||||
u_int16_t s, e;
|
||||
|
||||
for (i = 0; i < minfo->count; i++) {
|
||||
s = minfo->ports[i];
|
||||
|
||||
if (minfo->pflags[i]) {
|
||||
/* range port matching */
|
||||
e = minfo->ports[++i];
|
||||
duprintf("src or dst matches with %d-%d?\n", s, e);
|
||||
|
||||
if (minfo->flags == XT_MULTIPORT_SOURCE
|
||||
&& src >= s && src <= e)
|
||||
return 1 ^ minfo->invert;
|
||||
if (minfo->flags == XT_MULTIPORT_DESTINATION
|
||||
&& dst >= s && dst <= e)
|
||||
return 1 ^ minfo->invert;
|
||||
if (minfo->flags == XT_MULTIPORT_EITHER
|
||||
&& ((dst >= s && dst <= e)
|
||||
|| (src >= s && src <= e)))
|
||||
return 1 ^ minfo->invert;
|
||||
} else {
|
||||
/* exact port matching */
|
||||
duprintf("src or dst matches with %d?\n", s);
|
||||
|
||||
if (minfo->flags == XT_MULTIPORT_SOURCE
|
||||
&& src == s)
|
||||
return 1 ^ minfo->invert;
|
||||
if (minfo->flags == XT_MULTIPORT_DESTINATION
|
||||
&& dst == s)
|
||||
return 1 ^ minfo->invert;
|
||||
if (minfo->flags == XT_MULTIPORT_EITHER
|
||||
&& (src == s || dst == s))
|
||||
return 1 ^ minfo->invert;
|
||||
}
|
||||
}
|
||||
|
||||
return minfo->invert;
|
||||
}
|
||||
|
||||
static int
|
||||
match(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const struct xt_match *match,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
u16 _ports[2], *pptr;
|
||||
const struct xt_multiport *multiinfo = matchinfo;
|
||||
|
||||
if (offset)
|
||||
return 0;
|
||||
|
||||
pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports);
|
||||
if (pptr == NULL) {
|
||||
/* We've been asked to examine this packet, and we
|
||||
* can't. Hence, no choice but to drop.
|
||||
*/
|
||||
duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
|
||||
*hotdrop = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ports_match(multiinfo->ports,
|
||||
multiinfo->flags, multiinfo->count,
|
||||
ntohs(pptr[0]), ntohs(pptr[1]));
|
||||
}
|
||||
|
||||
static int
|
||||
match_v1(const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const struct xt_match *match,
|
||||
const void *matchinfo,
|
||||
int offset,
|
||||
unsigned int protoff,
|
||||
int *hotdrop)
|
||||
{
|
||||
u16 _ports[2], *pptr;
|
||||
const struct xt_multiport_v1 *multiinfo = matchinfo;
|
||||
|
||||
if (offset)
|
||||
return 0;
|
||||
|
||||
pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports);
|
||||
if (pptr == NULL) {
|
||||
/* We've been asked to examine this packet, and we
|
||||
* can't. Hence, no choice but to drop.
|
||||
*/
|
||||
duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
|
||||
*hotdrop = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1]));
|
||||
}
|
||||
|
||||
static inline int
|
||||
check(u_int16_t proto,
|
||||
u_int8_t ip_invflags,
|
||||
u_int8_t match_flags,
|
||||
u_int8_t count)
|
||||
{
|
||||
/* Must specify proto == TCP/UDP, no unknown flags or bad count */
|
||||
return (proto == IPPROTO_TCP || proto == IPPROTO_UDP)
|
||||
&& !(ip_invflags & XT_INV_PROTO)
|
||||
&& (match_flags == XT_MULTIPORT_SOURCE
|
||||
|| match_flags == XT_MULTIPORT_DESTINATION
|
||||
|| match_flags == XT_MULTIPORT_EITHER)
|
||||
&& count <= XT_MULTI_PORTS;
|
||||
}
|
||||
|
||||
/* Called when user tries to insert an entry of this type. */
|
||||
static int
|
||||
checkentry(const char *tablename,
|
||||
const void *info,
|
||||
const struct xt_match *match,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_ip *ip = info;
|
||||
const struct xt_multiport *multiinfo = matchinfo;
|
||||
|
||||
return check(ip->proto, ip->invflags, multiinfo->flags,
|
||||
multiinfo->count);
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry_v1(const char *tablename,
|
||||
const void *info,
|
||||
const struct xt_match *match,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_ip *ip = info;
|
||||
const struct xt_multiport_v1 *multiinfo = matchinfo;
|
||||
|
||||
return check(ip->proto, ip->invflags, multiinfo->flags,
|
||||
multiinfo->count);
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry6(const char *tablename,
|
||||
const void *info,
|
||||
const struct xt_match *match,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ip6t_ip6 *ip = info;
|
||||
const struct xt_multiport *multiinfo = matchinfo;
|
||||
|
||||
return check(ip->proto, ip->invflags, multiinfo->flags,
|
||||
multiinfo->count);
|
||||
}
|
||||
|
||||
static int
|
||||
checkentry6_v1(const char *tablename,
|
||||
const void *info,
|
||||
const struct xt_match *match,
|
||||
void *matchinfo,
|
||||
unsigned int matchsize,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ip6t_ip6 *ip = info;
|
||||
const struct xt_multiport_v1 *multiinfo = matchinfo;
|
||||
|
||||
return check(ip->proto, ip->invflags, multiinfo->flags,
|
||||
multiinfo->count);
|
||||
}
|
||||
|
||||
static struct xt_match multiport_match = {
|
||||
.name = "multiport",
|
||||
.revision = 0,
|
||||
.matchsize = sizeof(struct xt_multiport),
|
||||
.match = &match,
|
||||
.checkentry = &checkentry,
|
||||
.family = AF_INET,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct xt_match multiport_match_v1 = {
|
||||
.name = "multiport",
|
||||
.revision = 1,
|
||||
.matchsize = sizeof(struct xt_multiport_v1),
|
||||
.match = &match_v1,
|
||||
.checkentry = &checkentry_v1,
|
||||
.family = AF_INET,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct xt_match multiport6_match = {
|
||||
.name = "multiport",
|
||||
.revision = 0,
|
||||
.matchsize = sizeof(struct xt_multiport),
|
||||
.match = &match,
|
||||
.checkentry = &checkentry6,
|
||||
.family = AF_INET6,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct xt_match multiport6_match_v1 = {
|
||||
.name = "multiport",
|
||||
.revision = 1,
|
||||
.matchsize = sizeof(struct xt_multiport_v1),
|
||||
.match = &match_v1,
|
||||
.checkentry = &checkentry6_v1,
|
||||
.family = AF_INET6,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init xt_multiport_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = xt_register_match(&multiport_match);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = xt_register_match(&multiport_match_v1);
|
||||
if (ret)
|
||||
goto out_unreg_multi_v0;
|
||||
|
||||
ret = xt_register_match(&multiport6_match);
|
||||
if (ret)
|
||||
goto out_unreg_multi_v1;
|
||||
|
||||
ret = xt_register_match(&multiport6_match_v1);
|
||||
if (ret)
|
||||
goto out_unreg_multi6_v0;
|
||||
|
||||
return ret;
|
||||
|
||||
out_unreg_multi6_v0:
|
||||
xt_unregister_match(&multiport6_match);
|
||||
out_unreg_multi_v1:
|
||||
xt_unregister_match(&multiport_match_v1);
|
||||
out_unreg_multi_v0:
|
||||
xt_unregister_match(&multiport_match);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit xt_multiport_fini(void)
|
||||
{
|
||||
xt_unregister_match(&multiport_match);
|
||||
xt_unregister_match(&multiport_match_v1);
|
||||
xt_unregister_match(&multiport6_match);
|
||||
xt_unregister_match(&multiport6_match_v1);
|
||||
}
|
||||
|
||||
module_init(xt_multiport_init);
|
||||
module_exit(xt_multiport_fini);
|
|
@ -71,7 +71,7 @@ match_policy_in(const struct sk_buff *skb, const struct xt_policy_info *info,
|
|||
return 0;
|
||||
e = &info->pol[pos];
|
||||
|
||||
if (match_xfrm_state(sp->x[i].xvec, e, family)) {
|
||||
if (match_xfrm_state(sp->xvec[i], e, family)) {
|
||||
if (!strict)
|
||||
return 1;
|
||||
} else if (strict)
|
||||
|
|
|
@ -1418,7 +1418,8 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _
|
|||
newfd = sock_alloc_fd(&newfile);
|
||||
if (unlikely(newfd < 0)) {
|
||||
err = newfd;
|
||||
goto out_release;
|
||||
sock_release(newsock);
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
err = sock_attach_fd(newsock, newfile);
|
||||
|
@ -1455,10 +1456,8 @@ out_put:
|
|||
out:
|
||||
return err;
|
||||
out_fd:
|
||||
put_filp(newfile);
|
||||
fput(newfile);
|
||||
put_unused_fd(newfd);
|
||||
out_release:
|
||||
sock_release(newsock);
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ void __secpath_destroy(struct sec_path *sp)
|
|||
{
|
||||
int i;
|
||||
for (i = 0; i < sp->len; i++)
|
||||
xfrm_state_put(sp->x[i].xvec);
|
||||
xfrm_state_put(sp->xvec[i]);
|
||||
kmem_cache_free(secpath_cachep, sp);
|
||||
}
|
||||
EXPORT_SYMBOL(__secpath_destroy);
|
||||
|
@ -37,7 +37,7 @@ struct sec_path *secpath_dup(struct sec_path *src)
|
|||
|
||||
memcpy(sp, src, sizeof(*sp));
|
||||
for (i = 0; i < sp->len; i++)
|
||||
xfrm_state_hold(sp->x[i].xvec);
|
||||
xfrm_state_hold(sp->xvec[i]);
|
||||
}
|
||||
atomic_set(&sp->refcnt, 1);
|
||||
return sp;
|
||||
|
|
|
@ -943,9 +943,9 @@ xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int start,
|
|||
} else
|
||||
start = -1;
|
||||
for (; idx < sp->len; idx++) {
|
||||
if (xfrm_state_ok(tmpl, sp->x[idx].xvec, family))
|
||||
if (xfrm_state_ok(tmpl, sp->xvec[idx], family))
|
||||
return ++idx;
|
||||
if (sp->x[idx].xvec->props.mode)
|
||||
if (sp->xvec[idx]->props.mode)
|
||||
break;
|
||||
}
|
||||
return start;
|
||||
|
@ -968,7 +968,7 @@ EXPORT_SYMBOL(xfrm_decode_session);
|
|||
static inline int secpath_has_tunnel(struct sec_path *sp, int k)
|
||||
{
|
||||
for (; k < sp->len; k++) {
|
||||
if (sp->x[k].xvec->props.mode)
|
||||
if (sp->xvec[k]->props.mode)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -994,8 +994,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
|
|||
int i;
|
||||
|
||||
for (i=skb->sp->len-1; i>=0; i--) {
|
||||
struct sec_decap_state *xvec = &(skb->sp->x[i]);
|
||||
if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family))
|
||||
struct xfrm_state *x = skb->sp->xvec[i];
|
||||
if (!xfrm_selector_match(&x->sel, &fl, family))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue