[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>
This commit is contained in:
Harald Welte
2006-01-12 13:30:04 -08:00
committed by David S. Miller
parent 880b005f29
commit 2e4e6a17af
154 changed files with 3614 additions and 4148 deletions

View File

@ -41,6 +41,7 @@ config IP6_NF_QUEUE
config IP6_NF_IPTABLES
tristate "IP6 tables support (required for filtering/masq/NAT)"
depends on NETFILTER_XTABLES
help
ip6tables is a general, extensible packet identification framework.
Currently only the packet filtering and packet mangling subsystem
@ -50,25 +51,6 @@ config IP6_NF_IPTABLES
To compile it as a module, choose M here. If unsure, say N.
# The simple matches.
config IP6_NF_MATCH_LIMIT
tristate "limit match support"
depends on IP6_NF_IPTABLES
help
limit matching allows you to control the rate at which a rule can be
matched: mainly useful in combination with the LOG target ("LOG
target support", below) and to avoid some Denial of Service attacks.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_MAC
tristate "MAC address match support"
depends on IP6_NF_IPTABLES
help
mac matching allows you to match packets based on the source
Ethernet address of the packet.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_RT
tristate "Routing header match support"
depends on IP6_NF_IPTABLES
@ -124,16 +106,6 @@ config IP6_NF_MATCH_OWNER
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_MARK
tristate "netfilter MARK match support"
depends on IP6_NF_IPTABLES
help
Netfilter mark matching allows you to match packets based on the
`nfmark' value in the packet. This can be set by the MARK target
(see below).
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_IPV6HEADER
tristate "IPv6 Extension Headers Match"
depends on IP6_NF_IPTABLES
@ -151,15 +123,6 @@ config IP6_NF_MATCH_AHESP
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_LENGTH
tristate "Packet Length match support"
depends on IP6_NF_IPTABLES
help
This option allows you to match the length of a packet against a
specific value or range of values.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_EUI64
tristate "EUI64 address check"
depends on IP6_NF_IPTABLES
@ -170,15 +133,6 @@ config IP6_NF_MATCH_EUI64
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_PHYSDEV
tristate "Physdev match support"
depends on IP6_NF_IPTABLES && BRIDGE_NETFILTER
help
Physdev packet matching matches against the physical bridge ports
the IP packet arrived on or will leave by.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_POLICY
tristate "IPsec policy match support"
depends on IP6_NF_IPTABLES && XFRM
@ -219,17 +173,6 @@ config IP6_NF_TARGET_REJECT
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_TARGET_NFQUEUE
tristate "NFQUEUE Target Support"
depends on IP6_NF_IPTABLES
help
This Target replaced the old obsolete QUEUE target.
As opposed to QUEUE, it supports 65535 different queues,
not just one.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MANGLE
tristate "Packet mangling"
depends on IP6_NF_IPTABLES
@ -240,19 +183,6 @@ config IP6_NF_MANGLE
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_TARGET_MARK
tristate "MARK target support"
depends on IP6_NF_MANGLE
help
This option adds a `MARK' target, which allows you to create rules
in the `mangle' table which alter the netfilter mark (nfmark) field
associated with the packet packet prior to routing. This can change
the routing method (see `Use netfilter MARK value as routing
key') and can also be used by other subsystems to change their
behavior.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_TARGET_HL
tristate 'HL (hoplimit) target support'
depends on IP6_NF_MANGLE

View File

@ -4,10 +4,7 @@
# Link order matters here.
obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o
obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o
obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
@ -17,12 +14,9 @@ obj-$(CONFIG_IP6_NF_MATCH_POLICY) += ip6t_policy.o
obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o
obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
obj-$(CONFIG_IP6_NF_MATCH_PHYSDEV) += ip6t_physdev.o
obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
obj-$(CONFIG_IP6_NF_TARGET_NFQUEUE) += ip6t_NFQUEUE.o
obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o

File diff suppressed because it is too large Load Diff

View File

@ -62,7 +62,7 @@ static unsigned int ip6t_hl_target(struct sk_buff **pskb,
}
static int ip6t_hl_checkentry(const char *tablename,
const struct ip6t_entry *e,
const void *entry,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)

View File

@ -444,7 +444,7 @@ ip6t_log_target(struct sk_buff **pskb,
static int ip6t_log_checkentry(const char *tablename,
const struct ip6t_entry *e,
const void *entry,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)

View File

@ -1,81 +0,0 @@
/* This is a module which is used for setting the NFMARK field of an skb. */
/* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <net/checksum.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_ipv6/ip6t_MARK.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
static unsigned int
target(struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
const struct ip6t_mark_target_info *markinfo = targinfo;
if((*pskb)->nfmark != markinfo->mark)
(*pskb)->nfmark = markinfo->mark;
return IP6T_CONTINUE;
}
static int
checkentry(const char *tablename,
const struct ip6t_entry *e,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)
{
if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))) {
printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
targinfosize,
IP6T_ALIGN(sizeof(struct ip6t_mark_target_info)));
return 0;
}
if (strcmp(tablename, "mangle") != 0) {
printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
return 0;
}
return 1;
}
static struct ip6t_target ip6t_mark_reg = {
.name = "MARK",
.target = target,
.checkentry = checkentry,
.me = THIS_MODULE
};
static int __init init(void)
{
printk(KERN_DEBUG "registering ipv6 mark target\n");
if (ip6t_register_target(&ip6t_mark_reg))
return -EINVAL;
return 0;
}
static void __exit fini(void)
{
ip6t_unregister_target(&ip6t_mark_reg);
}
module_init(init);
module_exit(fini);

View File

@ -1,70 +0,0 @@
/* ip6tables module for using new netfilter netlink queue
*
* (C) 2005 by Harald Welte <laforge@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_ipv4/ipt_NFQUEUE.h>
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
MODULE_DESCRIPTION("ip6tables NFQUEUE target");
MODULE_LICENSE("GPL");
static unsigned int
target(struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userinfo)
{
const struct ipt_NFQ_info *tinfo = targinfo;
return NF_QUEUE_NR(tinfo->queuenum);
}
static int
checkentry(const char *tablename,
const struct ip6t_entry *e,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)
{
if (targinfosize != IP6T_ALIGN(sizeof(struct ipt_NFQ_info))) {
printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n",
targinfosize,
IP6T_ALIGN(sizeof(struct ipt_NFQ_info)));
return 0;
}
return 1;
}
static struct ip6t_target ipt_NFQ_reg = {
.name = "NFQUEUE",
.target = target,
.checkentry = checkentry,
.me = THIS_MODULE,
};
static int __init init(void)
{
return ip6t_register_target(&ipt_NFQ_reg);
}
static void __exit fini(void)
{
ip6t_unregister_target(&ipt_NFQ_reg);
}
module_init(init);
module_exit(fini);

View File

@ -218,12 +218,13 @@ static unsigned int reject6_target(struct sk_buff **pskb,
}
static int check(const char *tablename,
const struct ip6t_entry *e,
const void *entry,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)
{
const struct ip6t_reject_info *rejinfo = targinfo;
const struct ip6t_entry *e = entry;
if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) {
DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize);

View File

@ -98,7 +98,7 @@ match(const struct sk_buff *skb,
/* Called when user tries to insert an entry of this type. */
static int
checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
const void *entry,
void *matchinfo,
unsigned int matchinfosize,
unsigned int hook_mask)

View File

@ -178,7 +178,7 @@ match(const struct sk_buff *skb,
/* Called when user tries to insert an entry of this type. */
static int
checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
const void *info,
void *matchinfo,
unsigned int matchinfosize,
unsigned int hook_mask)

View File

@ -76,7 +76,7 @@ match(const struct sk_buff *skb,
/* Called when user tries to insert an entry of this type. */
static int
checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
const void *ip,
void *matchinfo,
unsigned int matchinfosize,
unsigned int hook_mask)

View File

@ -62,7 +62,7 @@ match(const struct sk_buff *skb,
static int
ip6t_eui64_checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
const void *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)

View File

@ -115,7 +115,7 @@ match(const struct sk_buff *skb,
/* Called when user tries to insert an entry of this type. */
static int
checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
const void *ip,
void *matchinfo,
unsigned int matchinfosize,
unsigned int hook_mask)

View File

@ -178,7 +178,7 @@ match(const struct sk_buff *skb,
/* Called when user tries to insert an entry of this type. */
static int
checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
const void *entry,
void *matchinfo,
unsigned int matchinfosize,
unsigned int hook_mask)

View File

@ -48,7 +48,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in,
return 0;
}
static int checkentry(const char *tablename, const struct ip6t_ip6 *ip,
static int checkentry(const char *tablename, const void *entry,
void *matchinfo, unsigned int matchsize,
unsigned int hook_mask)
{

View File

@ -124,7 +124,7 @@ ipv6header_match(const struct sk_buff *skb,
static int
ipv6header_checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
const void *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)

View File

@ -1,66 +0,0 @@
/* Length Match - IPv6 Port */
/* (C) 1999-2001 James Morris <jmorros@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv6/ip6t_length.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
MODULE_DESCRIPTION("IPv6 packet length match");
static int
match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
unsigned int protoff,
int *hotdrop)
{
const struct ip6t_length_info *info = matchinfo;
u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr);
return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
}
static int
checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_length_info)))
return 0;
return 1;
}
static struct ip6t_match length_match = {
.name = "length",
.match = &match,
.checkentry = &checkentry,
.me = THIS_MODULE,
};
static int __init init(void)
{
return ip6t_register_match(&length_match);
}
static void __exit fini(void)
{
ip6t_unregister_match(&length_match);
}
module_init(init);
module_exit(fini);

View File

@ -1,147 +0,0 @@
/* Kernel module to control the rate
*
* 2 September 1999: Changed from the target RATE to the match
* `limit', removed logging. Did I mention that
* Alexey is a fucking genius?
* Rusty Russell (rusty@rustcorp.com.au). */
/* (C) 1999 J<>r<EFBFBD>me de Vivie <devivie@info.enserb.u-bordeaux.fr>
* (C) 1999 Herv<72> Eychenne <eychenne@info.enserb.u-bordeaux.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_ipv6/ip6t_limit.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>");
MODULE_DESCRIPTION("rate limiting within ip6tables");
/* The algorithm used is the Simple Token Bucket Filter (TBF)
* see net/sched/sch_tbf.c in the linux source tree
*/
static DEFINE_SPINLOCK(limit_lock);
/* Rusty: This is my (non-mathematically-inclined) understanding of
this algorithm. The `average rate' in jiffies becomes your initial
amount of credit `credit' and the most credit you can ever have
`credit_cap'. The `peak rate' becomes the cost of passing the
test, `cost'.
`prev' tracks the last packet hit: you gain one credit per jiffy.
If you get credit balance more than this, the extra credit is
discarded. Every time the match passes, you lose `cost' credits;
if you don't have that many, the test fails.
See Alexey's formal explanation in net/sched/sch_tbf.c.
To avoid underflow, we multiply by 128 (ie. you get 128 credits per
jiffy). Hence a cost of 2^32-1, means one pass per 32768 seconds
at 1024HZ (or one every 9 hours). A cost of 1 means 12800 passes
per second at 100HZ. */
#define CREDITS_PER_JIFFY 128
static int
ip6t_limit_match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
unsigned int protoff,
int *hotdrop)
{
struct ip6t_rateinfo *r = ((struct ip6t_rateinfo *)matchinfo)->master;
unsigned long now = jiffies;
spin_lock_bh(&limit_lock);
r->credit += (now - xchg(&r->prev, now)) * CREDITS_PER_JIFFY;
if (r->credit > r->credit_cap)
r->credit = r->credit_cap;
if (r->credit >= r->cost) {
/* We're not limited. */
r->credit -= r->cost;
spin_unlock_bh(&limit_lock);
return 1;
}
spin_unlock_bh(&limit_lock);
return 0;
}
/* Precision saver. */
static u_int32_t
user2credits(u_int32_t user)
{
/* If multiplying would overflow... */
if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
/* Divide first. */
return (user / IP6T_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
return (user * HZ * CREDITS_PER_JIFFY) / IP6T_LIMIT_SCALE;
}
static int
ip6t_limit_checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
struct ip6t_rateinfo *r = matchinfo;
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rateinfo)))
return 0;
/* Check for overflow. */
if (r->burst == 0
|| user2credits(r->avg * r->burst) < user2credits(r->avg)) {
printk("Call rusty: overflow in ip6t_limit: %u/%u\n",
r->avg, r->burst);
return 0;
}
/* User avg in seconds * IP6T_LIMIT_SCALE: convert to jiffies *
128. */
r->prev = jiffies;
r->credit = user2credits(r->avg * r->burst); /* Credits full. */
r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */
r->cost = user2credits(r->avg);
/* For SMP, we only want to use one set of counters. */
r->master = r;
return 1;
}
static struct ip6t_match ip6t_limit_reg = {
.name = "limit",
.match = ip6t_limit_match,
.checkentry = ip6t_limit_checkentry,
.me = THIS_MODULE,
};
static int __init init(void)
{
if (ip6t_register_match(&ip6t_limit_reg))
return -EINVAL;
return 0;
}
static void __exit fini(void)
{
ip6t_unregister_match(&ip6t_limit_reg);
}
module_init(init);
module_exit(fini);

