Commit bacd3add authored by Linus Torvalds's avatar Linus Torvalds

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"
parents 29e35094 9a1875e6
...@@ -125,11 +125,11 @@ static void __init com90xx_probe(void) ...@@ -125,11 +125,11 @@ static void __init com90xx_probe(void)
if (!io && !irq && !shmem && !*device && com90xx_skip_probe) if (!io && !irq && !shmem && !*device && com90xx_skip_probe)
return; return;
shmems = kzalloc(((0x10000-0xa0000) / 0x800) * sizeof(unsigned long), shmems = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(unsigned long),
GFP_KERNEL); GFP_KERNEL);
if (!shmems) if (!shmems)
return; return;
iomem = kzalloc(((0x10000-0xa0000) / 0x800) * sizeof(void __iomem *), iomem = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(void __iomem *),
GFP_KERNEL); GFP_KERNEL);
if (!iomem) { if (!iomem) {
kfree(shmems); kfree(shmems);
......
...@@ -69,8 +69,8 @@ ...@@ -69,8 +69,8 @@
#define DRV_MODULE_NAME "tg3" #define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": " #define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "3.55" #define DRV_MODULE_VERSION "3.56"
#define DRV_MODULE_RELDATE "Mar 27, 2006" #define DRV_MODULE_RELDATE "Apr 1, 2006"
#define TG3_DEF_MAC_MODE 0 #define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0 #define TG3_DEF_RX_MODE 0
...@@ -497,40 +497,33 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) ...@@ -497,40 +497,33 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&tp->indirect_lock, flags); spin_lock_irqsave(&tp->indirect_lock, flags);
if (tp->write32 != tg3_write_indirect_reg32) { pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
tw32_f(TG3PCI_MEM_WIN_DATA, val);
/* Always leave this as zero. */ /* Always leave this as zero. */
tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); pci_write_config_dword(tp->pdev, 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);
}
spin_unlock_irqrestore(&tp->indirect_lock, flags); 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) static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&tp->indirect_lock, flags); spin_lock_irqsave(&tp->indirect_lock, flags);
if (tp->write32 != tg3_write_indirect_reg32) { pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
*val = tr32(TG3PCI_MEM_WIN_DATA);
/* Always leave this as zero. */ /* Always leave this as zero. */
tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); pci_write_config_dword(tp->pdev, 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);
}
spin_unlock_irqrestore(&tp->indirect_lock, flags); spin_unlock_irqrestore(&tp->indirect_lock, flags);
} }
...@@ -1374,12 +1367,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) ...@@ -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. */ /* Finally, set the new power state. */
pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
udelay(100); /* Delay after power state change */ udelay(100); /* Delay after power state change */
tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
return 0; return 0;
} }
...@@ -6547,11 +6540,11 @@ static void tg3_timer(unsigned long __opaque) ...@@ -6547,11 +6540,11 @@ static void tg3_timer(unsigned long __opaque)
if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
u32 val; u32 val;
tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX,
FWCMD_NICDRV_ALIVE2); FWCMD_NICDRV_ALIVE2);
tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
/* 5 seconds timeout */ /* 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 = tr32(GRC_RX_CPU_EVENT);
val |= (1 << 14); val |= (1 << 14);
tw32(GRC_RX_CPU_EVENT, val); tw32(GRC_RX_CPU_EVENT, val);
......
...@@ -142,6 +142,12 @@ struct xt_counters_info ...@@ -142,6 +142,12 @@ struct xt_counters_info
#define ASSERT_WRITE_LOCK(x) #define ASSERT_WRITE_LOCK(x)
#include <linux/netfilter_ipv4/listhelp.h> #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 xt_match
{ {
struct list_head list; struct list_head list;
...@@ -175,6 +181,9 @@ struct xt_match ...@@ -175,6 +181,9 @@ struct xt_match
void (*destroy)(const struct xt_match *match, void *matchinfo, void (*destroy)(const struct xt_match *match, void *matchinfo,
unsigned int matchinfosize); 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 */ /* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me; struct module *me;
...@@ -220,6 +229,9 @@ struct xt_target ...@@ -220,6 +229,9 @@ struct xt_target
void (*destroy)(const struct xt_target *target, void *targinfo, void (*destroy)(const struct xt_target *target, void *targinfo,
unsigned int targinfosize); 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 */ /* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me; struct module *me;
...@@ -314,6 +326,61 @@ extern void xt_proto_fini(int af); ...@@ -314,6 +326,61 @@ extern void xt_proto_fini(int af);
extern struct xt_table_info *xt_alloc_table_info(unsigned int size); extern struct xt_table_info *xt_alloc_table_info(unsigned int size);
extern void xt_free_table_info(struct xt_table_info *info); 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 /* __KERNEL__ */
#endif /* _X_TABLES_H */ #endif /* _X_TABLES_H */
#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*/
#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, ...@@ -316,5 +316,23 @@ extern unsigned int ipt_do_table(struct sk_buff **pskb,
void *userdata); void *userdata);
#define IPT_ALIGN(s) XT_ALIGN(s) #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 /*__KERNEL__*/
#endif /* _IPTABLES_H */ #endif /* _IPTABLES_H */
#ifndef _IPT_ESP_H #ifndef _IPT_ESP_H
#define _IPT_ESP_H #define _IPT_ESP_H
struct ipt_esp #include <linux/netfilter/xt_esp.h>
{
u_int32_t spis[2]; /* Security Parameter Index */
u_int8_t invflags; /* Inverse flags */
};
#define ipt_esp xt_esp
#define IPT_ESP_INV_SPI XT_ESP_INV_SPI
/* Values for "invflags" field in struct ipt_esp. */ #define IPT_ESP_INV_MASK XT_ESP_INV_MASK
#define IPT_ESP_INV_SPI 0x01 /* Invert the sense of spi. */
#define IPT_ESP_INV_MASK 0x01 /* All possible flags. */
#endif /*_IPT_ESP_H*/ #endif /*_IPT_ESP_H*/
#ifndef _IPT_MULTIPORT_H #ifndef _IPT_MULTIPORT_H
#define _IPT_MULTIPORT_H #define _IPT_MULTIPORT_H
#include <linux/netfilter_ipv4/ip_tables.h>
enum ipt_multiport_flags #include <linux/netfilter/xt_multiport.h>
{
IPT_MULTIPORT_SOURCE,
IPT_MULTIPORT_DESTINATION,
IPT_MULTIPORT_EITHER
};
#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 */ #define IPT_MULTI_PORTS XT_MULTI_PORTS
struct ipt_multiport
{ #define ipt_multiport xt_multiport
u_int8_t flags; /* Type of comparison */ #define ipt_multiport_v1 xt_multiport_v1
u_int8_t count; /* Number of ports */
u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */
};
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*/ #endif /*_IPT_MULTIPORT_H*/
#ifndef _IP6T_ESP_H #ifndef _IP6T_ESP_H
#define _IP6T_ESP_H #define _IP6T_ESP_H
struct ip6t_esp #include <linux/netfilter/xt_esp.h>
{
u_int32_t spis[2]; /* Security Parameter Index */
u_int8_t invflags; /* Inverse flags */
};
/* Values for "invflags" field in struct ip6t_esp. */ #define ip6t_esp xt_esp
#define IP6T_ESP_INV_SPI 0x01 /* Invert the sense of spi. */ #define IP6T_ESP_INV_SPI XT_ESP_INV_SPI
#define IP6T_ESP_INV_MASK 0x01 /* All possible flags. */ #define IP6T_ESP_INV_MASK XT_ESP_INV_MASK
#endif /*_IP6T_ESP_H*/ #endif /*_IP6T_ESP_H*/
#ifndef _IP6T_MULTIPORT_H #ifndef _IP6T_MULTIPORT_H
#define _IP6T_MULTIPORT_H #define _IP6T_MULTIPORT_H
#include <linux/netfilter_ipv6/ip6_tables.h>
enum ip6t_multiport_flags #include <linux/netfilter/xt_multiport.h>
{
IP6T_MULTIPORT_SOURCE,
IP6T_MULTIPORT_DESTINATION,
IP6T_MULTIPORT_EITHER
};
#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 */ #define IP6T_MULTI_PORTS XT_MULTI_PORTS
struct ip6t_multiport
{ #define ip6t_multiport xt_multiport
u_int8_t flags; /* Type of comparison */
u_int8_t count; /* Number of ports */ #endif /*_IP6T_MULTIPORT_H*/
u_int16_t ports[IP6T_MULTI_PORTS]; /* Ports */
};
#endif /*_IPT_MULTIPORT_H*/
...@@ -242,7 +242,6 @@ extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo); ...@@ -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); extern void xfrm_state_delete_tunnel(struct xfrm_state *x);
struct xfrm_decap_state;
struct xfrm_type struct xfrm_type
{ {
char *description; char *description;
...@@ -251,7 +250,7 @@ struct xfrm_type ...@@ -251,7 +250,7 @@ struct xfrm_type
int (*init_state)(struct xfrm_state *x); int (*init_state)(struct xfrm_state *x);
void (*destructor)(struct xfrm_state *); 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); int (*output)(struct xfrm_state *, struct sk_buff *pskb);
/* Estimate maximal size of result of transformation of a dgram */ /* Estimate maximal size of result of transformation of a dgram */
u32 (*get_max_size)(struct xfrm_state *, int size); u32 (*get_max_size)(struct xfrm_state *, int size);
...@@ -606,25 +605,11 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst) ...@@ -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); 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 struct sec_path
{ {
atomic_t refcnt; atomic_t refcnt;
int len; int len;
struct sec_decap_state x[XFRM_MAX_DEPTH]; struct xfrm_state *xvec[XFRM_MAX_DEPTH];
}; };
static inline struct sec_path * static inline struct sec_path *
......
...@@ -476,8 +476,7 @@ asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, ...@@ -476,8 +476,7 @@ asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
int err; int err;
struct socket *sock; struct socket *sock;
/* SO_SET_REPLACE seems to be the same in all levels */ if (level == SOL_IPV6 && optname == IPT_SO_SET_REPLACE)
if (optname == IPT_SO_SET_REPLACE)
return do_netfilter_replace(fd, level, optname, return do_netfilter_replace(fd, level, optname,
optval, optlen); optval, optlen);
......
...@@ -116,7 +116,7 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -116,7 +116,7 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
return err; 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; int ah_hlen;
struct iphdr *iph; struct iphdr *iph;
......
...@@ -133,7 +133,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -133,7 +133,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
* expensive, so we only support truncated data, which is the recommended * expensive, so we only support truncated data, which is the recommended
* and common case. * 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 iphdr *iph;
struct ip_esp_hdr *esph; struct ip_esp_hdr *esph;
...@@ -208,9 +208,6 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc ...@@ -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 xfrm_encap_tmpl *encap = x->encap;
struct udphdr *uh; struct udphdr *uh;
if (encap->encap_type != decap->decap_type)
goto out;
uh = (struct udphdr *)(iph + 1); uh = (struct udphdr *)(iph + 1);
encap_len = (void*)esph - (void*)uh; encap_len = (void*)esph - (void*)uh;
......
...@@ -81,8 +81,7 @@ static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb) ...@@ -81,8 +81,7 @@ static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb)
return err; return err;
} }
static int ipcomp_input(struct xfrm_state *x, static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
struct xfrm_decap_state *decap, struct sk_buff *skb)
{ {
u8 nexthdr; u8 nexthdr;
int err = 0; int err = 0;
......
...@@ -221,16 +221,6 @@ config IP_NF_MATCH_IPRANGE ...@@ -221,16 +221,6 @@ config IP_NF_MATCH_IPRANGE
To compile it as a module, choose M here. If unsure, say N. 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 config IP_NF_MATCH_TOS
tristate "TOS match support" tristate "TOS match support"
depends on IP_NF_IPTABLES depends on IP_NF_IPTABLES
...@@ -272,12 +262,12 @@ config IP_NF_MATCH_DSCP ...@@ -272,12 +262,12 @@ config IP_NF_MATCH_DSCP
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config IP_NF_MATCH_AH_ESP config IP_NF_MATCH_AH
tristate "AH/ESP match support" tristate "AH match support"
depends on IP_NF_IPTABLES depends on IP_NF_IPTABLES
help help
These two match extensions (`ah' and `esp') allow you to match a This match extension allows you to match a range of SPIs
range of SPIs inside AH or ESP headers of IPSec packets. inside AH header of IPSec packets.
To compile it as a module, choose M here. If unsure, say N. 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 ...@@ -53,13 +53,12 @@ obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
# matches # matches
obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o
obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.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_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_RECENT) += ipt_recent.o obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.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_TTL) += ipt_ttl.o
obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
......
...@@ -1658,7 +1658,7 @@ static void __exit ctnetlink_exit(void) ...@@ -1658,7 +1658,7 @@ static void __exit ctnetlink_exit(void)
printk("ctnetlink: unregistering from nfnetlink.\n"); printk("ctnetlink: unregistering from nfnetlink.\n");
#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS #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); ip_conntrack_unregister_notifier(&ctnl_notifier);
#endif #endif
......
This diff is collapsed.
...@@ -68,7 +68,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) ...@@ -68,7 +68,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
{ {
int err; int err;
u32 spi, seq; u32 spi, seq;
struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH]; struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
struct xfrm_state *x; struct xfrm_state *x;
int xfrm_nr = 0; int xfrm_nr = 0;
int decaps = 0; int decaps = 0;
...@@ -90,14 +90,16 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) ...@@ -90,14 +90,16 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
if (unlikely(x->km.state != XFRM_STATE_VALID)) if (unlikely(x->km.state != XFRM_STATE_VALID))
goto drop_unlock; goto drop_unlock;
if (x->encap->encap_type != encap_type)
goto drop_unlock;
if (x->props.replay_window && xfrm_replay_check(x, seq)) if (x->props.replay_window && xfrm_replay_check(x, seq))
goto drop_unlock; goto drop_unlock;
if (xfrm_state_check_expire(x)) if (xfrm_state_check_expire(x))
goto drop_unlock; goto drop_unlock;
xfrm_vec[xfrm_nr].decap.decap_type = encap_type; if (x->type->input(x, skb))
if (x->type->input(x, &(xfrm_vec[xfrm_nr].decap), skb))
goto drop_unlock; goto drop_unlock;
/* only the first xfrm gets the encap type */ /* only the first xfrm gets the encap type */
...@@ -111,7 +113,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) ...@@ -111,7 +113,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
spin_unlock(&x->lock); spin_unlock(&x->lock);
xfrm_vec[xfrm_nr++].xvec = x; xfrm_vec[xfrm_nr++] = x;
iph = skb->nh.iph; iph = skb->nh.iph;
...@@ -153,7 +155,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) ...@@ -153,7 +155,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH) if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
goto drop; 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->sp->len += xfrm_nr;
nf_reset(skb); nf_reset(skb);
...@@ -184,7 +187,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) ...@@ -184,7 +187,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
xfrm_state_put(x); xfrm_state_put(x);
drop: drop:
while (--xfrm_nr >= 0) while (--xfrm_nr >= 0)
xfrm_state_put(xfrm_vec[xfrm_nr].xvec); xfrm_state_put(xfrm_vec[xfrm_nr]);
kfree_skb(skb); kfree_skb(skb);
return 0; return 0;
......
...@@ -21,7 +21,7 @@ static int ipip_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -21,7 +21,7 @@ static int ipip_output(struct xfrm_state *x, struct sk_buff *skb)
return 0; 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; return 0;
} }
......
...@@ -229,7 +229,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -229,7 +229,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
return err; 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 * Before process AH
......
...@@ -130,7 +130,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -130,7 +130,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
return err; 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 ipv6hdr *iph;
struct ipv6_esp_hdr *esph; struct ipv6_esp_hdr *esph;
......
...@@ -63,7 +63,7 @@ static void **ipcomp6_scratches; ...@@ -63,7 +63,7 @@ static void **ipcomp6_scratches;
static int ipcomp6_scratch_users; static int ipcomp6_scratch_users;
static LIST_HEAD(ipcomp6_tfms_list); 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; int err = 0;
u8 nexthdr = 0; u8 nexthdr = 0;
......
...@@ -87,16 +87,6 @@ config IP6_NF_MATCH_HL ...@@ -87,16 +87,6 @@ config IP6_NF_MATCH_HL
To compile it as a module, choose M here. If unsure, say N. 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 config IP6_NF_MATCH_OWNER
tristate "Owner match support" tristate "Owner match support"
depends on IP6_NF_IPTABLES depends on IP6_NF_IPTABLES
...@@ -115,11 +105,11 @@ config IP6_NF_MATCH_IPV6HEADER ...@@ -115,11 +105,11 @@ config IP6_NF_MATCH_IPV6HEADER
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_AHESP config IP6_NF_MATCH_AH
tristate "AH/ESP match support" tristate "AH match support"
depends on IP6_NF_IPTABLES depends on IP6_NF_IPTABLES
help 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. 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 ...@@ -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_OPTS) += ip6t_hbh.o ip6t_dst.o
obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.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_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_MATCH_OWNER) += ip6t_owner.o
obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
......
/* 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);
/* 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) ...@@ -32,7 +32,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
{ {
int err; int err;
u32 seq; u32 seq;
struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH]; struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
struct xfrm_state *x; struct xfrm_state *x;
int xfrm_nr = 0; int xfrm_nr = 0;
int decaps = 0; int decaps = 0;
...@@ -65,7 +65,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi) ...@@ -65,7 +65,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
if (xfrm_state_check_expire(x)) if (xfrm_state_check_expire(x))
goto drop_unlock; goto drop_unlock;
nexthdr = x->type->input(x, &(xfrm_vec[xfrm_nr].decap), skb); nexthdr = x->type->input(x, skb);
if (nexthdr <= 0) if (nexthdr <= 0)
goto drop_unlock; goto drop_unlock;
...@@ -79,7 +79,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi) ...@@ -79,7 +79,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
spin_unlock(&x->lock); spin_unlock(&x->lock);
xfrm_vec[xfrm_nr++].xvec = x; xfrm_vec[xfrm_nr++] = x;
if (x->props.mode) { /* XXX */ if (x->props.mode) { /* XXX */
if (nexthdr != IPPROTO_IPV6) if (nexthdr != IPPROTO_IPV6)
...@@ -118,7 +118,8 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi) ...@@ -118,7 +118,8 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH) if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
goto drop; 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->sp->len += xfrm_nr;
skb->ip_summed = CHECKSUM_NONE; skb->ip_summed = CHECKSUM_NONE;
...@@ -149,7 +150,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi) ...@@ -149,7 +150,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
xfrm_state_put(x); xfrm_state_put(x);
drop: drop:
while (--xfrm_nr >= 0) while (--xfrm_nr >= 0)
xfrm_state_put(xfrm_vec[xfrm_nr].xvec); xfrm_state_put(xfrm_vec[xfrm_nr]);
kfree_skb(skb); kfree_skb(skb);
return -1; return -1;
} }
......
...@@ -351,7 +351,7 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -351,7 +351,7 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
return 0; 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; return 0;
} }
......
...@@ -231,6 +231,15 @@ config NETFILTER_XT_MATCH_DCCP ...@@ -231,6 +231,15 @@ config NETFILTER_XT_MATCH_DCCP
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 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 config NETFILTER_XT_MATCH_HELPER
tristate '"helper" match support' tristate '"helper" match support'
depends on NETFILTER_XTABLES depends on NETFILTER_XTABLES
...@@ -289,6 +298,16 @@ config NETFILTER_XT_MATCH_POLICY ...@@ -289,6 +298,16 @@ config NETFILTER_XT_MATCH_POLICY
To compile it as a module, choose M here. If unsure, say N. 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 config NETFILTER_XT_MATCH_PHYSDEV
tristate '"physdev" match support' tristate '"physdev" match support'
depends on NETFILTER_XTABLES && BRIDGE_NETFILTER depends on NETFILTER_XTABLES && BRIDGE_NETFILTER
......
...@@ -35,11 +35,13 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o ...@@ -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_CONNMARK) += xt_connmark.o
obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o
obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.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_HELPER) += xt_helper.o
obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o
obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o
obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o
obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.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_POLICY) += xt_policy.o
obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
......
...@@ -1022,7 +1022,7 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[]) ...@@ -1022,7 +1022,7 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[])
return err; return err;
} }
#if defined(CONFIG_IP_NF_CONNTRACK_MARK) #if defined(CONFIG_NF_CONNTRACK_MARK)
if (cda[CTA_MARK-1]) if (cda[CTA_MARK-1])
ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
#endif #endif
...@@ -1062,7 +1062,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[], ...@@ -1062,7 +1062,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
return err; return err;
} }
#if defined(CONFIG_IP_NF_CONNTRACK_MARK) #if defined(CONFIG_NF_CONNTRACK_MARK)
if (cda[CTA_MARK-1]) if (cda[CTA_MARK-1])
ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
#endif #endif
...@@ -1687,7 +1687,7 @@ static void __exit ctnetlink_exit(void) ...@@ -1687,7 +1687,7 @@ static void __exit ctnetlink_exit(void)
printk("ctnetlink: unregistering from nfnetlink.\n"); printk("ctnetlink: unregistering from nfnetlink.\n");
#ifdef CONFIG_NF_CONNTRACK_EVENTS #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); nf_conntrack_unregister_notifier(&ctnl_notifier);
#endif #endif
......
...@@ -38,6 +38,7 @@ struct xt_af { ...@@ -38,6 +38,7 @@ struct xt_af {
struct list_head match; struct list_head match;
struct list_head target; struct list_head target;
struct list_head tables; struct list_head tables;
struct mutex compat_mutex;
}; };
static struct xt_af *xt; static struct xt_af *xt;
...@@ -272,6 +273,54 @@ int xt_check_match(const struct xt_match *match, unsigned short family, ...@@ -272,6 +273,54 @@ int xt_check_match(const struct xt_match *match, unsigned short family,
} }
EXPORT_SYMBOL_GPL(xt_check_match); 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, int xt_check_target(const struct xt_target *target, unsigned short family,
unsigned int size, const char *table, unsigned int hook_mask, unsigned int size, const char *table, unsigned int hook_mask,
unsigned short proto, int inv_proto) unsigned short proto, int inv_proto)
...@@ -301,6 +350,54 @@ int xt_check_target(const struct xt_target *target, unsigned short family, ...@@ -301,6 +350,54 @@ int xt_check_target(const struct xt_target *target, unsigned short family,
} }
EXPORT_SYMBOL_GPL(xt_check_target); 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 *xt_alloc_table_info(unsigned int size)
{ {
struct xt_table_info *newinfo; struct xt_table_info *newinfo;
...@@ -371,6 +468,19 @@ void xt_table_unlock(struct xt_table *table) ...@@ -371,6 +468,19 @@ void xt_table_unlock(struct xt_table *table)
} }
EXPORT_SYMBOL_GPL(xt_table_unlock); 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 * struct xt_table_info *
xt_replace_table(struct xt_table *table, xt_replace_table(struct xt_table *table,
...@@ -671,6 +781,9 @@ static int __init xt_init(void) ...@@ -671,6 +781,9 @@ static int __init xt_init(void)
for (i = 0; i < NPROTO; i++) { for (i = 0; i < NPROTO; i++) {
mutex_init(&xt[i].mutex); 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].target);
INIT_LIST_HEAD(&xt[i].match); INIT_LIST_HEAD(&xt[i].match);
INIT_LIST_HEAD(&xt[i].tables); INIT_LIST_HEAD(&xt[i].tables);
......
...@@ -9,16 +9,22 @@ ...@@ -9,16 +9,22 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/ip.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_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>"); 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) #define duprintf(format, args...) printk(format , ## args)
#else #else
#define duprintf(format, args...) #define duprintf(format, args...)
...@@ -28,11 +34,11 @@ MODULE_DESCRIPTION("iptables ESP SPI match module"); ...@@ -28,11 +34,11 @@ MODULE_DESCRIPTION("iptables ESP SPI match module");
static inline int static inline int
spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert) spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
{ {
int r=0; int r = 0;
duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ', duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
min,spi,max); min, spi, max);
r=(spi >= min && spi <= max) ^ invert; r = (spi >= min && spi <= max) ^ invert;
duprintf(" result %s\n",r? "PASS" : "FAILED"); duprintf(" result %s\n", r ? "PASS" : "FAILED");
return r; return r;
} }
...@@ -47,14 +53,13 @@ match(const struct sk_buff *skb, ...@@ -47,14 +53,13 @@ match(const struct sk_buff *skb,
int *hotdrop) int *hotdrop)
{ {
struct ip_esp_hdr _esp, *eh; struct ip_esp_hdr _esp, *eh;
const struct ipt_esp *espinfo = matchinfo; const struct xt_esp *espinfo = matchinfo;
/* Must not be a fragment. */ /* Must not be a fragment. */
if (offset) if (offset)
return 0; return 0;
eh = skb_header_pointer(skb, protoff, eh = skb_header_pointer(skb, protoff, sizeof(_esp), &_esp);
sizeof(_esp), &_esp);
if (eh == NULL) { if (eh == NULL) {
/* We've been asked to examine this packet, and we /* We've been asked to examine this packet, and we
* can't. Hence, no choice but to drop. * can't. Hence, no choice but to drop.
...@@ -64,9 +69,8 @@ match(const struct sk_buff *skb, ...@@ -64,9 +69,8 @@ match(const struct sk_buff *skb,
return 0; return 0;
} }
return spi_match(espinfo->spis[0], espinfo->spis[1], return spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi),
ntohl(eh->spi), !!(espinfo->invflags & XT_ESP_INV_SPI));
!!(espinfo->invflags & IPT_ESP_INV_SPI));
} }
/* Called when user tries to insert an entry of this type. */ /* Called when user tries to insert an entry of this type. */
...@@ -78,34 +82,55 @@ checkentry(const char *tablename, ...@@ -78,34 +82,55 @@ checkentry(const char *tablename,
unsigned int matchinfosize, unsigned int matchinfosize,
unsigned int hook_mask) unsigned int hook_mask)
{ {
const struct ipt_esp *espinfo = matchinfo; const struct xt_esp *espinfo = matchinfo;
/* Must specify no unknown invflags */ if (espinfo->invflags & ~XT_ESP_INV_MASK) {
if (espinfo->invflags & ~IPT_ESP_INV_MASK) { duprintf("xt_esp: unknown flags %X\n", espinfo->invflags);
duprintf("ipt_esp: unknown flags %X\n", espinfo->invflags);
return 0; return 0;
} }
return 1; return 1;
} }
static struct ipt_match esp_match = { static struct xt_match esp_match = {
.name = "esp", .name = "esp",
.match = match, .family = AF_INET,
.matchsize = sizeof(struct ipt_esp),
.proto = IPPROTO_ESP, .proto = IPPROTO_ESP,
.checkentry = checkentry, .match = &match,
.matchsize = sizeof(struct xt_esp),
.checkentry = &checkentry,
.me = THIS_MODULE, .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_init(xt_esp_init);
module_exit(ipt_esp_fini); module_exit(xt_esp_cleanup);
...@@ -13,13 +13,18 @@ ...@@ -13,13 +13,18 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/udp.h> #include <linux/udp.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/netfilter_ipv4/ipt_multiport.h> #include <linux/netfilter/xt_multiport.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
MODULE_DESCRIPTION("iptables multiple port match module"); MODULE_DESCRIPTION("x_tables multiple port match module");
MODULE_ALIAS("ipt_multiport");
MODULE_ALIAS("ip6t_multiport");
#if 0 #if 0
#define duprintf(format, args...) printk(format , ## args) #define duprintf(format, args...) printk(format , ## args)
...@@ -29,17 +34,15 @@ MODULE_DESCRIPTION("iptables multiple port match module"); ...@@ -29,17 +34,15 @@ MODULE_DESCRIPTION("iptables multiple port match module");
/* Returns 1 if the port is matched by the test, 0 otherwise. */ /* Returns 1 if the port is matched by the test, 0 otherwise. */
static inline int static inline int
ports_match(const u_int16_t *portlist, enum ipt_multiport_flags flags, ports_match(const u_int16_t *portlist, enum xt_multiport_flags flags,
u_int8_t count, u_int16_t src, u_int16_t dst) u_int8_t count, u_int16_t src, u_int16_t dst)
{ {
unsigned int i; unsigned int i;
for (i=0; i<count; i++) { for (i = 0; i < count; i++) {
if (flags != IPT_MULTIPORT_DESTINATION if (flags != XT_MULTIPORT_DESTINATION && portlist[i] == src)
&& portlist[i] == src)
return 1; return 1;
if (flags != IPT_MULTIPORT_SOURCE if (flags != XT_MULTIPORT_SOURCE && portlist[i] == dst)
&& portlist[i] == dst)
return 1; return 1;
} }
...@@ -48,13 +51,13 @@ ports_match(const u_int16_t *portlist, enum ipt_multiport_flags flags, ...@@ -48,13 +51,13 @@ ports_match(const u_int16_t *portlist, enum ipt_multiport_flags flags,
/* Returns 1 if the port is matched by the test, 0 otherwise. */ /* Returns 1 if the port is matched by the test, 0 otherwise. */
static inline int static inline int
ports_match_v1(const struct ipt_multiport_v1 *minfo, ports_match_v1(const struct xt_multiport_v1 *minfo,
u_int16_t src, u_int16_t dst) u_int16_t src, u_int16_t dst)
{ {
unsigned int i; unsigned int i;
u_int16_t s, e; u_int16_t s, e;
for (i=0; i < minfo->count; i++) { for (i = 0; i < minfo->count; i++) {
s = minfo->ports[i]; s = minfo->ports[i];
if (minfo->pflags[i]) { if (minfo->pflags[i]) {
...@@ -62,13 +65,13 @@ ports_match_v1(const struct ipt_multiport_v1 *minfo, ...@@ -62,13 +65,13 @@ ports_match_v1(const struct ipt_multiport_v1 *minfo,
e = minfo->ports[++i]; e = minfo->ports[++i];
duprintf("src or dst matches with %d-%d?\n", s, e); duprintf("src or dst matches with %d-%d?\n", s, e);
if (minfo->flags == IPT_MULTIPORT_SOURCE if (minfo->flags == XT_MULTIPORT_SOURCE
&& src >= s && src <= e) && src >= s && src <= e)
return 1 ^ minfo->invert; return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_DESTINATION if (minfo->flags == XT_MULTIPORT_DESTINATION
&& dst >= s && dst <= e) && dst >= s && dst <= e)
return 1 ^ minfo->invert; return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_EITHER if (minfo->flags == XT_MULTIPORT_EITHER
&& ((dst >= s && dst <= e) && ((dst >= s && dst <= e)
|| (src >= s && src <= e))) || (src >= s && src <= e)))
return 1 ^ minfo->invert; return 1 ^ minfo->invert;
...@@ -76,18 +79,18 @@ ports_match_v1(const struct ipt_multiport_v1 *minfo, ...@@ -76,18 +79,18 @@ ports_match_v1(const struct ipt_multiport_v1 *minfo,
/* exact port matching */ /* exact port matching */
duprintf("src or dst matches with %d?\n", s); duprintf("src or dst matches with %d?\n", s);
if (minfo->flags == IPT_MULTIPORT_SOURCE if (minfo->flags == XT_MULTIPORT_SOURCE
&& src == s) && src == s)
return 1 ^ minfo->invert; return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_DESTINATION if (minfo->flags == XT_MULTIPORT_DESTINATION
&& dst == s) && dst == s)
return 1 ^ minfo->invert; return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_EITHER if (minfo->flags == XT_MULTIPORT_EITHER
&& (src == s || dst == s)) && (src == s || dst == s))
return 1 ^ minfo->invert; return 1 ^ minfo->invert;
} }
} }
return minfo->invert; return minfo->invert;
} }
...@@ -102,19 +105,17 @@ match(const struct sk_buff *skb, ...@@ -102,19 +105,17 @@ match(const struct sk_buff *skb,
int *hotdrop) int *hotdrop)
{ {
u16 _ports[2], *pptr; u16 _ports[2], *pptr;
const struct ipt_multiport *multiinfo = matchinfo; const struct xt_multiport *multiinfo = matchinfo;
if (offset) if (offset)
return 0; return 0;
pptr = skb_header_pointer(skb, protoff, pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports);
sizeof(_ports), _ports);
if (pptr == NULL) { if (pptr == NULL) {
/* We've been asked to examine this packet, and we /* We've been asked to examine this packet, and we
* can't. Hence, no choice but to drop. * can't. Hence, no choice but to drop.
*/ */
duprintf("ipt_multiport:" duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
" Dropping evil offset=0 tinygram.\n");
*hotdrop = 1; *hotdrop = 1;
return 0; return 0;
} }
...@@ -135,19 +136,17 @@ match_v1(const struct sk_buff *skb, ...@@ -135,19 +136,17 @@ match_v1(const struct sk_buff *skb,
int *hotdrop) int *hotdrop)
{ {
u16 _ports[2], *pptr; u16 _ports[2], *pptr;
const struct ipt_multiport_v1 *multiinfo = matchinfo; const struct xt_multiport_v1 *multiinfo = matchinfo;
if (offset) if (offset)
return 0; return 0;
pptr = skb_header_pointer(skb, protoff, pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports);
sizeof(_ports), _ports);
if (pptr == NULL) { if (pptr == NULL) {
/* We've been asked to examine this packet, and we /* We've been asked to examine this packet, and we
* can't. Hence, no choice but to drop. * can't. Hence, no choice but to drop.
*/ */
duprintf("ipt_multiport:" duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
" Dropping evil offset=0 tinygram.\n");
*hotdrop = 1; *hotdrop = 1;
return 0; return 0;
} }
...@@ -155,41 +154,161 @@ match_v1(const struct sk_buff *skb, ...@@ -155,41 +154,161 @@ match_v1(const struct sk_buff *skb,
return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1])); return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1]));
} }
static struct ipt_match multiport_match = { 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", .name = "multiport",
.revision = 0, .revision = 0,
.match = match, .matchsize = sizeof(struct xt_multiport),
.matchsize = sizeof(struct ipt_multiport), .match = &match,
.checkentry = &checkentry6,
.family = AF_INET6,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static struct ipt_match multiport_match_v1 = { static struct xt_match multiport6_match_v1 = {
.name = "multiport", .name = "multiport",
.revision = 1, .revision = 1,
.match = match_v1, .matchsize = sizeof(struct xt_multiport_v1),
.matchsize = sizeof(struct ipt_multiport_v1), .match = &match_v1,
.checkentry = &checkentry6_v1,
.family = AF_INET6,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static int __init ipt_multiport_init(void) static int __init xt_multiport_init(void)
{ {
int err; int ret;
err = ipt_register_match(&multiport_match); ret = xt_register_match(&multiport_match);
if (!err) { if (ret)
err = ipt_register_match(&multiport_match_v1); goto out;
if (err)
ipt_unregister_match(&multiport_match); 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;
return err; 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 ipt_multiport_fini(void) static void __exit xt_multiport_fini(void)
{ {
ipt_unregister_match(&multiport_match); xt_unregister_match(&multiport_match);
ipt_unregister_match(&multiport_match_v1); xt_unregister_match(&multiport_match_v1);
xt_unregister_match(&multiport6_match);
xt_unregister_match(&multiport6_match_v1);
} }
module_init(ipt_multiport_init); module_init(xt_multiport_init);
module_exit(ipt_multiport_fini); module_exit(xt_multiport_fini);
...@@ -71,7 +71,7 @@ match_policy_in(const struct sk_buff *skb, const struct xt_policy_info *info, ...@@ -71,7 +71,7 @@ match_policy_in(const struct sk_buff *skb, const struct xt_policy_info *info,
return 0; return 0;
e = &info->pol[pos]; 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) if (!strict)
return 1; return 1;
} else if (strict) } else if (strict)
......
...@@ -1418,7 +1418,8 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _ ...@@ -1418,7 +1418,8 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _
newfd = sock_alloc_fd(&newfile); newfd = sock_alloc_fd(&newfile);
if (unlikely(newfd < 0)) { if (unlikely(newfd < 0)) {
err = newfd; err = newfd;
goto out_release; sock_release(newsock);
goto out_put;
} }
err = sock_attach_fd(newsock, newfile); err = sock_attach_fd(newsock, newfile);
...@@ -1455,10 +1456,8 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _ ...@@ -1455,10 +1456,8 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _
out: out:
return err; return err;
out_fd: out_fd:
put_filp(newfile); fput(newfile);
put_unused_fd(newfd); put_unused_fd(newfd);
out_release:
sock_release(newsock);
goto out_put; goto out_put;
} }
......
...@@ -18,7 +18,7 @@ void __secpath_destroy(struct sec_path *sp) ...@@ -18,7 +18,7 @@ void __secpath_destroy(struct sec_path *sp)
{ {
int i; int i;
for (i = 0; i < sp->len; 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); kmem_cache_free(secpath_cachep, sp);
} }
EXPORT_SYMBOL(__secpath_destroy); EXPORT_SYMBOL(__secpath_destroy);
...@@ -37,7 +37,7 @@ struct sec_path *secpath_dup(struct sec_path *src) ...@@ -37,7 +37,7 @@ struct sec_path *secpath_dup(struct sec_path *src)
memcpy(sp, src, sizeof(*sp)); memcpy(sp, src, sizeof(*sp));
for (i = 0; i < sp->len; i++) 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); atomic_set(&sp->refcnt, 1);
return sp; return sp;
......
...@@ -943,9 +943,9 @@ xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int start, ...@@ -943,9 +943,9 @@ xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int start,
} else } else
start = -1; start = -1;
for (; idx < sp->len; idx++) { 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; return ++idx;
if (sp->x[idx].xvec->props.mode) if (sp->xvec[idx]->props.mode)
break; break;
} }
return start; return start;
...@@ -968,7 +968,7 @@ EXPORT_SYMBOL(xfrm_decode_session); ...@@ -968,7 +968,7 @@ EXPORT_SYMBOL(xfrm_decode_session);
static inline int secpath_has_tunnel(struct sec_path *sp, int k) static inline int secpath_has_tunnel(struct sec_path *sp, int k)
{ {
for (; k < sp->len; k++) { for (; k < sp->len; k++) {
if (sp->x[k].xvec->props.mode) if (sp->xvec[k]->props.mode)
return 1; return 1;
} }
...@@ -994,8 +994,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, ...@@ -994,8 +994,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
int i; int i;
for (i=skb->sp->len-1; i>=0; i--) { for (i=skb->sp->len-1; i>=0; i--) {
struct sec_decap_state *xvec = &(skb->sp->x[i]); struct xfrm_state *x = skb->sp->xvec[i];
if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family)) if (!xfrm_selector_match(&x->sel, &fl, family))
return 0; return 0;
} }
} }
......
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