2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* Packet matching code.
|
|
|
|
*
|
|
|
|
* Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
|
2005-10-26 07:34:24 +00:00
|
|
|
* Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org>
|
2005-04-16 22:20:36 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
2006-01-11 20:17:47 +00:00
|
|
|
|
|
|
|
#include <linux/capability.h>
|
2005-12-27 04:43:12 +00:00
|
|
|
#include <linux/in.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <linux/skbuff.h>
|
|
|
|
#include <linux/kmod.h>
|
|
|
|
#include <linux/vmalloc.h>
|
|
|
|
#include <linux/netdevice.h>
|
|
|
|
#include <linux/module.h>
|
2006-07-04 02:47:27 +00:00
|
|
|
#include <linux/poison.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <linux/icmpv6.h>
|
|
|
|
#include <net/ipv6.h>
|
|
|
|
#include <asm/uaccess.h>
|
2006-03-21 06:35:41 +00:00
|
|
|
#include <linux/mutex.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <linux/proc_fs.h>
|
2005-10-13 21:41:23 +00:00
|
|
|
#include <linux/cpumask.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
#include <linux/netfilter_ipv6/ip6_tables.h>
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
#include <linux/netfilter/x_tables.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
|
|
|
|
MODULE_DESCRIPTION("IPv6 packet filter");
|
|
|
|
|
|
|
|
/*#define DEBUG_IP_FIREWALL*/
|
|
|
|
/*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */
|
|
|
|
/*#define DEBUG_IP_FIREWALL_USER*/
|
|
|
|
|
|
|
|
#ifdef DEBUG_IP_FIREWALL
|
|
|
|
#define dprintf(format, args...) printk(format , ## args)
|
|
|
|
#else
|
|
|
|
#define dprintf(format, args...)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef DEBUG_IP_FIREWALL_USER
|
|
|
|
#define duprintf(format, args...) printk(format , ## args)
|
|
|
|
#else
|
|
|
|
#define duprintf(format, args...)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_NETFILTER_DEBUG
|
|
|
|
#define IP_NF_ASSERT(x) \
|
|
|
|
do { \
|
|
|
|
if (!(x)) \
|
|
|
|
printk("IP_NF_ASSERT: %s:%s:%u\n", \
|
|
|
|
__FUNCTION__, __FILE__, __LINE__); \
|
|
|
|
} while(0)
|
|
|
|
#else
|
|
|
|
#define IP_NF_ASSERT(x)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* All the better to debug you with... */
|
|
|
|
#define static
|
|
|
|
#define inline
|
|
|
|
#endif
|
|
|
|
|
2005-10-26 07:34:24 +00:00
|
|
|
/*
|
2005-04-16 22:20:36 +00:00
|
|
|
We keep a set of rules for each CPU, so we can avoid write-locking
|
2005-10-26 07:34:24 +00:00
|
|
|
them in the softirq when updating the counters and therefore
|
|
|
|
only need to read-lock in the softirq; doing a write_lock_bh() in user
|
|
|
|
context stops packets coming through and allows user context to read
|
|
|
|
the counters or update the rules.
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
Hence the start of any table is given by get_table() below. */
|
|
|
|
|
|
|
|
/* Check for an extension */
|
2007-02-09 14:24:49 +00:00
|
|
|
int
|
2005-04-16 22:20:36 +00:00
|
|
|
ip6t_ext_hdr(u8 nexthdr)
|
|
|
|
{
|
2007-02-09 14:24:49 +00:00
|
|
|
return ( (nexthdr == IPPROTO_HOPOPTS) ||
|
|
|
|
(nexthdr == IPPROTO_ROUTING) ||
|
|
|
|
(nexthdr == IPPROTO_FRAGMENT) ||
|
|
|
|
(nexthdr == IPPROTO_ESP) ||
|
|
|
|
(nexthdr == IPPROTO_AH) ||
|
|
|
|
(nexthdr == IPPROTO_NONE) ||
|
|
|
|
(nexthdr == IPPROTO_DSTOPTS) );
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns whether matches rule or not. */
|
2007-07-08 05:15:35 +00:00
|
|
|
static inline bool
|
2005-04-16 22:20:36 +00:00
|
|
|
ip6_packet_match(const struct sk_buff *skb,
|
|
|
|
const char *indev,
|
|
|
|
const char *outdev,
|
|
|
|
const struct ip6t_ip6 *ip6info,
|
|
|
|
unsigned int *protoff,
|
2007-07-08 05:15:12 +00:00
|
|
|
int *fragoff, bool *hotdrop)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
unsigned long ret;
|
2007-04-26 00:54:47 +00:00
|
|
|
const struct ipv6hdr *ipv6 = ipv6_hdr(skb);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
#define FWINV(bool,invflg) ((bool) ^ !!(ip6info->invflags & invflg))
|
|
|
|
|
2006-03-21 02:03:16 +00:00
|
|
|
if (FWINV(ipv6_masked_addr_cmp(&ipv6->saddr, &ip6info->smsk,
|
2007-02-09 14:24:49 +00:00
|
|
|
&ip6info->src), IP6T_INV_SRCIP)
|
2006-03-21 02:03:16 +00:00
|
|
|
|| FWINV(ipv6_masked_addr_cmp(&ipv6->daddr, &ip6info->dmsk,
|
2007-02-09 14:24:49 +00:00
|
|
|
&ip6info->dst), IP6T_INV_DSTIP)) {
|
2005-04-16 22:20:36 +00:00
|
|
|
dprintf("Source or dest mismatch.\n");
|
|
|
|
/*
|
|
|
|
dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr,
|
|
|
|
ipinfo->smsk.s_addr, ipinfo->src.s_addr,
|
|
|
|
ipinfo->invflags & IP6T_INV_SRCIP ? " (INV)" : "");
|
|
|
|
dprintf("DST: %u. Mask: %u. Target: %u.%s\n", ip->daddr,
|
|
|
|
ipinfo->dmsk.s_addr, ipinfo->dst.s_addr,
|
|
|
|
ipinfo->invflags & IP6T_INV_DSTIP ? " (INV)" : "");*/
|
2007-07-08 05:15:35 +00:00
|
|
|
return false;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Look for ifname matches; this should unroll nicely. */
|
|
|
|
for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
|
|
|
|
ret |= (((const unsigned long *)indev)[i]
|
|
|
|
^ ((const unsigned long *)ip6info->iniface)[i])
|
|
|
|
& ((const unsigned long *)ip6info->iniface_mask)[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FWINV(ret != 0, IP6T_INV_VIA_IN)) {
|
|
|
|
dprintf("VIA in mismatch (%s vs %s).%s\n",
|
|
|
|
indev, ip6info->iniface,
|
|
|
|
ip6info->invflags&IP6T_INV_VIA_IN ?" (INV)":"");
|
2007-07-08 05:15:35 +00:00
|
|
|
return false;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
|
|
|
|
ret |= (((const unsigned long *)outdev)[i]
|
|
|
|
^ ((const unsigned long *)ip6info->outiface)[i])
|
|
|
|
& ((const unsigned long *)ip6info->outiface_mask)[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FWINV(ret != 0, IP6T_INV_VIA_OUT)) {
|
|
|
|
dprintf("VIA out mismatch (%s vs %s).%s\n",
|
|
|
|
outdev, ip6info->outiface,
|
|
|
|
ip6info->invflags&IP6T_INV_VIA_OUT ?" (INV)":"");
|
2007-07-08 05:15:35 +00:00
|
|
|
return false;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ... might want to do something with class and flowlabel here ... */
|
|
|
|
|
|
|
|
/* look for the desired protocol header */
|
|
|
|
if((ip6info->flags & IP6T_F_PROTO)) {
|
2006-01-05 20:21:16 +00:00
|
|
|
int protohdr;
|
|
|
|
unsigned short _frag_off;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-01-05 20:21:16 +00:00
|
|
|
protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off);
|
2006-10-24 23:14:04 +00:00
|
|
|
if (protohdr < 0) {
|
|
|
|
if (_frag_off == 0)
|
2007-07-08 05:15:12 +00:00
|
|
|
*hotdrop = true;
|
2007-07-08 05:15:35 +00:00
|
|
|
return false;
|
2006-10-24 23:14:04 +00:00
|
|
|
}
|
2006-01-05 20:21:16 +00:00
|
|
|
*fragoff = _frag_off;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
dprintf("Packet protocol %hi ?= %s%hi.\n",
|
2007-02-09 14:24:49 +00:00
|
|
|
protohdr,
|
2005-04-16 22:20:36 +00:00
|
|
|
ip6info->invflags & IP6T_INV_PROTO ? "!":"",
|
|
|
|
ip6info->proto);
|
|
|
|
|
2006-01-05 20:21:16 +00:00
|
|
|
if (ip6info->proto == protohdr) {
|
2005-04-16 22:20:36 +00:00
|
|
|
if(ip6info->invflags & IP6T_INV_PROTO) {
|
2007-07-08 05:15:35 +00:00
|
|
|
return false;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
2007-07-08 05:15:35 +00:00
|
|
|
return true;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We need match for the '-p all', too! */
|
|
|
|
if ((ip6info->proto != 0) &&
|
|
|
|
!(ip6info->invflags & IP6T_INV_PROTO))
|
2007-07-08 05:15:35 +00:00
|
|
|
return false;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
2007-07-08 05:15:35 +00:00
|
|
|
return true;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* should be ip6 safe */
|
2007-07-08 05:16:00 +00:00
|
|
|
static inline bool
|
2005-04-16 22:20:36 +00:00
|
|
|
ip6_checkentry(const struct ip6t_ip6 *ipv6)
|
|
|
|
{
|
|
|
|
if (ipv6->flags & ~IP6T_F_MASK) {
|
|
|
|
duprintf("Unknown flag bits set: %08X\n",
|
|
|
|
ipv6->flags & ~IP6T_F_MASK);
|
2007-07-08 05:16:00 +00:00
|
|
|
return false;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
if (ipv6->invflags & ~IP6T_INV_MASK) {
|
|
|
|
duprintf("Unknown invflag bits set: %08X\n",
|
|
|
|
ipv6->invflags & ~IP6T_INV_MASK);
|
2007-07-08 05:16:00 +00:00
|
|
|
return false;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
2007-07-08 05:16:00 +00:00
|
|
|
return true;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int
|
2007-10-15 07:53:15 +00:00
|
|
|
ip6t_error(struct sk_buff *skb,
|
2005-04-16 22:20:36 +00:00
|
|
|
const struct net_device *in,
|
|
|
|
const struct net_device *out,
|
|
|
|
unsigned int hooknum,
|
2006-03-21 02:02:56 +00:00
|
|
|
const struct xt_target *target,
|
2006-08-22 07:35:47 +00:00
|
|
|
const void *targinfo)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
if (net_ratelimit())
|
|
|
|
printk("ip6_tables: error: `%s'\n", (char *)targinfo);
|
|
|
|
|
|
|
|
return NF_DROP;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline
|
2007-07-08 05:15:35 +00:00
|
|
|
bool do_match(struct ip6t_entry_match *m,
|
|
|
|
const struct sk_buff *skb,
|
|
|
|
const struct net_device *in,
|
|
|
|
const struct net_device *out,
|
|
|
|
int offset,
|
|
|
|
unsigned int protoff,
|
|
|
|
bool *hotdrop)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
/* Stop iteration if it doesn't match */
|
2006-03-21 02:02:15 +00:00
|
|
|
if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data,
|
2005-04-16 22:20:36 +00:00
|
|
|
offset, protoff, hotdrop))
|
2007-07-08 05:15:35 +00:00
|
|
|
return true;
|
2005-04-16 22:20:36 +00:00
|
|
|
else
|
2007-07-08 05:15:35 +00:00
|
|
|
return false;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline struct ip6t_entry *
|
|
|
|
get_entry(void *base, unsigned int offset)
|
|
|
|
{
|
|
|
|
return (struct ip6t_entry *)(base + offset);
|
|
|
|
}
|
|
|
|
|
2007-07-08 05:21:23 +00:00
|
|
|
/* All zeroes == unconditional rule. */
|
|
|
|
static inline int
|
|
|
|
unconditional(const struct ip6t_ip6 *ipv6)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof(*ipv6); i++)
|
|
|
|
if (((char *)ipv6)[i])
|
|
|
|
break;
|
|
|
|
|
|
|
|
return (i == sizeof(*ipv6));
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
|
|
|
|
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
|
|
|
|
/* This cries for unification! */
|
|
|
|
static const char *hooknames[] = {
|
2007-11-20 02:53:30 +00:00
|
|
|
[NF_INET_PRE_ROUTING] = "PREROUTING",
|
|
|
|
[NF_INET_LOCAL_IN] = "INPUT",
|
|
|
|
[NF_INET_FORWARD] = "FORWARD",
|
|
|
|
[NF_INET_LOCAL_OUT] = "OUTPUT",
|
|
|
|
[NF_INET_POST_ROUTING] = "POSTROUTING",
|
2007-07-08 05:21:23 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum nf_ip_trace_comments {
|
|
|
|
NF_IP6_TRACE_COMMENT_RULE,
|
|
|
|
NF_IP6_TRACE_COMMENT_RETURN,
|
|
|
|
NF_IP6_TRACE_COMMENT_POLICY,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *comments[] = {
|
|
|
|
[NF_IP6_TRACE_COMMENT_RULE] = "rule",
|
|
|
|
[NF_IP6_TRACE_COMMENT_RETURN] = "return",
|
|
|
|
[NF_IP6_TRACE_COMMENT_POLICY] = "policy",
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct nf_loginfo trace_loginfo = {
|
|
|
|
.type = NF_LOG_TYPE_LOG,
|
|
|
|
.u = {
|
|
|
|
.log = {
|
|
|
|
.level = 4,
|
|
|
|
.logflags = NF_LOG_MASK,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
|
|
|
|
char *hookname, char **chainname,
|
|
|
|
char **comment, unsigned int *rulenum)
|
|
|
|
{
|
|
|
|
struct ip6t_standard_target *t = (void *)ip6t_get_target(s);
|
|
|
|
|
|
|
|
if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) {
|
|
|
|
/* Head of user chain: ERROR target with chainname */
|
|
|
|
*chainname = t->target.data;
|
|
|
|
(*rulenum) = 0;
|
|
|
|
} else if (s == e) {
|
|
|
|
(*rulenum)++;
|
|
|
|
|
|
|
|
if (s->target_offset == sizeof(struct ip6t_entry)
|
|
|
|
&& strcmp(t->target.u.kernel.target->name,
|
|
|
|
IP6T_STANDARD_TARGET) == 0
|
|
|
|
&& t->verdict < 0
|
|
|
|
&& unconditional(&s->ipv6)) {
|
|
|
|
/* Tail of chains: STANDARD target (return/policy) */
|
|
|
|
*comment = *chainname == hookname
|
|
|
|
? (char *)comments[NF_IP6_TRACE_COMMENT_POLICY]
|
|
|
|
: (char *)comments[NF_IP6_TRACE_COMMENT_RETURN];
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
} else
|
|
|
|
(*rulenum)++;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void trace_packet(struct sk_buff *skb,
|
|
|
|
unsigned int hook,
|
|
|
|
const struct net_device *in,
|
|
|
|
const struct net_device *out,
|
|
|
|
char *tablename,
|
|
|
|
struct xt_table_info *private,
|
|
|
|
struct ip6t_entry *e)
|
|
|
|
{
|
|
|
|
void *table_base;
|
|
|
|
struct ip6t_entry *root;
|
|
|
|
char *hookname, *chainname, *comment;
|
|
|
|
unsigned int rulenum = 0;
|
|
|
|
|
|
|
|
table_base = (void *)private->entries[smp_processor_id()];
|
|
|
|
root = get_entry(table_base, private->hook_entry[hook]);
|
|
|
|
|
|
|
|
hookname = chainname = (char *)hooknames[hook];
|
|
|
|
comment = (char *)comments[NF_IP6_TRACE_COMMENT_RULE];
|
|
|
|
|
|
|
|
IP6T_ENTRY_ITERATE(root,
|
|
|
|
private->size - private->hook_entry[hook],
|
|
|
|
get_chainname_rulenum,
|
|
|
|
e, hookname, &chainname, &comment, &rulenum);
|
|
|
|
|
|
|
|
nf_log_packet(AF_INET6, hook, skb, in, out, &trace_loginfo,
|
|
|
|
"TRACE: %s:%s:%s:%u ",
|
|
|
|
tablename, chainname, comment, rulenum);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* Returns one of the generic firewall policies, like NF_ACCEPT. */
|
|
|
|
unsigned int
|
2007-10-15 07:53:15 +00:00
|
|
|
ip6t_do_table(struct sk_buff *skb,
|
2005-04-16 22:20:36 +00:00
|
|
|
unsigned int hook,
|
|
|
|
const struct net_device *in,
|
|
|
|
const struct net_device *out,
|
2006-08-22 07:35:47 +00:00
|
|
|
struct xt_table *table)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2005-10-26 07:34:24 +00:00
|
|
|
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
|
2005-04-16 22:20:36 +00:00
|
|
|
int offset = 0;
|
|
|
|
unsigned int protoff = 0;
|
2007-07-08 05:15:12 +00:00
|
|
|
bool hotdrop = false;
|
2005-04-16 22:20:36 +00:00
|
|
|
/* Initializing verdict to NF_DROP keeps gcc happy. */
|
|
|
|
unsigned int verdict = NF_DROP;
|
|
|
|
const char *indev, *outdev;
|
|
|
|
void *table_base;
|
|
|
|
struct ip6t_entry *e, *back;
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
struct xt_table_info *private;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* Initialization */
|
|
|
|
indev = in ? in->name : nulldevname;
|
|
|
|
outdev = out ? out->name : nulldevname;
|
|
|
|
/* We handle fragments by dealing with the first fragment as
|
|
|
|
* if it was a normal packet. All other fragments are treated
|
|
|
|
* normally, except that they will NEVER match rules that ask
|
|
|
|
* things we don't know, ie. tcp syn flag or ports). If the
|
|
|
|
* rule is also a fragment-specific rule, non-fragments won't
|
|
|
|
* match it. */
|
|
|
|
|
|
|
|
read_lock_bh(&table->lock);
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
private = table->private;
|
2005-04-16 22:20:36 +00:00
|
|
|
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
table_base = (void *)private->entries[smp_processor_id()];
|
|
|
|
e = get_entry(table_base, private->hook_entry[hook]);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* For return from builtin chain */
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
back = get_entry(table_base, private->underflow[hook]);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
do {
|
|
|
|
IP_NF_ASSERT(e);
|
|
|
|
IP_NF_ASSERT(back);
|
2007-10-15 07:53:15 +00:00
|
|
|
if (ip6_packet_match(skb, indev, outdev, &e->ipv6,
|
2006-10-24 23:14:04 +00:00
|
|
|
&protoff, &offset, &hotdrop)) {
|
2005-04-16 22:20:36 +00:00
|
|
|
struct ip6t_entry_target *t;
|
|
|
|
|
|
|
|
if (IP6T_MATCH_ITERATE(e, do_match,
|
2007-10-15 07:53:15 +00:00
|
|
|
skb, in, out,
|
2005-04-16 22:20:36 +00:00
|
|
|
offset, protoff, &hotdrop) != 0)
|
|
|
|
goto no_match;
|
|
|
|
|
|
|
|
ADD_COUNTER(e->counters,
|
2007-12-18 05:48:02 +00:00
|
|
|
ntohs(ipv6_hdr(skb)->payload_len) +
|
|
|
|
sizeof(struct ipv6hdr), 1);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
t = ip6t_get_target(e);
|
|
|
|
IP_NF_ASSERT(t->u.kernel.target);
|
2007-07-08 05:21:23 +00:00
|
|
|
|
|
|
|
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
|
|
|
|
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
|
|
|
|
/* The packet is traced: log it */
|
2007-10-15 07:53:15 +00:00
|
|
|
if (unlikely(skb->nf_trace))
|
|
|
|
trace_packet(skb, hook, in, out,
|
2007-07-08 05:21:23 +00:00
|
|
|
table->name, private, e);
|
|
|
|
#endif
|
2005-04-16 22:20:36 +00:00
|
|
|
/* Standard target? */
|
|
|
|
if (!t->u.kernel.target->target) {
|
|
|
|
int v;
|
|
|
|
|
|
|
|
v = ((struct ip6t_standard_target *)t)->verdict;
|
|
|
|
if (v < 0) {
|
|
|
|
/* Pop from stack? */
|
|
|
|
if (v != IP6T_RETURN) {
|
|
|
|
verdict = (unsigned)(-v) - 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
e = back;
|
|
|
|
back = get_entry(table_base,
|
|
|
|
back->comefrom);
|
|
|
|
continue;
|
|
|
|
}
|
2005-08-22 06:31:43 +00:00
|
|
|
if (table_base + v != (void *)e + e->next_offset
|
|
|
|
&& !(e->ipv6.flags & IP6T_F_GOTO)) {
|
2005-04-16 22:20:36 +00:00
|
|
|
/* Save old back ptr in next entry */
|
|
|
|
struct ip6t_entry *next
|
|
|
|
= (void *)e + e->next_offset;
|
|
|
|
next->comefrom
|
|
|
|
= (void *)back - table_base;
|
|
|
|
/* set back pointer to next entry */
|
|
|
|
back = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
e = get_entry(table_base, v);
|
|
|
|
} else {
|
|
|
|
/* Targets which reenter must return
|
2007-02-09 14:24:49 +00:00
|
|
|
abs. verdicts */
|
2005-04-16 22:20:36 +00:00
|
|
|
#ifdef CONFIG_NETFILTER_DEBUG
|
|
|
|
((struct ip6t_entry *)table_base)->comefrom
|
|
|
|
= 0xeeeeeeec;
|
|
|
|
#endif
|
2007-10-15 07:53:15 +00:00
|
|
|
verdict = t->u.kernel.target->target(skb,
|
2005-04-16 22:20:36 +00:00
|
|
|
in, out,
|
|
|
|
hook,
|
2006-03-21 02:02:15 +00:00
|
|
|
t->u.kernel.target,
|
2006-08-22 07:35:47 +00:00
|
|
|
t->data);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_NETFILTER_DEBUG
|
|
|
|
if (((struct ip6t_entry *)table_base)->comefrom
|
|
|
|
!= 0xeeeeeeec
|
|
|
|
&& verdict == IP6T_CONTINUE) {
|
|
|
|
printk("Target %s reentered!\n",
|
|
|
|
t->u.kernel.target->name);
|
|
|
|
verdict = NF_DROP;
|
|
|
|
}
|
|
|
|
((struct ip6t_entry *)table_base)->comefrom
|
|
|
|
= 0x57acc001;
|
|
|
|
#endif
|
|
|
|
if (verdict == IP6T_CONTINUE)
|
|
|
|
e = (void *)e + e->next_offset;
|
|
|
|
else
|
|
|
|
/* Verdict */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
no_match:
|
|
|
|
e = (void *)e + e->next_offset;
|
|
|
|
}
|
|
|
|
} while (!hotdrop);
|
|
|
|
|
|
|
|
#ifdef CONFIG_NETFILTER_DEBUG
|
2006-07-04 02:47:27 +00:00
|
|
|
((struct ip6t_entry *)table_base)->comefrom = NETFILTER_LINK_POISON;
|
2005-04-16 22:20:36 +00:00
|
|
|
#endif
|
|
|
|
read_unlock_bh(&table->lock);
|
|
|
|
|
|
|
|
#ifdef DEBUG_ALLOW_ALL
|
|
|
|
return NF_ACCEPT;
|
|
|
|
#else
|
|
|
|
if (hotdrop)
|
|
|
|
return NF_DROP;
|
|
|
|
else return verdict;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Figures out from what hook each rule can be called: returns 0 if
|
|
|
|
there are loops. Puts hook bitmask in comefrom. */
|
|
|
|
static int
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
mark_source_chains(struct xt_table_info *newinfo,
|
2005-12-14 07:13:48 +00:00
|
|
|
unsigned int valid_hooks, void *entry0)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
unsigned int hook;
|
|
|
|
|
|
|
|
/* No recursion; use packet counter to save back ptrs (reset
|
|
|
|
to 0 as we leave), and comefrom to save source hook bitmask */
|
2007-11-20 02:53:30 +00:00
|
|
|
for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) {
|
2005-04-16 22:20:36 +00:00
|
|
|
unsigned int pos = newinfo->hook_entry[hook];
|
|
|
|
struct ip6t_entry *e
|
2005-12-14 07:13:48 +00:00
|
|
|
= (struct ip6t_entry *)(entry0 + pos);
|
2006-12-12 08:29:52 +00:00
|
|
|
int visited = e->comefrom & (1 << hook);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (!(valid_hooks & (1 << hook)))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Set initial back pointer. */
|
|
|
|
e->counters.pcnt = pos;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
struct ip6t_standard_target *t
|
|
|
|
= (void *)ip6t_get_target(e);
|
|
|
|
|
2007-11-20 02:53:30 +00:00
|
|
|
if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
|
2005-04-16 22:20:36 +00:00
|
|
|
printk("iptables: loop hook %u pos %u %08X.\n",
|
|
|
|
hook, pos, e->comefrom);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
e->comefrom
|
2007-11-20 02:53:30 +00:00
|
|
|
|= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* Unconditional return/END. */
|
2006-12-12 08:29:52 +00:00
|
|
|
if ((e->target_offset == sizeof(struct ip6t_entry)
|
2005-04-16 22:20:36 +00:00
|
|
|
&& (strcmp(t->target.u.user.name,
|
|
|
|
IP6T_STANDARD_TARGET) == 0)
|
|
|
|
&& t->verdict < 0
|
2006-12-12 08:29:52 +00:00
|
|
|
&& unconditional(&e->ipv6)) || visited) {
|
2005-04-16 22:20:36 +00:00
|
|
|
unsigned int oldpos, size;
|
|
|
|
|
2006-12-05 21:43:50 +00:00
|
|
|
if (t->verdict < -NF_MAX_VERDICT - 1) {
|
|
|
|
duprintf("mark_source_chains: bad "
|
|
|
|
"negative verdict (%i)\n",
|
|
|
|
t->verdict);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* Return: backtrack through the last
|
|
|
|
big jump. */
|
|
|
|
do {
|
2007-11-20 02:53:30 +00:00
|
|
|
e->comefrom ^= (1<<NF_INET_NUMHOOKS);
|
2005-04-16 22:20:36 +00:00
|
|
|
#ifdef DEBUG_IP_FIREWALL_USER
|
|
|
|
if (e->comefrom
|
2007-11-20 02:53:30 +00:00
|
|
|
& (1 << NF_INET_NUMHOOKS)) {
|
2005-04-16 22:20:36 +00:00
|
|
|
duprintf("Back unset "
|
|
|
|
"on hook %u "
|
|
|
|
"rule %u\n",
|
|
|
|
hook, pos);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
oldpos = pos;
|
|
|
|
pos = e->counters.pcnt;
|
|
|
|
e->counters.pcnt = 0;
|
|
|
|
|
|
|
|
/* We're at the start. */
|
|
|
|
if (pos == oldpos)
|
|
|
|
goto next;
|
|
|
|
|
|
|
|
e = (struct ip6t_entry *)
|
2005-12-14 07:13:48 +00:00
|
|
|
(entry0 + pos);
|
2005-04-16 22:20:36 +00:00
|
|
|
} while (oldpos == pos + e->next_offset);
|
|
|
|
|
|
|
|
/* Move along one */
|
|
|
|
size = e->next_offset;
|
|
|
|
e = (struct ip6t_entry *)
|
2005-12-14 07:13:48 +00:00
|
|
|
(entry0 + pos + size);
|
2005-04-16 22:20:36 +00:00
|
|
|
e->counters.pcnt = pos;
|
|
|
|
pos += size;
|
|
|
|
} else {
|
|
|
|
int newpos = t->verdict;
|
|
|
|
|
|
|
|
if (strcmp(t->target.u.user.name,
|
|
|
|
IP6T_STANDARD_TARGET) == 0
|
|
|
|
&& newpos >= 0) {
|
2006-12-05 21:43:50 +00:00
|
|
|
if (newpos > newinfo->size -
|
|
|
|
sizeof(struct ip6t_entry)) {
|
|
|
|
duprintf("mark_source_chains: "
|
|
|
|
"bad verdict (%i)\n",
|
|
|
|
newpos);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
/* This a jump; chase it. */
|
|
|
|
duprintf("Jump rule %u -> %u\n",
|
|
|
|
pos, newpos);
|
|
|
|
} else {
|
|
|
|
/* ... this is a fallthru */
|
|
|
|
newpos = pos + e->next_offset;
|
|
|
|
}
|
|
|
|
e = (struct ip6t_entry *)
|
2005-12-14 07:13:48 +00:00
|
|
|
(entry0 + newpos);
|
2005-04-16 22:20:36 +00:00
|
|
|
e->counters.pcnt = pos;
|
|
|
|
pos = newpos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
next:
|
|
|
|
duprintf("Finished chain %u\n", hook);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
|
|
|
|
{
|
|
|
|
if (i && (*i)-- == 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (m->u.kernel.match->destroy)
|
2006-08-22 07:36:37 +00:00
|
|
|
m->u.kernel.match->destroy(m->u.kernel.match, m->data);
|
2005-04-16 22:20:36 +00:00
|
|
|
module_put(m->u.kernel.match->me);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
2007-12-18 05:48:17 +00:00
|
|
|
check_entry(struct ip6t_entry *e, const char *name)
|
|
|
|
{
|
|
|
|
struct ip6t_entry_target *t;
|
|
|
|
|
|
|
|
if (!ip6_checkentry(&e->ipv6)) {
|
|
|
|
duprintf("ip_tables: ip check failed %p %s.\n", e, name);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e->target_offset + sizeof(struct ip6t_entry_target) >
|
|
|
|
e->next_offset)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
t = ip6t_get_target(e);
|
|
|
|
if (e->target_offset + t->u.target_size > e->next_offset)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int check_match(struct ip6t_entry_match *m, const char *name,
|
|
|
|
const struct ip6t_ip6 *ipv6,
|
|
|
|
unsigned int hookmask, unsigned int *i)
|
|
|
|
{
|
|
|
|
struct xt_match *match;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
match = m->u.kernel.match;
|
|
|
|
ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m),
|
|
|
|
name, hookmask, ipv6->proto,
|
|
|
|
ipv6->invflags & IP6T_INV_PROTO);
|
|
|
|
if (!ret && m->u.kernel.match->checkentry
|
|
|
|
&& !m->u.kernel.match->checkentry(name, ipv6, match, m->data,
|
|
|
|
hookmask)) {
|
|
|
|
duprintf("ip_tables: check failed for `%s'.\n",
|
|
|
|
m->u.kernel.match->name);
|
|
|
|
ret = -EINVAL;
|
|
|
|
}
|
|
|
|
if (!ret)
|
|
|
|
(*i)++;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
find_check_match(struct ip6t_entry_match *m,
|
|
|
|
const char *name,
|
|
|
|
const struct ip6t_ip6 *ipv6,
|
|
|
|
unsigned int hookmask,
|
|
|
|
unsigned int *i)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2007-02-07 23:11:19 +00:00
|
|
|
struct xt_match *match;
|
2006-03-21 02:00:36 +00:00
|
|
|
int ret;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name,
|
2007-02-09 14:24:49 +00:00
|
|
|
m->u.user.revision),
|
2005-10-26 07:34:24 +00:00
|
|
|
"ip6t_%s", m->u.user.name);
|
|
|
|
if (IS_ERR(match) || !match) {
|
2007-12-18 05:48:17 +00:00
|
|
|
duprintf("find_check_match: `%s' not found\n", m->u.user.name);
|
2005-10-26 07:34:24 +00:00
|
|
|
return match ? PTR_ERR(match) : -ENOENT;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
m->u.kernel.match = match;
|
|
|
|
|
2007-12-18 05:48:17 +00:00
|
|
|
ret = check_match(m, name, ipv6, hookmask, i);
|
2006-03-21 02:00:36 +00:00
|
|
|
if (ret)
|
|
|
|
goto err;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
return 0;
|
2006-03-21 02:00:36 +00:00
|
|
|
err:
|
|
|
|
module_put(m->u.kernel.match->me);
|
|
|
|
return ret;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2007-12-18 05:48:17 +00:00
|
|
|
static inline int check_target(struct ip6t_entry *e, const char *name)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
struct ip6t_entry_target *t;
|
2007-02-07 23:11:19 +00:00
|
|
|
struct xt_target *target;
|
2005-04-16 22:20:36 +00:00
|
|
|
int ret;
|
|
|
|
|
2007-12-18 05:48:17 +00:00
|
|
|
t = ip6t_get_target(e);
|
|
|
|
target = t->u.kernel.target;
|
|
|
|
ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t),
|
|
|
|
name, e->comefrom, e->ipv6.proto,
|
|
|
|
e->ipv6.invflags & IP6T_INV_PROTO);
|
|
|
|
if (!ret && t->u.kernel.target->checkentry
|
|
|
|
&& !t->u.kernel.target->checkentry(name, e, target, t->data,
|
|
|
|
e->comefrom)) {
|
|
|
|
duprintf("ip_tables: check failed for `%s'.\n",
|
|
|
|
t->u.kernel.target->name);
|
|
|
|
ret = -EINVAL;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
2007-12-18 05:48:17 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2007-12-18 05:48:17 +00:00
|
|
|
static inline int
|
|
|
|
find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
|
|
|
|
unsigned int *i)
|
|
|
|
{
|
|
|
|
struct ip6t_entry_target *t;
|
|
|
|
struct xt_target *target;
|
|
|
|
int ret;
|
|
|
|
unsigned int j;
|
|
|
|
|
|
|
|
ret = check_entry(e, name);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
[NETFILTER]: Missed and reordered checks in {arp,ip,ip6}_tables
There is a number of issues in parsing user-provided table in
translate_table(). Malicious user with CAP_NET_ADMIN may crash system by
passing special-crafted table to the *_tables.
The first issue is that mark_source_chains() function is called before entry
content checks. In case of standard target, mark_source_chains() function
uses t->verdict field in order to determine new position. But the check, that
this field leads no further, than the table end, is in check_entry(), which
is called later, than mark_source_chains().
The second issue, that there is no check that target_offset points inside
entry. If so, *_ITERATE_MATCH macro will follow further, than the entry
ends. As a result, we'll have oops or memory disclosure.
And the third issue, that there is no check that the target is completely
inside entry. Results are the same, as in previous issue.
Signed-off-by: Dmitry Mishin <dim@openvz.org>
Acked-by: Kirill Korotaev <dev@openvz.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-10-30 23:12:55 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
j = 0;
|
2007-12-18 05:48:17 +00:00
|
|
|
ret = IP6T_MATCH_ITERATE(e, find_check_match, name, &e->ipv6,
|
|
|
|
e->comefrom, &j);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (ret != 0)
|
|
|
|
goto cleanup_matches;
|
|
|
|
|
|
|
|
t = ip6t_get_target(e);
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
target = try_then_request_module(xt_find_target(AF_INET6,
|
|
|
|
t->u.user.name,
|
|
|
|
t->u.user.revision),
|
2005-10-26 07:34:24 +00:00
|
|
|
"ip6t_%s", t->u.user.name);
|
|
|
|
if (IS_ERR(target) || !target) {
|
2007-12-18 05:48:17 +00:00
|
|
|
duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
|
2005-10-26 07:34:24 +00:00
|
|
|
ret = target ? PTR_ERR(target) : -ENOENT;
|
2005-04-16 22:20:36 +00:00
|
|
|
goto cleanup_matches;
|
|
|
|
}
|
|
|
|
t->u.kernel.target = target;
|
2005-10-26 07:34:24 +00:00
|
|
|
|
2007-12-18 05:48:17 +00:00
|
|
|
ret = check_target(e, name);
|
2006-03-21 02:00:36 +00:00
|
|
|
if (ret)
|
|
|
|
goto err;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
(*i)++;
|
|
|
|
return 0;
|
2006-03-21 02:00:36 +00:00
|
|
|
err:
|
|
|
|
module_put(t->u.kernel.target->me);
|
2005-04-16 22:20:36 +00:00
|
|
|
cleanup_matches:
|
|
|
|
IP6T_MATCH_ITERATE(e, cleanup_match, &j);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
check_entry_size_and_hooks(struct ip6t_entry *e,
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
struct xt_table_info *newinfo,
|
2005-04-16 22:20:36 +00:00
|
|
|
unsigned char *base,
|
|
|
|
unsigned char *limit,
|
|
|
|
const unsigned int *hook_entries,
|
|
|
|
const unsigned int *underflows,
|
|
|
|
unsigned int *i)
|
|
|
|
{
|
|
|
|
unsigned int h;
|
|
|
|
|
|
|
|
if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0
|
|
|
|
|| (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) {
|
|
|
|
duprintf("Bad offset %p\n", e);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e->next_offset
|
|
|
|
< sizeof(struct ip6t_entry) + sizeof(struct ip6t_entry_target)) {
|
|
|
|
duprintf("checking: element %p size %u\n",
|
|
|
|
e, e->next_offset);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check hooks & underflows */
|
2007-11-20 02:53:30 +00:00
|
|
|
for (h = 0; h < NF_INET_NUMHOOKS; h++) {
|
2005-04-16 22:20:36 +00:00
|
|
|
if ((unsigned char *)e - base == hook_entries[h])
|
|
|
|
newinfo->hook_entry[h] = hook_entries[h];
|
|
|
|
if ((unsigned char *)e - base == underflows[h])
|
|
|
|
newinfo->underflow[h] = underflows[h];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: underflows must be unconditional, standard verdicts
|
2007-02-09 14:24:49 +00:00
|
|
|
< 0 (not IP6T_RETURN). --RR */
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* Clear counters and comefrom */
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
e->counters = ((struct xt_counters) { 0, 0 });
|
2005-04-16 22:20:36 +00:00
|
|
|
e->comefrom = 0;
|
|
|
|
|
|
|
|
(*i)++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
cleanup_entry(struct ip6t_entry *e, unsigned int *i)
|
|
|
|
{
|
|
|
|
struct ip6t_entry_target *t;
|
|
|
|
|
|
|
|
if (i && (*i)-- == 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
/* Cleanup all matches */
|
|
|
|
IP6T_MATCH_ITERATE(e, cleanup_match, NULL);
|
|
|
|
t = ip6t_get_target(e);
|
|
|
|
if (t->u.kernel.target->destroy)
|
2006-08-22 07:36:37 +00:00
|
|
|
t->u.kernel.target->destroy(t->u.kernel.target, t->data);
|
2005-04-16 22:20:36 +00:00
|
|
|
module_put(t->u.kernel.target->me);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Checks and translates the user-supplied table segment (held in
|
|
|
|
newinfo) */
|
|
|
|
static int
|
|
|
|
translate_table(const char *name,
|
|
|
|
unsigned int valid_hooks,
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
struct xt_table_info *newinfo,
|
2005-12-14 07:13:48 +00:00
|
|
|
void *entry0,
|
2005-04-16 22:20:36 +00:00
|
|
|
unsigned int size,
|
|
|
|
unsigned int number,
|
|
|
|
const unsigned int *hook_entries,
|
|
|
|
const unsigned int *underflows)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
newinfo->size = size;
|
|
|
|
newinfo->number = number;
|
|
|
|
|
|
|
|
/* Init all hooks to impossible value. */
|
2007-11-20 02:53:30 +00:00
|
|
|
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
|
2005-04-16 22:20:36 +00:00
|
|
|
newinfo->hook_entry[i] = 0xFFFFFFFF;
|
|
|
|
newinfo->underflow[i] = 0xFFFFFFFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
duprintf("translate_table: size %u\n", newinfo->size);
|
|
|
|
i = 0;
|
|
|
|
/* Walk through entries, checking offsets. */
|
2005-12-14 07:13:48 +00:00
|
|
|
ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
|
2005-04-16 22:20:36 +00:00
|
|
|
check_entry_size_and_hooks,
|
|
|
|
newinfo,
|
2005-12-14 07:13:48 +00:00
|
|
|
entry0,
|
|
|
|
entry0 + size,
|
2005-04-16 22:20:36 +00:00
|
|
|
hook_entries, underflows, &i);
|
|
|
|
if (ret != 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (i != number) {
|
|
|
|
duprintf("translate_table: %u not %u entries\n",
|
|
|
|
i, number);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check hooks all assigned */
|
2007-11-20 02:53:30 +00:00
|
|
|
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
|
2005-04-16 22:20:36 +00:00
|
|
|
/* Only hooks which are valid */
|
|
|
|
if (!(valid_hooks & (1 << i)))
|
|
|
|
continue;
|
|
|
|
if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
|
|
|
|
duprintf("Invalid hook entry %u %u\n",
|
|
|
|
i, hook_entries[i]);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
if (newinfo->underflow[i] == 0xFFFFFFFF) {
|
|
|
|
duprintf("Invalid underflow %u %u\n",
|
|
|
|
i, underflows[i]);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-12-05 21:43:50 +00:00
|
|
|
if (!mark_source_chains(newinfo, valid_hooks, entry0))
|
|
|
|
return -ELOOP;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* Finally, each sanity check must pass */
|
|
|
|
i = 0;
|
2005-12-14 07:13:48 +00:00
|
|
|
ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
|
2007-12-18 05:48:17 +00:00
|
|
|
find_check_entry, name, size, &i);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-12-05 21:43:50 +00:00
|
|
|
if (ret != 0) {
|
|
|
|
IP6T_ENTRY_ITERATE(entry0, newinfo->size,
|
|
|
|
cleanup_entry, &i);
|
|
|
|
return ret;
|
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* And one copy for every other CPU */
|
2006-04-11 05:52:50 +00:00
|
|
|
for_each_possible_cpu(i) {
|
2005-12-14 07:13:48 +00:00
|
|
|
if (newinfo->entries[i] && newinfo->entries[i] != entry0)
|
|
|
|
memcpy(newinfo->entries[i], entry0, newinfo->size);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
[NETFILTER]: Missed and reordered checks in {arp,ip,ip6}_tables
There is a number of issues in parsing user-provided table in
translate_table(). Malicious user with CAP_NET_ADMIN may crash system by
passing special-crafted table to the *_tables.
The first issue is that mark_source_chains() function is called before entry
content checks. In case of standard target, mark_source_chains() function
uses t->verdict field in order to determine new position. But the check, that
this field leads no further, than the table end, is in check_entry(), which
is called later, than mark_source_chains().
The second issue, that there is no check that target_offset points inside
entry. If so, *_ITERATE_MATCH macro will follow further, than the entry
ends. As a result, we'll have oops or memory disclosure.
And the third issue, that there is no check that the target is completely
inside entry. Results are the same, as in previous issue.
Signed-off-by: Dmitry Mishin <dim@openvz.org>
Acked-by: Kirill Korotaev <dev@openvz.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-10-30 23:12:55 +00:00
|
|
|
return 0;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Gets counters. */
|
|
|
|
static inline int
|
|
|
|
add_entry_to_counter(const struct ip6t_entry *e,
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
struct xt_counters total[],
|
2005-04-16 22:20:36 +00:00
|
|
|
unsigned int *i)
|
|
|
|
{
|
|
|
|
ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
|
|
|
|
|
|
|
|
(*i)++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-12-14 07:13:48 +00:00
|
|
|
static inline int
|
|
|
|
set_entry_to_counter(const struct ip6t_entry *e,
|
|
|
|
struct ip6t_counters total[],
|
|
|
|
unsigned int *i)
|
|
|
|
{
|
|
|
|
SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
|
|
|
|
|
|
|
|
(*i)++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
static void
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
get_counters(const struct xt_table_info *t,
|
|
|
|
struct xt_counters counters[])
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
unsigned int cpu;
|
|
|
|
unsigned int i;
|
2005-12-14 07:13:48 +00:00
|
|
|
unsigned int curcpu;
|
|
|
|
|
|
|
|
/* Instead of clearing (by a previous call to memset())
|
|
|
|
* the counters and using adds, we set the counters
|
|
|
|
* with data used by 'current' CPU
|
|
|
|
* We dont care about preemption here.
|
|
|
|
*/
|
|
|
|
curcpu = raw_smp_processor_id();
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
IP6T_ENTRY_ITERATE(t->entries[curcpu],
|
|
|
|
t->size,
|
|
|
|
set_entry_to_counter,
|
|
|
|
counters,
|
|
|
|
&i);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-04-11 05:52:50 +00:00
|
|
|
for_each_possible_cpu(cpu) {
|
2005-12-14 07:13:48 +00:00
|
|
|
if (cpu == curcpu)
|
|
|
|
continue;
|
2005-04-16 22:20:36 +00:00
|
|
|
i = 0;
|
2005-12-14 07:13:48 +00:00
|
|
|
IP6T_ENTRY_ITERATE(t->entries[cpu],
|
2005-04-16 22:20:36 +00:00
|
|
|
t->size,
|
|
|
|
add_entry_to_counter,
|
|
|
|
counters,
|
|
|
|
&i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-18 05:49:51 +00:00
|
|
|
static inline struct xt_counters *alloc_counters(struct xt_table *table)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2007-12-18 05:49:51 +00:00
|
|
|
unsigned int countersize;
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
struct xt_counters *counters;
|
|
|
|
struct xt_table_info *private = table->private;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* We need atomic snapshot of counters: rest doesn't change
|
|
|
|
(other than comefrom, which userspace doesn't care
|
|
|
|
about). */
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
countersize = sizeof(struct xt_counters) * private->number;
|
2007-12-18 05:48:33 +00:00
|
|
|
counters = vmalloc_node(countersize, numa_node_id());
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (counters == NULL)
|
2007-12-18 05:49:51 +00:00
|
|
|
return ERR_PTR(-ENOMEM);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* First, sum counters... */
|
|
|
|
write_lock_bh(&table->lock);
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
get_counters(private, counters);
|
2005-04-16 22:20:36 +00:00
|
|
|
write_unlock_bh(&table->lock);
|
|
|
|
|
2007-12-18 05:49:51 +00:00
|
|
|
return counters;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
copy_entries_to_user(unsigned int total_size,
|
|
|
|
struct xt_table *table,
|
|
|
|
void __user *userptr)
|
|
|
|
{
|
|
|
|
unsigned int off, num;
|
|
|
|
struct ip6t_entry *e;
|
|
|
|
struct xt_counters *counters;
|
|
|
|
struct xt_table_info *private = table->private;
|
|
|
|
int ret = 0;
|
|
|
|
void *loc_cpu_entry;
|
|
|
|
|
|
|
|
counters = alloc_counters(table);
|
|
|
|
if (IS_ERR(counters))
|
|
|
|
return PTR_ERR(counters);
|
|
|
|
|
2005-12-14 07:13:48 +00:00
|
|
|
/* choose the copy that is on ourc node/cpu */
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
loc_cpu_entry = private->entries[raw_smp_processor_id()];
|
2005-12-14 07:13:48 +00:00
|
|
|
if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
|
2005-04-16 22:20:36 +00:00
|
|
|
ret = -EFAULT;
|
|
|
|
goto free_counters;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: use iterator macros --RR */
|
|
|
|
/* ... then go back and fix counters and names */
|
|
|
|
for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
|
|
|
|
unsigned int i;
|
|
|
|
struct ip6t_entry_match *m;
|
|
|
|
struct ip6t_entry_target *t;
|
|
|
|
|
2005-12-14 07:13:48 +00:00
|
|
|
e = (struct ip6t_entry *)(loc_cpu_entry + off);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (copy_to_user(userptr + off
|
|
|
|
+ offsetof(struct ip6t_entry, counters),
|
|
|
|
&counters[num],
|
|
|
|
sizeof(counters[num])) != 0) {
|
|
|
|
ret = -EFAULT;
|
|
|
|
goto free_counters;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = sizeof(struct ip6t_entry);
|
|
|
|
i < e->target_offset;
|
|
|
|
i += m->u.match_size) {
|
|
|
|
m = (void *)e + i;
|
|
|
|
|
|
|
|
if (copy_to_user(userptr + off + i
|
|
|
|
+ offsetof(struct ip6t_entry_match,
|
|
|
|
u.user.name),
|
|
|
|
m->u.kernel.match->name,
|
|
|
|
strlen(m->u.kernel.match->name)+1)
|
|
|
|
!= 0) {
|
|
|
|
ret = -EFAULT;
|
|
|
|
goto free_counters;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
t = ip6t_get_target(e);
|
|
|
|
if (copy_to_user(userptr + off + e->target_offset
|
|
|
|
+ offsetof(struct ip6t_entry_target,
|
|
|
|
u.user.name),
|
|
|
|
t->u.kernel.target->name,
|
|
|
|
strlen(t->u.kernel.target->name)+1) != 0) {
|
|
|
|
ret = -EFAULT;
|
|
|
|
goto free_counters;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
free_counters:
|
|
|
|
vfree(counters);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2007-12-18 05:50:05 +00:00
|
|
|
static int get_info(void __user *user, int *len)
|
|
|
|
{
|
|
|
|
char name[IP6T_TABLE_MAXNAMELEN];
|
|
|
|
struct xt_table *t;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (*len != sizeof(struct ip6t_getinfo)) {
|
|
|
|
duprintf("length %u != %u\n", *len,
|
|
|
|
sizeof(struct ip6t_getinfo));
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (copy_from_user(name, user, sizeof(name)) != 0)
|
|
|
|
return -EFAULT;
|
|
|
|
|
|
|
|
name[IP6T_TABLE_MAXNAMELEN-1] = '\0';
|
|
|
|
|
|
|
|
t = try_then_request_module(xt_find_table_lock(AF_INET6, name),
|
|
|
|
"ip6table_%s", name);
|
|
|
|
if (t && !IS_ERR(t)) {
|
|
|
|
struct ip6t_getinfo info;
|
|
|
|
struct xt_table_info *private = t->private;
|
|
|
|
|
|
|
|
info.valid_hooks = t->valid_hooks;
|
|
|
|
memcpy(info.hook_entry, private->hook_entry,
|
|
|
|
sizeof(info.hook_entry));
|
|
|
|
memcpy(info.underflow, private->underflow,
|
|
|
|
sizeof(info.underflow));
|
|
|
|
info.num_entries = private->number;
|
|
|
|
info.size = private->size;
|
|
|
|
memcpy(info.name, name, sizeof(info.name));
|
|
|
|
|
|
|
|
if (copy_to_user(user, &info, *len) != 0)
|
|
|
|
ret = -EFAULT;
|
|
|
|
else
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
xt_table_unlock(t);
|
|
|
|
module_put(t->me);
|
|
|
|
} else
|
|
|
|
ret = t ? PTR_ERR(t) : -ENOENT;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
static int
|
|
|
|
get_entries(const struct ip6t_get_entries *entries,
|
|
|
|
struct ip6t_get_entries __user *uptr)
|
|
|
|
{
|
|
|
|
int ret;
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
struct xt_table *t;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
t = xt_find_table_lock(AF_INET6, entries->name);
|
2005-10-26 07:34:24 +00:00
|
|
|
if (t && !IS_ERR(t)) {
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
struct xt_table_info *private = t->private;
|
|
|
|
duprintf("t->private->number = %u\n", private->number);
|
|
|
|
if (entries->size == private->size)
|
|
|
|
ret = copy_entries_to_user(private->size,
|
2005-04-16 22:20:36 +00:00
|
|
|
t, uptr->entrytable);
|
|
|
|
else {
|
|
|
|
duprintf("get_entries: I've got %u not %u!\n",
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
private->size, entries->size);
|
2005-04-16 22:20:36 +00:00
|
|
|
ret = -EINVAL;
|
|
|
|
}
|
2005-10-26 07:34:24 +00:00
|
|
|
module_put(t->me);
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
xt_table_unlock(t);
|
2005-04-16 22:20:36 +00:00
|
|
|
} else
|
2005-10-26 07:34:24 +00:00
|
|
|
ret = t ? PTR_ERR(t) : -ENOENT;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_replace(void __user *user, unsigned int len)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct ip6t_replace tmp;
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
struct xt_table *t;
|
|
|
|
struct xt_table_info *newinfo, *oldinfo;
|
|
|
|
struct xt_counters *counters;
|
2005-12-14 07:13:48 +00:00
|
|
|
void *loc_cpu_entry, *loc_cpu_old_entry;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
|
|
|
|
return -EFAULT;
|
|
|
|
|
2006-02-04 10:16:56 +00:00
|
|
|
/* overflow check */
|
|
|
|
if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
|
|
|
|
return -ENOMEM;
|
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
newinfo = xt_alloc_table_info(tmp.size);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (!newinfo)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2005-12-14 07:13:48 +00:00
|
|
|
/* choose the copy that is on our node/cpu */
|
|
|
|
loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
|
|
|
|
if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
|
2005-04-16 22:20:36 +00:00
|
|
|
tmp.size) != 0) {
|
|
|
|
ret = -EFAULT;
|
|
|
|
goto free_newinfo;
|
|
|
|
}
|
|
|
|
|
2007-12-18 05:48:33 +00:00
|
|
|
counters = vmalloc_node(tmp.num_counters * sizeof(struct xt_counters),
|
|
|
|
numa_node_id());
|
2005-04-16 22:20:36 +00:00
|
|
|
if (!counters) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto free_newinfo;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = translate_table(tmp.name, tmp.valid_hooks,
|
2005-12-14 07:13:48 +00:00
|
|
|
newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
|
2005-04-16 22:20:36 +00:00
|
|
|
tmp.hook_entry, tmp.underflow);
|
|
|
|
if (ret != 0)
|
|
|
|
goto free_newinfo_counters;
|
|
|
|
|
|
|
|
duprintf("ip_tables: Translated table\n");
|
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
t = try_then_request_module(xt_find_table_lock(AF_INET6, tmp.name),
|
2005-10-26 07:34:24 +00:00
|
|
|
"ip6table_%s", tmp.name);
|
|
|
|
if (!t || IS_ERR(t)) {
|
|
|
|
ret = t ? PTR_ERR(t) : -ENOENT;
|
2005-04-16 22:20:36 +00:00
|
|
|
goto free_newinfo_counters_untrans;
|
2005-10-26 07:34:24 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* You lied! */
|
|
|
|
if (tmp.valid_hooks != t->valid_hooks) {
|
|
|
|
duprintf("Valid hook crap: %08X vs %08X\n",
|
|
|
|
tmp.valid_hooks, t->valid_hooks);
|
|
|
|
ret = -EINVAL;
|
2005-10-26 07:34:24 +00:00
|
|
|
goto put_module;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (!oldinfo)
|
|
|
|
goto put_module;
|
|
|
|
|
|
|
|
/* Update module usage count based on number of rules */
|
|
|
|
duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n",
|
|
|
|
oldinfo->number, oldinfo->initial_entries, newinfo->number);
|
2007-02-09 14:24:49 +00:00
|
|
|
if ((oldinfo->number > oldinfo->initial_entries) ||
|
|
|
|
(newinfo->number <= oldinfo->initial_entries))
|
2005-04-16 22:20:36 +00:00
|
|
|
module_put(t->me);
|
|
|
|
if ((oldinfo->number > oldinfo->initial_entries) &&
|
|
|
|
(newinfo->number <= oldinfo->initial_entries))
|
|
|
|
module_put(t->me);
|
|
|
|
|
|
|
|
/* Get the old counters. */
|
|
|
|
get_counters(oldinfo, counters);
|
|
|
|
/* Decrease module usage counts and free resource */
|
2005-12-14 07:13:48 +00:00
|
|
|
loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
|
|
|
|
IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
xt_free_table_info(oldinfo);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (copy_to_user(tmp.counters, counters,
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
sizeof(struct xt_counters) * tmp.num_counters) != 0)
|
2005-04-16 22:20:36 +00:00
|
|
|
ret = -EFAULT;
|
|
|
|
vfree(counters);
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
xt_table_unlock(t);
|
2005-04-16 22:20:36 +00:00
|
|
|
return ret;
|
|
|
|
|
|
|
|
put_module:
|
|
|
|
module_put(t->me);
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
xt_table_unlock(t);
|
2005-04-16 22:20:36 +00:00
|
|
|
free_newinfo_counters_untrans:
|
2005-12-14 07:13:48 +00:00
|
|
|
IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL);
|
2005-04-16 22:20:36 +00:00
|
|
|
free_newinfo_counters:
|
|
|
|
vfree(counters);
|
|
|
|
free_newinfo:
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
xt_free_table_info(newinfo);
|
2005-04-16 22:20:36 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We're lazy, and add to the first CPU; overflow works its fey magic
|
|
|
|
* and everything is OK. */
|
|
|
|
static inline int
|
|
|
|
add_counter_to_entry(struct ip6t_entry *e,
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
const struct xt_counters addme[],
|
2005-04-16 22:20:36 +00:00
|
|
|
unsigned int *i)
|
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
duprintf("add_counter: Entry %u %lu/%lu + %lu/%lu\n",
|
|
|
|
*i,
|
|
|
|
(long unsigned int)e->counters.pcnt,
|
|
|
|
(long unsigned int)e->counters.bcnt,
|
|
|
|
(long unsigned int)addme[*i].pcnt,
|
|
|
|
(long unsigned int)addme[*i].bcnt);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt);
|
|
|
|
|
|
|
|
(*i)++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_add_counters(void __user *user, unsigned int len)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
struct xt_counters_info tmp, *paddc;
|
|
|
|
struct xt_table_info *private;
|
|
|
|
struct xt_table *t;
|
2005-10-26 07:34:24 +00:00
|
|
|
int ret = 0;
|
2005-12-14 07:13:48 +00:00
|
|
|
void *loc_cpu_entry;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
|
|
|
|
return -EFAULT;
|
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters))
|
2005-04-16 22:20:36 +00:00
|
|
|
return -EINVAL;
|
|
|
|
|
2007-12-18 05:48:33 +00:00
|
|
|
paddc = vmalloc_node(len, numa_node_id());
|
2005-04-16 22:20:36 +00:00
|
|
|
if (!paddc)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
if (copy_from_user(paddc, user, len) != 0) {
|
|
|
|
ret = -EFAULT;
|
|
|
|
goto free;
|
|
|
|
}
|
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
t = xt_find_table_lock(AF_INET6, tmp.name);
|
2005-10-26 07:34:24 +00:00
|
|
|
if (!t || IS_ERR(t)) {
|
|
|
|
ret = t ? PTR_ERR(t) : -ENOENT;
|
2005-04-16 22:20:36 +00:00
|
|
|
goto free;
|
2005-10-26 07:34:24 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
write_lock_bh(&t->lock);
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
private = t->private;
|
2006-05-19 09:16:52 +00:00
|
|
|
if (private->number != tmp.num_counters) {
|
2005-04-16 22:20:36 +00:00
|
|
|
ret = -EINVAL;
|
|
|
|
goto unlock_up_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = 0;
|
2005-12-14 07:13:48 +00:00
|
|
|
/* Choose the copy that is on our node */
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
loc_cpu_entry = private->entries[smp_processor_id()];
|
2005-12-14 07:13:48 +00:00
|
|
|
IP6T_ENTRY_ITERATE(loc_cpu_entry,
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
private->size,
|
2005-04-16 22:20:36 +00:00
|
|
|
add_counter_to_entry,
|
|
|
|
paddc->counters,
|
|
|
|
&i);
|
|
|
|
unlock_up_free:
|
|
|
|
write_unlock_bh(&t->lock);
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
xt_table_unlock(t);
|
2005-10-26 07:34:24 +00:00
|
|
|
module_put(t->me);
|
2005-04-16 22:20:36 +00:00
|
|
|
free:
|
|
|
|
vfree(paddc);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!capable(CAP_NET_ADMIN))
|
|
|
|
return -EPERM;
|
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
case IP6T_SO_SET_REPLACE:
|
|
|
|
ret = do_replace(user, len);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IP6T_SO_SET_ADD_COUNTERS:
|
|
|
|
ret = do_add_counters(user, len);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
duprintf("do_ip6t_set_ctl: unknown request %i\n", cmd);
|
|
|
|
ret = -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!capable(CAP_NET_ADMIN))
|
|
|
|
return -EPERM;
|
|
|
|
|
|
|
|
switch (cmd) {
|
2007-12-18 05:50:05 +00:00
|
|
|
case IP6T_SO_GET_INFO:
|
|
|
|
ret = get_info(user, len);
|
|
|
|
break;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
case IP6T_SO_GET_ENTRIES: {
|
|
|
|
struct ip6t_get_entries get;
|
|
|
|
|
|
|
|
if (*len < sizeof(get)) {
|
|
|
|
duprintf("get_entries: %u < %u\n", *len, sizeof(get));
|
|
|
|
ret = -EINVAL;
|
|
|
|
} else if (copy_from_user(&get, user, sizeof(get)) != 0) {
|
|
|
|
ret = -EFAULT;
|
|
|
|
} else if (*len != sizeof(struct ip6t_get_entries) + get.size) {
|
|
|
|
duprintf("get_entries: %u != %u\n", *len,
|
|
|
|
sizeof(struct ip6t_get_entries) + get.size);
|
|
|
|
ret = -EINVAL;
|
|
|
|
} else
|
|
|
|
ret = get_entries(&get, user);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-10-26 07:34:24 +00:00
|
|
|
case IP6T_SO_GET_REVISION_MATCH:
|
|
|
|
case IP6T_SO_GET_REVISION_TARGET: {
|
|
|
|
struct ip6t_get_revision rev;
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
int target;
|
2005-10-26 07:34:24 +00:00
|
|
|
|
|
|
|
if (*len != sizeof(rev)) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (copy_from_user(&rev, user, sizeof(rev)) != 0) {
|
|
|
|
ret = -EFAULT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cmd == IP6T_SO_GET_REVISION_TARGET)
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
target = 1;
|
2005-10-26 07:34:24 +00:00
|
|
|
else
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
target = 0;
|
2005-10-26 07:34:24 +00:00
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
try_then_request_module(xt_find_revision(AF_INET6, rev.name,
|
|
|
|
rev.revision,
|
|
|
|
target, &ret),
|
2005-10-26 07:34:24 +00:00
|
|
|
"ip6t_%s", rev.name);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
default:
|
|
|
|
duprintf("do_ip6t_get_ctl: unknown request %i\n", cmd);
|
|
|
|
ret = -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
int ip6t_register_table(struct xt_table *table,
|
2005-04-16 22:20:36 +00:00
|
|
|
const struct ip6t_replace *repl)
|
|
|
|
{
|
|
|
|
int ret;
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
struct xt_table_info *newinfo;
|
2007-12-05 07:24:56 +00:00
|
|
|
struct xt_table_info bootstrap
|
2005-04-16 22:20:36 +00:00
|
|
|
= { 0, 0, 0, { 0 }, { 0 }, { } };
|
2005-12-14 07:13:48 +00:00
|
|
|
void *loc_cpu_entry;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
newinfo = xt_alloc_table_info(repl->size);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (!newinfo)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2005-12-14 07:13:48 +00:00
|
|
|
/* choose the copy on our node/cpu */
|
|
|
|
loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
|
|
|
|
memcpy(loc_cpu_entry, repl->entries, repl->size);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
ret = translate_table(table->name, table->valid_hooks,
|
2005-12-14 07:13:48 +00:00
|
|
|
newinfo, loc_cpu_entry, repl->size,
|
2005-04-16 22:20:36 +00:00
|
|
|
repl->num_entries,
|
|
|
|
repl->hook_entry,
|
|
|
|
repl->underflow);
|
|
|
|
if (ret != 0) {
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
xt_free_table_info(newinfo);
|
2005-04-16 22:20:36 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2006-06-27 10:00:09 +00:00
|
|
|
ret = xt_register_table(table, &bootstrap, newinfo);
|
|
|
|
if (ret != 0) {
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
xt_free_table_info(newinfo);
|
2005-04-16 22:20:36 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
return 0;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
void ip6t_unregister_table(struct xt_table *table)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
struct xt_table_info *private;
|
2005-12-14 07:13:48 +00:00
|
|
|
void *loc_cpu_entry;
|
|
|
|
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
private = xt_unregister_table(table);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* Decrease module usage counts and free resources */
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
loc_cpu_entry = private->entries[raw_smp_processor_id()];
|
|
|
|
IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL);
|
|
|
|
xt_free_table_info(private);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns 1 if the type and code is matched by the range, 0 otherwise */
|
2007-07-08 05:16:00 +00:00
|
|
|
static inline bool
|
2005-04-16 22:20:36 +00:00
|
|
|
icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
|
|
|
|
u_int8_t type, u_int8_t code,
|
2007-07-08 05:16:00 +00:00
|
|
|
bool invert)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
return (type == test_type && code >= min_code && code <= max_code)
|
|
|
|
^ invert;
|
|
|
|
}
|
|
|
|
|
2007-07-08 05:15:35 +00:00
|
|
|
static bool
|
2005-04-16 22:20:36 +00:00
|
|
|
icmp6_match(const struct sk_buff *skb,
|
|
|
|
const struct net_device *in,
|
|
|
|
const struct net_device *out,
|
2006-03-21 02:02:56 +00:00
|
|
|
const struct xt_match *match,
|
2005-04-16 22:20:36 +00:00
|
|
|
const void *matchinfo,
|
|
|
|
int offset,
|
|
|
|
unsigned int protoff,
|
2007-07-08 05:15:12 +00:00
|
|
|
bool *hotdrop)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
struct icmp6hdr _icmp, *ic;
|
|
|
|
const struct ip6t_icmp *icmpinfo = matchinfo;
|
|
|
|
|
|
|
|
/* Must not be a fragment. */
|
|
|
|
if (offset)
|
2007-07-08 05:15:35 +00:00
|
|
|
return false;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
ic = skb_header_pointer(skb, protoff, sizeof(_icmp), &_icmp);
|
|
|
|
if (ic == NULL) {
|
|
|
|
/* We've been asked to examine this packet, and we
|
|
|
|
can't. Hence, no choice but to drop. */
|
|
|
|
duprintf("Dropping evil ICMP tinygram.\n");
|
2007-07-08 05:15:12 +00:00
|
|
|
*hotdrop = true;
|
2007-07-08 05:15:35 +00:00
|
|
|
return false;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return icmp6_type_code_match(icmpinfo->type,
|
|
|
|
icmpinfo->code[0],
|
|
|
|
icmpinfo->code[1],
|
|
|
|
ic->icmp6_type, ic->icmp6_code,
|
|
|
|
!!(icmpinfo->invflags&IP6T_ICMP_INV));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Called when user tries to insert an entry of this type. */
|
2007-07-08 05:16:00 +00:00
|
|
|
static bool
|
2005-04-16 22:20:36 +00:00
|
|
|
icmp6_checkentry(const char *tablename,
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
const void *entry,
|
2006-03-21 02:02:56 +00:00
|
|
|
const struct xt_match *match,
|
2005-04-16 22:20:36 +00:00
|
|
|
void *matchinfo,
|
|
|
|
unsigned int hook_mask)
|
|
|
|
{
|
|
|
|
const struct ip6t_icmp *icmpinfo = matchinfo;
|
|
|
|
|
2006-03-21 02:01:43 +00:00
|
|
|
/* Must specify no unknown invflags */
|
|
|
|
return !(icmpinfo->invflags & ~IP6T_ICMP_INV);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* The built-in targets: standard (NULL) and error. */
|
2007-07-08 05:22:02 +00:00
|
|
|
static struct xt_target ip6t_standard_target __read_mostly = {
|
2005-04-16 22:20:36 +00:00
|
|
|
.name = IP6T_STANDARD_TARGET,
|
2006-03-21 02:01:43 +00:00
|
|
|
.targetsize = sizeof(int),
|
2006-03-22 21:55:40 +00:00
|
|
|
.family = AF_INET6,
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2007-07-08 05:22:02 +00:00
|
|
|
static struct xt_target ip6t_error_target __read_mostly = {
|
2005-04-16 22:20:36 +00:00
|
|
|
.name = IP6T_ERROR_TARGET,
|
|
|
|
.target = ip6t_error,
|
2006-03-21 02:01:43 +00:00
|
|
|
.targetsize = IP6T_FUNCTION_MAXNAMELEN,
|
2006-03-22 21:55:40 +00:00
|
|
|
.family = AF_INET6,
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct nf_sockopt_ops ip6t_sockopts = {
|
|
|
|
.pf = PF_INET6,
|
|
|
|
.set_optmin = IP6T_BASE_CTL,
|
|
|
|
.set_optmax = IP6T_SO_SET_MAX+1,
|
|
|
|
.set = do_ip6t_set_ctl,
|
|
|
|
.get_optmin = IP6T_BASE_CTL,
|
|
|
|
.get_optmax = IP6T_SO_GET_MAX+1,
|
|
|
|
.get = do_ip6t_get_ctl,
|
[NETFILTER]: Fix/improve deadlock condition on module removal netfilter
So I've had a deadlock reported to me. I've found that the sequence of
events goes like this:
1) process A (modprobe) runs to remove ip_tables.ko
2) process B (iptables-restore) runs and calls setsockopt on a netfilter socket,
increasing the ip_tables socket_ops use count
3) process A acquires a file lock on the file ip_tables.ko, calls remove_module
in the kernel, which in turn executes the ip_tables module cleanup routine,
which calls nf_unregister_sockopt
4) nf_unregister_sockopt, seeing that the use count is non-zero, puts the
calling process into uninterruptible sleep, expecting the process using the
socket option code to wake it up when it exits the kernel
4) the user of the socket option code (process B) in do_ipt_get_ctl, calls
ipt_find_table_lock, which in this case calls request_module to load
ip_tables_nat.ko
5) request_module forks a copy of modprobe (process C) to load the module and
blocks until modprobe exits.
6) Process C. forked by request_module process the dependencies of
ip_tables_nat.ko, of which ip_tables.ko is one.
7) Process C attempts to lock the request module and all its dependencies, it
blocks when it attempts to lock ip_tables.ko (which was previously locked in
step 3)
Theres not really any great permanent solution to this that I can see, but I've
developed a two part solution that corrects the problem
Part 1) Modifies the nf_sockopt registration code so that, instead of using a
use counter internal to the nf_sockopt_ops structure, we instead use a pointer
to the registering modules owner to do module reference counting when nf_sockopt
calls a modules set/get routine. This prevents the deadlock by preventing set 4
from happening.
Part 2) Enhances the modprobe utilty so that by default it preforms non-blocking
remove operations (the same way rmmod does), and add an option to explicity
request blocking operation. So if you select blocking operation in modprobe you
can still cause the above deadlock, but only if you explicity try (and since
root can do any old stupid thing it would like.... :) ).
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
2007-09-11 09:28:26 +00:00
|
|
|
.owner = THIS_MODULE,
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2007-07-08 05:22:02 +00:00
|
|
|
static struct xt_match icmp6_matchstruct __read_mostly = {
|
2005-04-16 22:20:36 +00:00
|
|
|
.name = "icmp6",
|
|
|
|
.match = &icmp6_match,
|
2006-03-21 02:01:43 +00:00
|
|
|
.matchsize = sizeof(struct ip6t_icmp),
|
|
|
|
.checkentry = icmp6_checkentry,
|
|
|
|
.proto = IPPROTO_ICMPV6,
|
2006-03-22 21:55:40 +00:00
|
|
|
.family = AF_INET6,
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2006-03-29 00:37:06 +00:00
|
|
|
static int __init ip6_tables_init(void)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2006-08-14 01:57:28 +00:00
|
|
|
ret = xt_proto_init(AF_INET6);
|
|
|
|
if (ret < 0)
|
|
|
|
goto err1;
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* Noone else will be downing sem now, so we won't sleep */
|
2006-08-14 01:57:28 +00:00
|
|
|
ret = xt_register_target(&ip6t_standard_target);
|
|
|
|
if (ret < 0)
|
|
|
|
goto err2;
|
|
|
|
ret = xt_register_target(&ip6t_error_target);
|
|
|
|
if (ret < 0)
|
|
|
|
goto err3;
|
|
|
|
ret = xt_register_match(&icmp6_matchstruct);
|
|
|
|
if (ret < 0)
|
|
|
|
goto err4;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* Register setsockopt */
|
|
|
|
ret = nf_register_sockopt(&ip6t_sockopts);
|
2006-08-14 01:57:28 +00:00
|
|
|
if (ret < 0)
|
|
|
|
goto err5;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2007-07-15 03:46:15 +00:00
|
|
|
printk(KERN_INFO "ip6_tables: (C) 2000-2006 Netfilter Core Team\n");
|
2005-04-16 22:20:36 +00:00
|
|
|
return 0;
|
2006-08-14 01:57:28 +00:00
|
|
|
|
|
|
|
err5:
|
|
|
|
xt_unregister_match(&icmp6_matchstruct);
|
|
|
|
err4:
|
|
|
|
xt_unregister_target(&ip6t_error_target);
|
|
|
|
err3:
|
|
|
|
xt_unregister_target(&ip6t_standard_target);
|
|
|
|
err2:
|
|
|
|
xt_proto_fini(AF_INET6);
|
|
|
|
err1:
|
|
|
|
return ret;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2006-03-29 00:37:06 +00:00
|
|
|
static void __exit ip6_tables_fini(void)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
|
|
|
nf_unregister_sockopt(&ip6t_sockopts);
|
2006-03-22 21:55:40 +00:00
|
|
|
xt_unregister_match(&icmp6_matchstruct);
|
|
|
|
xt_unregister_target(&ip6t_error_target);
|
|
|
|
xt_unregister_target(&ip6t_standard_target);
|
[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables
This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.
o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers
Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-01-12 21:30:04 +00:00
|
|
|
xt_proto_fini(AF_INET6);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2005-09-19 22:34:40 +00:00
|
|
|
/*
|
2006-01-05 20:21:16 +00:00
|
|
|
* find the offset to specified header or the protocol number of last header
|
|
|
|
* if target < 0. "last header" is transport protocol header, ESP, or
|
|
|
|
* "No next header".
|
|
|
|
*
|
|
|
|
* If target header is found, its offset is set in *offset and return protocol
|
|
|
|
* number. Otherwise, return -1.
|
|
|
|
*
|
2006-10-24 23:15:10 +00:00
|
|
|
* If the first fragment doesn't contain the final protocol header or
|
|
|
|
* NEXTHDR_NONE it is considered invalid.
|
|
|
|
*
|
2006-01-05 20:21:16 +00:00
|
|
|
* Note that non-1st fragment is special case that "the protocol number
|
|
|
|
* of last header" is "next header" field in Fragment header. In this case,
|
|
|
|
* *offset is meaningless and fragment offset is stored in *fragoff if fragoff
|
|
|
|
* isn't NULL.
|
2005-09-19 22:34:40 +00:00
|
|
|
*
|
|
|
|
*/
|
2006-01-05 20:21:16 +00:00
|
|
|
int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
|
|
|
|
int target, unsigned short *fragoff)
|
2005-09-19 22:34:40 +00:00
|
|
|
{
|
2007-03-20 01:29:03 +00:00
|
|
|
unsigned int start = skb_network_offset(skb) + sizeof(struct ipv6hdr);
|
2007-04-26 00:54:47 +00:00
|
|
|
u8 nexthdr = ipv6_hdr(skb)->nexthdr;
|
2005-09-19 22:34:40 +00:00
|
|
|
unsigned int len = skb->len - start;
|
|
|
|
|
2006-01-05 20:21:16 +00:00
|
|
|
if (fragoff)
|
|
|
|
*fragoff = 0;
|
|
|
|
|
2005-09-19 22:34:40 +00:00
|
|
|
while (nexthdr != target) {
|
|
|
|
struct ipv6_opt_hdr _hdr, *hp;
|
|
|
|
unsigned int hdrlen;
|
|
|
|
|
2006-01-05 20:21:16 +00:00
|
|
|
if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
|
|
|
|
if (target < 0)
|
|
|
|
break;
|
2006-10-24 23:15:10 +00:00
|
|
|
return -ENOENT;
|
2006-01-05 20:21:16 +00:00
|
|
|
}
|
|
|
|
|
2005-09-19 22:34:40 +00:00
|
|
|
hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
|
|
|
|
if (hp == NULL)
|
2006-10-24 23:15:10 +00:00
|
|
|
return -EBADMSG;
|
2005-09-19 22:34:40 +00:00
|
|
|
if (nexthdr == NEXTHDR_FRAGMENT) {
|
2006-11-15 04:56:00 +00:00
|
|
|
unsigned short _frag_off;
|
|
|
|
__be16 *fp;
|
2005-09-19 22:34:40 +00:00
|
|
|
fp = skb_header_pointer(skb,
|
|
|
|
start+offsetof(struct frag_hdr,
|
|
|
|
frag_off),
|
|
|
|
sizeof(_frag_off),
|
|
|
|
&_frag_off);
|
|
|
|
if (fp == NULL)
|
2006-10-24 23:15:10 +00:00
|
|
|
return -EBADMSG;
|
2005-09-19 22:34:40 +00:00
|
|
|
|
2006-01-05 20:21:16 +00:00
|
|
|
_frag_off = ntohs(*fp) & ~0x7;
|
|
|
|
if (_frag_off) {
|
|
|
|
if (target < 0 &&
|
|
|
|
((!ipv6_ext_hdr(hp->nexthdr)) ||
|
2006-11-15 03:49:13 +00:00
|
|
|
hp->nexthdr == NEXTHDR_NONE)) {
|
2006-01-05 20:21:16 +00:00
|
|
|
if (fragoff)
|
|
|
|
*fragoff = _frag_off;
|
|
|
|
return hp->nexthdr;
|
|
|
|
}
|
2006-10-24 23:15:10 +00:00
|
|
|
return -ENOENT;
|
2006-01-05 20:21:16 +00:00
|
|
|
}
|
2005-09-19 22:34:40 +00:00
|
|
|
hdrlen = 8;
|
|
|
|
} else if (nexthdr == NEXTHDR_AUTH)
|
2007-02-09 14:24:49 +00:00
|
|
|
hdrlen = (hp->hdrlen + 2) << 2;
|
2005-09-19 22:34:40 +00:00
|
|
|
else
|
2007-02-09 14:24:49 +00:00
|
|
|
hdrlen = ipv6_optlen(hp);
|
2005-09-19 22:34:40 +00:00
|
|
|
|
|
|
|
nexthdr = hp->nexthdr;
|
|
|
|
len -= hdrlen;
|
|
|
|
start += hdrlen;
|
|
|
|
}
|
|
|
|
|
|
|
|
*offset = start;
|
2006-01-05 20:21:16 +00:00
|
|
|
return nexthdr;
|
2005-09-19 22:34:40 +00:00
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
EXPORT_SYMBOL(ip6t_register_table);
|
|
|
|
EXPORT_SYMBOL(ip6t_unregister_table);
|
|
|
|
EXPORT_SYMBOL(ip6t_do_table);
|
|
|
|
EXPORT_SYMBOL(ip6t_ext_hdr);
|
2005-09-19 22:34:40 +00:00
|
|
|
EXPORT_SYMBOL(ipv6_find_hdr);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-03-29 00:37:06 +00:00
|
|
|
module_init(ip6_tables_init);
|
|
|
|
module_exit(ip6_tables_fini);
|