View File

@ -1,81 +0,0 @@
/* Kernel module to match MAC address parameters. */
/* (C) 1999-2001 Paul `Rusty' Russell
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/if_ether.h>
#include <linux/etherdevice.h>
#include <linux/netfilter_ipv6/ip6t_mac.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MAC address matching module for IPv6");
MODULE_AUTHOR("Netfilter Core Teaam <coreteam@netfilter.org>");
static int
match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
unsigned int protoff,
int *hotdrop)
{
const struct ip6t_mac_info *info = matchinfo;
/* Is mac pointer valid? */
return (skb->mac.raw >= skb->head
&& (skb->mac.raw + ETH_HLEN) <= skb->data
/* If so, compare... */
&& ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr))
^ info->invert));
}
static int
ip6t_mac_checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
if (hook_mask
& ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN)
| (1 << NF_IP6_FORWARD))) {
printk("ip6t_mac: only valid for PRE_ROUTING, LOCAL_IN or"
" FORWARD\n");
return 0;
}
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mac_info)))
return 0;
return 1;
}
static struct ip6t_match mac_match = {
.name = "mac",
.match = &match,
.checkentry = &ip6t_mac_checkentry,
.me = THIS_MODULE,
};
static int __init init(void)
{
return ip6t_register_match(&mac_match);
}
static void __exit fini(void)
{
ip6t_unregister_match(&mac_match);
}
module_init(init);
module_exit(fini);

