[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:
committed by
David S. Miller
parent
880b005f29
commit
2e4e6a17af
@ -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
|
||||
|
@ -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
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
@ -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);
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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)))
|
||||
|
@ -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)
|
||||
|
@ -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);
|
@ -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)
|
||||
|
@ -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. */
|
||||
|
@ -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. */
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
Reference in New Issue
Block a user