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)
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 */
#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,
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 */
#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*/
#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*/
#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*/
#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 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
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 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
* 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 @@ static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb)
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
......
This diff is collapsed.
......@@ -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 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
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 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
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 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
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
......
/* 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)
{
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 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
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);
......@@ -13,13 +13,18 @@
#include <linux/types.h>
#include <linux/udp.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_ipv6/ip6_tables.h>
MODULE_LICENSE("GPL");
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
#define duprintf(format, args...) printk(format , ## args)
......@@ -29,17 +34,15 @@ MODULE_DESCRIPTION("iptables multiple port match module");
/* 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,
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 != IPT_MULTIPORT_DESTINATION
&& portlist[i] == src)
for (i = 0; i < count; i++) {
if (flags != XT_MULTIPORT_DESTINATION && portlist[i] == src)
return 1;
if (flags != IPT_MULTIPORT_SOURCE
&& portlist[i] == dst)
if (flags != XT_MULTIPORT_SOURCE && portlist[i] == dst)
return 1;
}
......@@ -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. */
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)
{
unsigned int i;
u_int16_t s, e;
for (i=0; i < minfo->count; i++) {
for (i = 0; i < minfo->count; i++) {
s = minfo->ports[i];
if (minfo->pflags[i]) {
......@@ -62,13 +65,13 @@ ports_match_v1(const struct ipt_multiport_v1 *minfo,
e = minfo->ports[++i];
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)
return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_DESTINATION
if (minfo->flags == XT_MULTIPORT_DESTINATION
&& dst >= s && dst <= e)
return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_EITHER
if (minfo->flags == XT_MULTIPORT_EITHER
&& ((dst >= s && dst <= e)
|| (src >= s && src <= e)))
return 1 ^ minfo->invert;
......@@ -76,18 +79,18 @@ ports_match_v1(const struct ipt_multiport_v1 *minfo,
/* exact port matching */
duprintf("src or dst matches with %d?\n", s);
if (minfo->flags == IPT_MULTIPORT_SOURCE
if (minfo->flags == XT_MULTIPORT_SOURCE
&& src == s)
return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_DESTINATION
if (minfo->flags == XT_MULTIPORT_DESTINATION
&& dst == s)
return 1 ^ minfo->invert;
if (minfo->flags == IPT_MULTIPORT_EITHER
if (minfo->flags == XT_MULTIPORT_EITHER
&& (src == s || dst == s))
return 1 ^ minfo->invert;
}
}
return minfo->invert;
}
......@@ -102,19 +105,17 @@ match(const struct sk_buff *skb,
int *hotdrop)
{
u16 _ports[2], *pptr;
const struct ipt_multiport *multiinfo = matchinfo;
const struct xt_multiport *multiinfo = matchinfo;
if (offset)
return 0;
pptr = skb_header_pointer(skb, protoff,
sizeof(_ports), _ports);
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");
duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
*hotdrop = 1;
return 0;
}
......@@ -135,19 +136,17 @@ match_v1(const struct sk_buff *skb,
int *hotdrop)
{
u16 _ports[2], *pptr;
const struct ipt_multiport_v1 *multiinfo = matchinfo;
const struct xt_multiport_v1 *multiinfo = matchinfo;
if (offset)
return 0;
pptr = skb_header_pointer(skb, protoff,
sizeof(_ports), _ports);
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");
duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
*hotdrop = 1;
return 0;
}
......@@ -155,41 +154,161 @@ match_v1(const struct sk_buff *skb,
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",
.revision = 0,
.match = match,
.matchsize = sizeof(struct ipt_multiport),
.matchsize = sizeof(struct xt_multiport),
.match = &match,
.checkentry = &checkentry6,
.family = AF_INET6,
.me = THIS_MODULE,
};
static struct ipt_match multiport_match_v1 = {
static struct xt_match multiport6_match_v1 = {
.name = "multiport",
.revision = 1,
.match = match_v1,
.matchsize = sizeof(struct ipt_multiport_v1),
.matchsize = sizeof(struct xt_multiport_v1),
.match = &match_v1,
.checkentry = &checkentry6_v1,
.family = AF_INET6,
.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);
if (!err) {
err = ipt_register_match(&multiport_match_v1);
if (err)
ipt_unregister_match(&multiport_match);
}
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;
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);
ipt_unregister_match(&multiport_match_v1);
xt_unregister_match(&multiport_match);
xt_unregister_match(&multiport_match_v1);
xt_unregister_match(&multiport6_match);
xt_unregister_match(&multiport6_match_v1);
}
module_init(ipt_multiport_init);
module_exit(ipt_multiport_fini);
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 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _
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;
}
}
......
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