View File

@ -1,66 +0,0 @@
/* Kernel module to match NFMARK values. */
/* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv6/ip6t_mark.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
MODULE_DESCRIPTION("ip6tables mark match");
static int
match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
unsigned int protoff,
int *hotdrop)
{
const struct ip6t_mark_info *info = matchinfo;
return ((skb->nfmark & info->mask) == info->mark) ^ info->invert;
}
static int
checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mark_info)))
return 0;
return 1;
}
static struct ip6t_match mark_match = {
.name = "mark",
.match = &match,
.checkentry = &checkentry,
.me = THIS_MODULE,
};
static int __init init(void)
{
return ip6t_register_match(&mark_match);
}
static void __exit fini(void)
{
ip6t_unregister_match(&mark_match);
}
module_init(init);
module_exit(fini);

View File

@ -84,11 +84,12 @@ match(const struct sk_buff *skb,
/* Called when user tries to insert an entry of this type. */
static int
checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
const void *info,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
const struct ip6t_ip6 *ip = info;
const struct ip6t_multiport *multiinfo = matchinfo;
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_multiport)))

View File

@ -53,7 +53,7 @@ match(const struct sk_buff *skb,
static int
checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
const void *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)

View File

@ -1,135 +0,0 @@
/* Kernel module to match the bridge port in and
* out device for IP packets coming into contact with a bridge. */
/* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv6/ip6t_physdev.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_bridge.h>
#define MATCH 1
#define NOMATCH 0
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
MODULE_DESCRIPTION("iptables bridge physical device match module");
static int
match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
unsigned int protoff,
int *hotdrop)
{
int i;
static const char nulldevname[IFNAMSIZ];
const struct ip6t_physdev_info *info = matchinfo;
unsigned int ret;
const char *indev, *outdev;
struct nf_bridge_info *nf_bridge;
/* Not a bridged IP packet or no info available yet:
* LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if
* the destination device will be a bridge. */
if (!(nf_bridge = skb->nf_bridge)) {
/* Return MATCH if the invert flags of the used options are on */
if ((info->bitmask & IP6T_PHYSDEV_OP_BRIDGED) &&
!(info->invert & IP6T_PHYSDEV_OP_BRIDGED))
return NOMATCH;
if ((info->bitmask & IP6T_PHYSDEV_OP_ISIN) &&
!(info->invert & IP6T_PHYSDEV_OP_ISIN))
return NOMATCH;
if ((info->bitmask & IP6T_PHYSDEV_OP_ISOUT) &&
!(info->invert & IP6T_PHYSDEV_OP_ISOUT))
return NOMATCH;
if ((info->bitmask & IP6T_PHYSDEV_OP_IN) &&
!(info->invert & IP6T_PHYSDEV_OP_IN))
return NOMATCH;
if ((info->bitmask & IP6T_PHYSDEV_OP_OUT) &&
!(info->invert & IP6T_PHYSDEV_OP_OUT))
return NOMATCH;
return MATCH;
}
/* This only makes sense in the FORWARD and POSTROUTING chains */
if ((info->bitmask & IP6T_PHYSDEV_OP_BRIDGED) &&
(!!(nf_bridge->mask & BRNF_BRIDGED) ^
!(info->invert & IP6T_PHYSDEV_OP_BRIDGED)))
return NOMATCH;
if ((info->bitmask & IP6T_PHYSDEV_OP_ISIN &&
(!nf_bridge->physindev ^ !!(info->invert & IP6T_PHYSDEV_OP_ISIN))) ||
(info->bitmask & IP6T_PHYSDEV_OP_ISOUT &&
(!nf_bridge->physoutdev ^ !!(info->invert & IP6T_PHYSDEV_OP_ISOUT))))
return NOMATCH;
if (!(info->bitmask & IP6T_PHYSDEV_OP_IN))
goto match_outdev;
indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
ret |= (((const unsigned int *)indev)[i]
^ ((const unsigned int *)info->physindev)[i])
& ((const unsigned int *)info->in_mask)[i];
}
if ((ret == 0) ^ !(info->invert & IP6T_PHYSDEV_OP_IN))
return NOMATCH;
match_outdev:
if (!(info->bitmask & IP6T_PHYSDEV_OP_OUT))
return MATCH;
outdev = nf_bridge->physoutdev ?
nf_bridge->physoutdev->name : nulldevname;
for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
ret |= (((const unsigned int *)outdev)[i]
^ ((const unsigned int *)info->physoutdev)[i])
& ((const unsigned int *)info->out_mask)[i];
}
return (ret != 0) ^ !(info->invert & IP6T_PHYSDEV_OP_OUT);
}
static int
checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
const struct ip6t_physdev_info *info = matchinfo;
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_physdev_info)))
return 0;
if (!(info->bitmask & IP6T_PHYSDEV_OP_MASK) ||
info->bitmask & ~IP6T_PHYSDEV_OP_MASK)
return 0;
return 1;
}
static struct ip6t_match physdev_match = {
.name = "physdev",
.match = &match,
.checkentry = &checkentry,
.me = THIS_MODULE,
};
static int __init init(void)
{
return ip6t_register_match(&physdev_match);
}
static void __exit fini(void)
{
ip6t_unregister_match(&physdev_match);
}
module_init(init);
module_exit(fini);

View File

@ -183,7 +183,7 @@ match(const struct sk_buff *skb,
/* Called when user tries to insert an entry of this type. */
static int
checkentry(const char *tablename,
const struct ip6t_ip6 *ip,
const void *entry,
void *matchinfo,
unsigned int matchinfosize,
unsigned int hook_mask)

View File

@ -97,6 +97,7 @@ static struct ip6t_table packet_filter = {
.valid_hooks = FILTER_VALID_HOOKS,
.lock = RW_LOCK_UNLOCKED,
.me = THIS_MODULE,
.af = AF_INET6,
};
/* The work comes in here from netfilter.c. */

View File

@ -127,6 +127,7 @@ static struct ip6t_table packet_mangler = {
.valid_hooks = MANGLE_VALID_HOOKS,
.lock = RW_LOCK_UNLOCKED,
.me = THIS_MODULE,
.af = AF_INET6,
};
/* The work comes in here from netfilter.c. */

View File

@ -106,11 +106,12 @@ static struct
}
};
static struct ip6t_table packet_raw = {
static struct xt_table packet_raw = {
.name = "raw",
.valid_hooks = RAW_VALID_HOOKS,
.lock = RW_LOCK_UNLOCKED,
.me = THIS_MODULE
.me = THIS_MODULE,
.af = AF_INET6,
};
/* The work comes in here from netfilter.c. */

View File

@ -584,7 +584,7 @@ MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
static int __init init(void)
{
need_nf_conntrack();
need_conntrack();
return init_or_cleanup(1);
}
@ -595,9 +595,3 @@ static void __exit fini(void)
module_init(init);
module_exit(fini);
void need_ip6_conntrack(void)
{
}
EXPORT_SYMBOL(need_ip6_conntrack);

View File

@ -70,8 +70,8 @@ struct nf_ct_frag6_skb_cb
struct nf_ct_frag6_queue
{
struct nf_ct_frag6_queue *next;
struct list_head lru_list; /* lru list member */
struct hlist_node list;
struct list_head lru_list; /* lru list member */
__u32 id; /* fragment id */
struct in6_addr saddr;
@ -90,14 +90,13 @@ struct nf_ct_frag6_queue
#define FIRST_IN 2
#define LAST_IN 1
__u16 nhoffset;
struct nf_ct_frag6_queue **pprev;
};
/* Hash table. */
#define FRAG6Q_HASHSZ 64
static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ];
static struct hlist_head nf_ct_frag6_hash[FRAG6Q_HASHSZ];
static DEFINE_RWLOCK(nf_ct_frag6_lock);
static u32 nf_ct_frag6_hash_rnd;
static LIST_HEAD(nf_ct_frag6_lru_list);
@ -105,9 +104,7 @@ int nf_ct_frag6_nqueues = 0;
static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq)
{
if (fq->next)
fq->next->pprev = fq->pprev;
*fq->pprev = fq->next;
hlist_del(&fq->list);
list_del(&fq->lru_list);
nf_ct_frag6_nqueues--;
}
@ -158,28 +155,18 @@ static void nf_ct_frag6_secret_rebuild(unsigned long dummy)
get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32));
for (i = 0; i < FRAG6Q_HASHSZ; i++) {
struct nf_ct_frag6_queue *q;
struct hlist_node *p, *n;
q = nf_ct_frag6_hash[i];
while (q) {
struct nf_ct_frag6_queue *next = q->next;
hlist_for_each_entry_safe(q, p, n, &nf_ct_frag6_hash[i], list) {
unsigned int hval = ip6qhashfn(q->id,
&q->saddr,
&q->daddr);
if (hval != i) {
/* Unlink. */
if (q->next)
q->next->pprev = q->pprev;
*q->pprev = q->next;
hlist_del(&q->list);
/* Relink to new hash chain. */
if ((q->next = nf_ct_frag6_hash[hval]) != NULL)
q->next->pprev = &q->next;
nf_ct_frag6_hash[hval] = q;
q->pprev = &nf_ct_frag6_hash[hval];
hlist_add_head(&q->list,
&nf_ct_frag6_hash[hval]);
}
q = next;
}
}
write_unlock(&nf_ct_frag6_lock);
@ -314,15 +301,17 @@ out:
/* Creation primitives. */
static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
struct nf_ct_frag6_queue *fq_in)
{
struct nf_ct_frag6_queue *fq;
#ifdef CONFIG_SMP
struct hlist_node *n;
#endif
write_lock(&nf_ct_frag6_lock);
#ifdef CONFIG_SMP
for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) {
hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) {
if (fq->id == fq_in->id &&
!ipv6_addr_cmp(&fq_in->saddr, &fq->saddr) &&
!ipv6_addr_cmp(&fq_in->daddr, &fq->daddr)) {
@ -340,10 +329,7 @@ static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
atomic_inc(&fq->refcnt);
atomic_inc(&fq->refcnt);
if ((fq->next = nf_ct_frag6_hash[hash]) != NULL)
fq->next->pprev = &fq->next;
nf_ct_frag6_hash[hash] = fq;
fq->pprev = &nf_ct_frag6_hash[hash];
hlist_add_head(&fq->list, &nf_ct_frag6_hash[hash]);
INIT_LIST_HEAD(&fq->lru_list);
list_add_tail(&fq->lru_list, &nf_ct_frag6_lru_list);
nf_ct_frag6_nqueues++;
@ -384,10 +370,11 @@ static __inline__ struct nf_ct_frag6_queue *
fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst)
{
struct nf_ct_frag6_queue *fq;
struct hlist_node *n;
unsigned int hash = ip6qhashfn(id, src, dst);
read_lock(&nf_ct_frag6_lock);
for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) {
hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) {
if (fq->id == id &&
!ipv6_addr_cmp(src, &fq->saddr) &&
!ipv6_addr_cmp(dst, &fq->daddr)) {