Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6

This commit is contained in:
David S. Miller 2010-05-10 23:03:26 -07:00
commit d250fe91ae
154 changed files with 2032 additions and 2113 deletions

View File

@ -49,7 +49,7 @@ o oprofile 0.9 # oprofiled --version
o udev 081 # udevinfo -V o udev 081 # udevinfo -V
o grub 0.93 # grub --version o grub 0.93 # grub --version
o mcelog 0.6 o mcelog 0.6
o iptables 1.4.1 # iptables -V o iptables 1.4.2 # iptables -V
Kernel compilation Kernel compilation

View File

@ -241,16 +241,6 @@ Who: Thomas Gleixner <tglx@linutronix.de>
--------------------------- ---------------------------
What (Why):
- xt_recent: the old ipt_recent proc dir
(superseded by /proc/net/xt_recent)
When: January 2009 or Linux 2.7.0, whichever comes first
Why: Superseded by newer revisions or modules
Who: Jan Engelhardt <jengelh@computergmbh.de>
---------------------------
What: GPIO autorequest on gpio_direction_{input,output}() in gpiolib What: GPIO autorequest on gpio_direction_{input,output}() in gpiolib
When: February 2010 When: February 2010
Why: All callers should use explicit gpio_request()/gpio_free(). Why: All callers should use explicit gpio_request()/gpio_free().
@ -628,3 +618,11 @@ Why: Internal alias support has been present in module-init-tools for some
with no impact. with no impact.
Who: Wey-Yi Guy <wey-yi.w.guy@intel.com> Who: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---------------------------
What: xt_NOTRACK
Files: net/netfilter/xt_NOTRACK.c
When: April 2011
Why: Superseded by xt_CT
Who: Netfilter developer team <netfilter-devel@vger.kernel.org>

View File

@ -254,6 +254,7 @@ struct inet6_skb_parm {
#define IP6SKB_XFRM_TRANSFORMED 1 #define IP6SKB_XFRM_TRANSFORMED 1
#define IP6SKB_FORWARDED 2 #define IP6SKB_FORWARDED 2
#define IP6SKB_REROUTED 4
}; };
#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb)) #define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))

View File

@ -4,6 +4,8 @@
/* /*
* 'kernel.h' contains some often-used function prototypes etc * 'kernel.h' contains some often-used function prototypes etc
*/ */
#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)
#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
#ifdef __KERNEL__ #ifdef __KERNEL__
@ -37,8 +39,8 @@ extern const char linux_proc_banner[];
#define STACK_MAGIC 0xdeadbeef #define STACK_MAGIC 0xdeadbeef
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) #define ALIGN(x, a) __ALIGN_KERNEL((x), (a))
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) #define __ALIGN_MASK(x, mask) __ALIGN_KERNEL_MASK((x), (mask))
#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) #define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)

View File

@ -16,6 +16,7 @@ header-y += xt_RATEEST.h
header-y += xt_SECMARK.h header-y += xt_SECMARK.h
header-y += xt_TCPMSS.h header-y += xt_TCPMSS.h
header-y += xt_TCPOPTSTRIP.h header-y += xt_TCPOPTSTRIP.h
header-y += xt_TEE.h
header-y += xt_TPROXY.h header-y += xt_TPROXY.h
header-y += xt_comment.h header-y += xt_comment.h
header-y += xt_connbytes.h header-y += xt_connbytes.h

View File

@ -113,6 +113,7 @@ struct ip_conntrack_stat {
unsigned int expect_new; unsigned int expect_new;
unsigned int expect_create; unsigned int expect_create;
unsigned int expect_delete; unsigned int expect_delete;
unsigned int search_restart;
}; };
/* call to create an explicit dependency on nf_conntrack. */ /* call to create an explicit dependency on nf_conntrack. */

View File

@ -1,8 +1,7 @@
#ifndef _NF_CONNTRACK_TUPLE_COMMON_H #ifndef _NF_CONNTRACK_TUPLE_COMMON_H
#define _NF_CONNTRACK_TUPLE_COMMON_H #define _NF_CONNTRACK_TUPLE_COMMON_H
enum ip_conntrack_dir enum ip_conntrack_dir {
{
IP_CT_DIR_ORIGINAL, IP_CT_DIR_ORIGINAL,
IP_CT_DIR_REPLY, IP_CT_DIR_REPLY,
IP_CT_DIR_MAX IP_CT_DIR_MAX

View File

@ -1,9 +1,10 @@
#ifndef _X_TABLES_H #ifndef _X_TABLES_H
#define _X_TABLES_H #define _X_TABLES_H
#include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#define XT_FUNCTION_MAXNAMELEN 30 #define XT_FUNCTION_MAXNAMELEN 30
#define XT_EXTENSION_MAXNAMELEN 29
#define XT_TABLE_MAXNAMELEN 32 #define XT_TABLE_MAXNAMELEN 32
struct xt_entry_match { struct xt_entry_match {
@ -12,8 +13,7 @@ struct xt_entry_match {
__u16 match_size; __u16 match_size;
/* Used by userspace */ /* Used by userspace */
char name[XT_FUNCTION_MAXNAMELEN-1]; char name[XT_EXTENSION_MAXNAMELEN];
__u8 revision; __u8 revision;
} user; } user;
struct { struct {
@ -36,8 +36,7 @@ struct xt_entry_target {
__u16 target_size; __u16 target_size;
/* Used by userspace */ /* Used by userspace */
char name[XT_FUNCTION_MAXNAMELEN-1]; char name[XT_EXTENSION_MAXNAMELEN];
__u8 revision; __u8 revision;
} user; } user;
struct { struct {
@ -70,8 +69,7 @@ struct xt_standard_target {
/* The argument to IPT_SO_GET_REVISION_*. Returns highest revision /* The argument to IPT_SO_GET_REVISION_*. Returns highest revision
* kernel supports, if >= revision. */ * kernel supports, if >= revision. */
struct xt_get_revision { struct xt_get_revision {
char name[XT_FUNCTION_MAXNAMELEN-1]; char name[XT_EXTENSION_MAXNAMELEN];
__u8 revision; __u8 revision;
}; };
@ -93,7 +91,7 @@ struct _xt_align {
__u64 u64; __u64 u64;
}; };
#define XT_ALIGN(s) ALIGN((s), __alignof__(struct _xt_align)) #define XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _xt_align))
/* Standard return verdict, or do jump. */ /* Standard return verdict, or do jump. */
#define XT_STANDARD_TARGET "" #define XT_STANDARD_TARGET ""
@ -197,6 +195,7 @@ struct xt_counters_info {
* @family: Actual NFPROTO_* through which the function is invoked * @family: Actual NFPROTO_* through which the function is invoked
* (helpful when match->family == NFPROTO_UNSPEC) * (helpful when match->family == NFPROTO_UNSPEC)
* @hotdrop: drop packet if we had inspection problems * @hotdrop: drop packet if we had inspection problems
* Network namespace obtainable using dev_net(in/out)
*/ */
struct xt_match_param { struct xt_match_param {
const struct net_device *in, *out; const struct net_device *in, *out;
@ -213,12 +212,14 @@ struct xt_match_param {
* struct xt_mtchk_param - parameters for match extensions' * struct xt_mtchk_param - parameters for match extensions'
* checkentry functions * checkentry functions
* *
* @net: network namespace through which the check was invoked
* @table: table the rule is tried to be inserted into * @table: table the rule is tried to be inserted into
* @entryinfo: the family-specific rule data * @entryinfo: the family-specific rule data
* (struct ipt_ip, ip6t_ip, ebt_entry) * (struct ipt_ip, ip6t_ip, arpt_arp or (note) ebt_entry)
* @match: struct xt_match through which this function was invoked * @match: struct xt_match through which this function was invoked
* @matchinfo: per-match data * @matchinfo: per-match data
* @hook_mask: via which hooks the new rule is reachable * @hook_mask: via which hooks the new rule is reachable
* Other fields as above.
*/ */
struct xt_mtchk_param { struct xt_mtchk_param {
struct net *net; struct net *net;
@ -230,7 +231,10 @@ struct xt_mtchk_param {
u_int8_t family; u_int8_t family;
}; };
/* Match destructor parameters */ /**
* struct xt_mdtor_param - match destructor parameters
* Fields as above.
*/
struct xt_mtdtor_param { struct xt_mtdtor_param {
struct net *net; struct net *net;
const struct xt_match *match; const struct xt_match *match;
@ -285,7 +289,7 @@ struct xt_tgdtor_param {
struct xt_match { struct xt_match {
struct list_head list; struct list_head list;
const char name[XT_FUNCTION_MAXNAMELEN-1]; const char name[XT_EXTENSION_MAXNAMELEN];
u_int8_t revision; u_int8_t revision;
/* Return true or false: return FALSE and set *hotdrop = 1 to /* Return true or false: return FALSE and set *hotdrop = 1 to
@ -297,7 +301,7 @@ struct xt_match {
const struct xt_match_param *); const struct xt_match_param *);
/* Called when user tries to insert an entry of this type. */ /* Called when user tries to insert an entry of this type. */
bool (*checkentry)(const struct xt_mtchk_param *); int (*checkentry)(const struct xt_mtchk_param *);
/* Called when entry of this type deleted. */ /* Called when entry of this type deleted. */
void (*destroy)(const struct xt_mtdtor_param *); void (*destroy)(const struct xt_mtdtor_param *);
@ -309,9 +313,6 @@ struct xt_match {
/* Set this to THIS_MODULE if you are a module, otherwise NULL */ /* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me; struct module *me;
/* Free to use by each match */
unsigned long data;
const char *table; const char *table;
unsigned int matchsize; unsigned int matchsize;
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
@ -327,7 +328,8 @@ struct xt_match {
struct xt_target { struct xt_target {
struct list_head list; struct list_head list;
const char name[XT_FUNCTION_MAXNAMELEN-1]; const char name[XT_EXTENSION_MAXNAMELEN];
u_int8_t revision;
/* Returns verdict. Argument order changed since 2.6.9, as this /* Returns verdict. Argument order changed since 2.6.9, as this
must now handle non-linear skbs, using skb_copy_bits and must now handle non-linear skbs, using skb_copy_bits and
@ -338,8 +340,8 @@ struct xt_target {
/* Called when user tries to insert an entry of this type: /* Called when user tries to insert an entry of this type:
hook_mask is a bitmask of hooks from which it can be hook_mask is a bitmask of hooks from which it can be
called. */ called. */
/* Should return true or false. */ /* Should return true or false, or an error code (-Exxxx). */
bool (*checkentry)(const struct xt_tgchk_param *); int (*checkentry)(const struct xt_tgchk_param *);
/* Called when entry of this type deleted. */ /* Called when entry of this type deleted. */
void (*destroy)(const struct xt_tgdtor_param *); void (*destroy)(const struct xt_tgdtor_param *);
@ -360,7 +362,6 @@ struct xt_target {
unsigned short proto; unsigned short proto;
unsigned short family; unsigned short family;
u_int8_t revision;
}; };
/* Furniture shopping... */ /* Furniture shopping... */
@ -398,6 +399,13 @@ struct xt_table_info {
unsigned int hook_entry[NF_INET_NUMHOOKS]; unsigned int hook_entry[NF_INET_NUMHOOKS];
unsigned int underflow[NF_INET_NUMHOOKS]; unsigned int underflow[NF_INET_NUMHOOKS];
/*
* Number of user chains. Since tables cannot have loops, at most
* @stacksize jumps (number of user chains) can possibly be made.
*/
unsigned int stacksize;
unsigned int *stackptr;
void ***jumpstack;
/* ipt_entry tables: one per CPU */ /* ipt_entry tables: one per CPU */
/* Note : this field MUST be the last one, see XT_TABLE_INFO_SZ */ /* Note : this field MUST be the last one, see XT_TABLE_INFO_SZ */
void *entries[1]; void *entries[1];
@ -433,6 +441,8 @@ extern struct xt_table_info *xt_replace_table(struct xt_table *table,
extern struct xt_match *xt_find_match(u8 af, const char *name, u8 revision); extern struct xt_match *xt_find_match(u8 af, const char *name, u8 revision);
extern struct xt_target *xt_find_target(u8 af, const char *name, u8 revision); extern struct xt_target *xt_find_target(u8 af, const char *name, u8 revision);
extern struct xt_match *xt_request_find_match(u8 af, const char *name,
u8 revision);
extern struct xt_target *xt_request_find_target(u8 af, const char *name, extern struct xt_target *xt_request_find_target(u8 af, const char *name,
u8 revision); u8 revision);
extern int xt_find_revision(u8 af, const char *name, u8 revision, extern int xt_find_revision(u8 af, const char *name, u8 revision,
@ -598,7 +608,7 @@ struct _compat_xt_align {
compat_u64 u64; compat_u64 u64;
}; };
#define COMPAT_XT_ALIGN(s) ALIGN((s), __alignof__(struct _compat_xt_align)) #define COMPAT_XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _compat_xt_align))
extern void xt_compat_lock(u_int8_t af); extern void xt_compat_lock(u_int8_t af);
extern void xt_compat_unlock(u_int8_t af); extern void xt_compat_unlock(u_int8_t af);

View File

@ -1,26 +1,6 @@
#ifndef _XT_CONNMARK_H_target #ifndef _XT_CONNMARK_H_target
#define _XT_CONNMARK_H_target #define _XT_CONNMARK_H_target
#include <linux/types.h> #include <linux/netfilter/xt_connmark.h>
/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
* by Henrik Nordstrom <hno@marasystems.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
enum {
XT_CONNMARK_SET = 0,
XT_CONNMARK_SAVE,
XT_CONNMARK_RESTORE
};
struct xt_connmark_tginfo1 {
__u32 ctmark, ctmask, nfmask;
__u8 mode;
};
#endif /*_XT_CONNMARK_H_target*/ #endif /*_XT_CONNMARK_H_target*/

View File

@ -1,10 +1,6 @@
#ifndef _XT_MARK_H_target #ifndef _XT_MARK_H_target
#define _XT_MARK_H_target #define _XT_MARK_H_target
#include <linux/types.h> #include <linux/netfilter/xt_mark.h>
struct xt_mark_tginfo2 {
__u32 mark, mask;
};
#endif /*_XT_MARK_H_target */ #endif /*_XT_MARK_H_target */

View File

@ -0,0 +1,12 @@
#ifndef _XT_TEE_TARGET_H
#define _XT_TEE_TARGET_H
struct xt_tee_tginfo {
union nf_inet_addr gw;
char oif[16];
/* used internally by the kernel */
struct xt_tee_priv *priv __attribute__((aligned(8)));
};
#endif /* _XT_TEE_TARGET_H */

View File

@ -12,6 +12,17 @@
* (at your option) any later version. * (at your option) any later version.
*/ */
enum {
XT_CONNMARK_SET = 0,
XT_CONNMARK_SAVE,
XT_CONNMARK_RESTORE
};
struct xt_connmark_tginfo1 {
__u32 ctmark, ctmask, nfmask;
__u8 mode;
};
struct xt_connmark_mtinfo1 { struct xt_connmark_mtinfo1 {
__u32 mark, mask; __u32 mark, mask;
__u8 invert; __u8 invert;

View File

@ -3,6 +3,10 @@
#include <linux/types.h> #include <linux/types.h>
struct xt_mark_tginfo2 {
__u32 mark, mask;
};
struct xt_mark_mtinfo1 { struct xt_mark_mtinfo1 {
__u32 mark, mask; __u32 mark, mask;
__u8 invert; __u8 invert;

View File

@ -9,6 +9,7 @@ enum {
XT_RECENT_UPDATE = 1 << 2, XT_RECENT_UPDATE = 1 << 2,
XT_RECENT_REMOVE = 1 << 3, XT_RECENT_REMOVE = 1 << 3,
XT_RECENT_TTL = 1 << 4, XT_RECENT_TTL = 1 << 4,
XT_RECENT_REAP = 1 << 5,
XT_RECENT_SOURCE = 0, XT_RECENT_SOURCE = 0,
XT_RECENT_DEST = 1, XT_RECENT_DEST = 1,
@ -16,6 +17,12 @@ enum {
XT_RECENT_NAME_LEN = 200, XT_RECENT_NAME_LEN = 200,
}; };
/* Only allowed with --rcheck and --update */
#define XT_RECENT_MODIFIERS (XT_RECENT_TTL|XT_RECENT_REAP)
#define XT_RECENT_VALID_FLAGS (XT_RECENT_CHECK|XT_RECENT_SET|XT_RECENT_UPDATE|\
XT_RECENT_REMOVE|XT_RECENT_TTL|XT_RECENT_REAP)
struct xt_recent_mtinfo { struct xt_recent_mtinfo {
__u32 seconds; __u32 seconds;
__u32 hit_count; __u32 hit_count;

View File

@ -41,10 +41,10 @@ enum nf_br_hook_priorities {
#define BRNF_PKT_TYPE 0x01 #define BRNF_PKT_TYPE 0x01
#define BRNF_BRIDGED_DNAT 0x02 #define BRNF_BRIDGED_DNAT 0x02
#define BRNF_DONT_TAKE_PARENT 0x04 #define BRNF_BRIDGED 0x04
#define BRNF_BRIDGED 0x08 #define BRNF_NF_BRIDGE_PREROUTING 0x08
#define BRNF_NF_BRIDGE_PREROUTING 0x10 #define BRNF_8021Q 0x10
#define BRNF_PPPoE 0x20
/* Only used in br_forward.c */ /* Only used in br_forward.c */
extern int nf_bridge_copy_header(struct sk_buff *skb); extern int nf_bridge_copy_header(struct sk_buff *skb);
@ -68,6 +68,27 @@ static inline unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb)
} }
} }
static inline unsigned int nf_bridge_mtu_reduction(const struct sk_buff *skb)
{
if (unlikely(skb->nf_bridge->mask & BRNF_PPPoE))
return PPPOE_SES_HLEN;
return 0;
}
extern int br_handle_frame_finish(struct sk_buff *skb);
/* Only used in br_device.c */
static inline int br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
{
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
skb_pull(skb, ETH_HLEN);
nf_bridge->mask ^= BRNF_BRIDGED_DNAT;
skb_copy_to_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN),
skb->nf_bridge->data, ETH_HLEN-ETH_ALEN);
skb->dev = nf_bridge->physindev;
return br_handle_frame_finish(skb);
}
/* This is called by the IP fragmenting code and it ensures there is /* This is called by the IP fragmenting code and it ensures there is
* enough room for the encapsulating header (if there is one). */ * enough room for the encapsulating header (if there is one). */
static inline unsigned int nf_bridge_pad(const struct sk_buff *skb) static inline unsigned int nf_bridge_pad(const struct sk_buff *skb)

View File

@ -316,10 +316,6 @@ extern int ip6t_ext_hdr(u8 nexthdr);
extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
int target, unsigned short *fragoff); int target, unsigned short *fragoff);
extern int ip6_masked_addrcmp(const struct in6_addr *addr1,
const struct in6_addr *mask,
const struct in6_addr *addr2);
#define IP6T_ALIGN(s) XT_ALIGN(s) #define IP6T_ALIGN(s) XT_ALIGN(s)
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT

View File

@ -299,6 +299,20 @@ static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
return 0; return 0;
} }
#ifdef CONFIG_BRIDGE_NETFILTER
static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
{
unsigned seq, hh_alen;
do {
seq = read_seqbegin(&hh->hh_lock);
hh_alen = HH_DATA_ALIGN(ETH_HLEN);
memcpy(skb->data - hh_alen, hh->hh_data, ETH_ALEN + hh_alen - ETH_HLEN);
} while (read_seqretry(&hh->hh_lock, seq));
return 0;
}
#endif
static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb) static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb)
{ {
unsigned seq; unsigned seq;

View File

@ -17,6 +17,7 @@
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/netfilter_bridge.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "br_private.h" #include "br_private.h"
@ -30,6 +31,13 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
struct net_bridge_mdb_entry *mdst; struct net_bridge_mdb_entry *mdst;
struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats); struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats);
#ifdef CONFIG_BRIDGE_NETFILTER
if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) {
br_nf_pre_routing_finish_bridge_slow(skb);
return NETDEV_TX_OK;
}
#endif
brstats->tx_packets++; brstats->tx_packets++;
brstats->tx_bytes += skb->len; brstats->tx_bytes += skb->len;

View File

@ -45,7 +45,7 @@ int br_dev_queue_push_xmit(struct sk_buff *skb)
if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb)) if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
kfree_skb(skb); kfree_skb(skb);
else { else {
/* ip_refrag calls ip_fragment, doesn't copy the MAC header. */ /* ip_fragment doesn't copy the MAC header */
if (nf_bridge_maybe_copy_header(skb)) if (nf_bridge_maybe_copy_header(skb))
kfree_skb(skb); kfree_skb(skb);
else { else {
@ -66,7 +66,7 @@ int br_dev_queue_push_xmit(struct sk_buff *skb)
int br_forward_finish(struct sk_buff *skb) int br_forward_finish(struct sk_buff *skb)
{ {
return NF_HOOK(PF_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev, return NF_HOOK(NFPROTO_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev,
br_dev_queue_push_xmit); br_dev_queue_push_xmit);
} }
@ -84,8 +84,8 @@ static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
} }
#endif #endif
skb->dev = to->dev; skb->dev = to->dev;
NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
br_forward_finish); br_forward_finish);
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
if (skb->dev->npinfo) if (skb->dev->npinfo)
skb->dev->npinfo->netpoll->dev = br->dev; skb->dev->npinfo->netpoll->dev = br->dev;
@ -105,8 +105,8 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
skb->dev = to->dev; skb->dev = to->dev;
skb_forward_csum(skb); skb_forward_csum(skb);
NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev, NF_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
br_forward_finish); br_forward_finish);
} }
/* called with rcu_read_lock */ /* called with rcu_read_lock */

View File

@ -33,7 +33,7 @@ static int br_pass_frame_up(struct sk_buff *skb)
indev = skb->dev; indev = skb->dev;
skb->dev = brdev; skb->dev = brdev;
return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,
netif_receive_skb); netif_receive_skb);
} }
@ -156,7 +156,7 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0) if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0)
goto forward; goto forward;
if (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
NULL, br_handle_local_finish)) NULL, br_handle_local_finish))
return NULL; /* frame consumed by filter */ return NULL; /* frame consumed by filter */
else else
@ -177,7 +177,7 @@ forward:
if (!compare_ether_addr(p->br->dev->dev_addr, dest)) if (!compare_ether_addr(p->br->dev->dev_addr, dest))
skb->pkt_type = PACKET_HOST; skb->pkt_type = PACKET_HOST;
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
br_handle_frame_finish); br_handle_frame_finish);
break; break;
default: default:

View File

@ -814,7 +814,7 @@ static void __br_multicast_send_query(struct net_bridge *br,
if (port) { if (port) {
__skb_push(skb, sizeof(struct ethhdr)); __skb_push(skb, sizeof(struct ethhdr));
skb->dev = port->dev; skb->dev = port->dev;
NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
dev_queue_xmit); dev_queue_xmit);
} else } else
netif_rx(skb); netif_rx(skb);

View File

@ -3,15 +3,8 @@
* Linux ethernet bridge * Linux ethernet bridge
* *
* Authors: * Authors:
* Lennert Buytenhek <buytenh@gnu.org> * Lennert Buytenhek <buytenh@gnu.org>
* Bart De Schuymer (maintainer) <bdschuym@pandora.be> * Bart De Schuymer <bdschuym@pandora.be>
*
* Changes:
* Apr 29 2003: physdev module support (bdschuym)
* Jun 19 2003: let arptables see bridged ARP traffic (bdschuym)
* Oct 06 2003: filter encapsulated IP/ARP VLAN traffic on untagged bridge
* (bdschuym)
* Sep 01 2004: add IPv6 filtering (bdschuym)
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -204,15 +197,24 @@ static inline void nf_bridge_save_header(struct sk_buff *skb)
skb->nf_bridge->data, header_size); skb->nf_bridge->data, header_size);
} }
/* static inline void nf_bridge_update_protocol(struct sk_buff *skb)
* When forwarding bridge frames, we save a copy of the original {
* header before processing. if (skb->nf_bridge->mask & BRNF_8021Q)
skb->protocol = htons(ETH_P_8021Q);
else if (skb->nf_bridge->mask & BRNF_PPPoE)
skb->protocol = htons(ETH_P_PPP_SES);
}
/* Fill in the header for fragmented IP packets handled by
* the IPv4 connection tracking code.
*/ */
int nf_bridge_copy_header(struct sk_buff *skb) int nf_bridge_copy_header(struct sk_buff *skb)
{ {
int err; int err;
int header_size = ETH_HLEN + nf_bridge_encap_header_len(skb); unsigned int header_size;
nf_bridge_update_protocol(skb);
header_size = ETH_HLEN + nf_bridge_encap_header_len(skb);
err = skb_cow_head(skb, header_size); err = skb_cow_head(skb, header_size);
if (err) if (err)
return err; return err;
@ -246,27 +248,48 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
skb_dst_set(skb, &rt->u.dst); skb_dst_set(skb, &rt->u.dst);
skb->dev = nf_bridge->physindev; skb->dev = nf_bridge->physindev;
nf_bridge_update_protocol(skb);
nf_bridge_push_encap_header(skb); nf_bridge_push_encap_header(skb);
NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
br_handle_frame_finish, 1); br_handle_frame_finish, 1);
return 0; return 0;
} }
static void __br_dnat_complain(void) /* Obtain the correct destination MAC address, while preserving the original
* source MAC address. If we already know this address, we just copy it. If we
* don't, we use the neighbour framework to find out. In both cases, we make
* sure that br_handle_frame_finish() is called afterwards.
*/
static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
{ {
static unsigned long last_complaint; struct nf_bridge_info *nf_bridge = skb->nf_bridge;
struct dst_entry *dst;
if (jiffies - last_complaint >= 5 * HZ) { skb->dev = bridge_parent(skb->dev);
printk(KERN_WARNING "Performing cross-bridge DNAT requires IP " if (!skb->dev)
"forwarding to be enabled\n"); goto free_skb;
last_complaint = jiffies; dst = skb_dst(skb);
if (dst->hh) {
neigh_hh_bridge(dst->hh, skb);
skb->dev = nf_bridge->physindev;
return br_handle_frame_finish(skb);
} else if (dst->neighbour) {
/* the neighbour function below overwrites the complete
* MAC header, so we save the Ethernet source address and
* protocol number. */
skb_copy_from_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN), skb->nf_bridge->data, ETH_HLEN-ETH_ALEN);
/* tell br_dev_xmit to continue with forwarding */
nf_bridge->mask |= BRNF_BRIDGED_DNAT;
return dst->neighbour->output(skb);
} }
free_skb:
kfree_skb(skb);
return 0;
} }
/* This requires some explaining. If DNAT has taken place, /* This requires some explaining. If DNAT has taken place,
* we will need to fix up the destination Ethernet address, * we will need to fix up the destination Ethernet address.
* and this is a tricky process.
* *
* There are two cases to consider: * There are two cases to consider:
* 1. The packet was DNAT'ed to a device in the same bridge * 1. The packet was DNAT'ed to a device in the same bridge
@ -280,62 +303,29 @@ static void __br_dnat_complain(void)
* call ip_route_input() and to look at skb->dst->dev, which is * call ip_route_input() and to look at skb->dst->dev, which is
* changed to the destination device if ip_route_input() succeeds. * changed to the destination device if ip_route_input() succeeds.
* *
* Let us first consider the case that ip_route_input() succeeds: * Let's first consider the case that ip_route_input() succeeds:
*
* If skb->dst->dev equals the logical bridge device the packet
* came in on, we can consider this bridging. The packet is passed
* through the neighbour output function to build a new destination
* MAC address, which will make the packet enter br_nf_local_out()
* not much later. In that function it is assured that the iptables
* FORWARD chain is traversed for the packet.
* *
* If the output device equals the logical bridge device the packet
* came in on, we can consider this bridging. The corresponding MAC
* address will be obtained in br_nf_pre_routing_finish_bridge.
* Otherwise, the packet is considered to be routed and we just * Otherwise, the packet is considered to be routed and we just
* change the destination MAC address so that the packet will * change the destination MAC address so that the packet will
* later be passed up to the IP stack to be routed. For a redirected * later be passed up to the IP stack to be routed. For a redirected
* packet, ip_route_input() will give back the localhost as output device, * packet, ip_route_input() will give back the localhost as output device,
* which differs from the bridge device. * which differs from the bridge device.
* *
* Let us now consider the case that ip_route_input() fails: * Let's now consider the case that ip_route_input() fails:
* *
* This can be because the destination address is martian, in which case * This can be because the destination address is martian, in which case
* the packet will be dropped. * the packet will be dropped.
* After a "echo '0' > /proc/sys/net/ipv4/ip_forward" ip_route_input() * If IP forwarding is disabled, ip_route_input() will fail, while
* will fail, while __ip_route_output_key() will return success. The source * ip_route_output_key() can return success. The source
* address for __ip_route_output_key() is set to zero, so __ip_route_output_key * address for ip_route_output_key() is set to zero, so ip_route_output_key()
* thinks we're handling a locally generated packet and won't care * thinks we're handling a locally generated packet and won't care
* if IP forwarding is allowed. We send a warning message to the users's * if IP forwarding is enabled. If the output device equals the logical bridge
* log telling her to put IP forwarding on. * device, we proceed as if ip_route_input() succeeded. If it differs from the
* * logical bridge port or if ip_route_output_key() fails we drop the packet.
* ip_route_input() will also fail if there is no route available. */
* In that case we just drop the packet.
*
* --Lennert, 20020411
* --Bart, 20020416 (updated)
* --Bart, 20021007 (updated)
* --Bart, 20062711 (updated) */
static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
{
if (skb->pkt_type == PACKET_OTHERHOST) {
skb->pkt_type = PACKET_HOST;
skb->nf_bridge->mask |= BRNF_PKT_TYPE;
}
skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
skb->dev = bridge_parent(skb->dev);
if (skb->dev) {
struct dst_entry *dst = skb_dst(skb);
nf_bridge_pull_encap_header(skb);
if (dst->hh)
return neigh_hh_output(dst->hh, skb);
else if (dst->neighbour)
return dst->neighbour->output(skb);
}
kfree_skb(skb);
return 0;
}
static int br_nf_pre_routing_finish(struct sk_buff *skb) static int br_nf_pre_routing_finish(struct sk_buff *skb)
{ {
struct net_device *dev = skb->dev; struct net_device *dev = skb->dev;
@ -379,11 +369,6 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
skb_dst_set(skb, (struct dst_entry *)rt); skb_dst_set(skb, (struct dst_entry *)rt);
goto bridged_dnat; goto bridged_dnat;
} }
/* we are sure that forwarding is disabled, so printing
* this message is no problem. Note that the packet could
* still have a martian destination address, in which case
* the packet could be dropped even if forwarding were enabled */
__br_dnat_complain();
dst_release((struct dst_entry *)rt); dst_release((struct dst_entry *)rt);
} }
free_skb: free_skb:
@ -392,12 +377,11 @@ free_skb:
} else { } else {
if (skb_dst(skb)->dev == dev) { if (skb_dst(skb)->dev == dev) {
bridged_dnat: bridged_dnat:
/* Tell br_nf_local_out this is a
* bridged frame */
nf_bridge->mask |= BRNF_BRIDGED_DNAT;
skb->dev = nf_bridge->physindev; skb->dev = nf_bridge->physindev;
nf_bridge_update_protocol(skb);
nf_bridge_push_encap_header(skb); nf_bridge_push_encap_header(skb);
NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, NF_HOOK_THRESH(NFPROTO_BRIDGE,
NF_BR_PRE_ROUTING,
skb, skb->dev, NULL, skb, skb->dev, NULL,
br_nf_pre_routing_finish_bridge, br_nf_pre_routing_finish_bridge,
1); 1);
@ -417,8 +401,9 @@ bridged_dnat:
} }
skb->dev = nf_bridge->physindev; skb->dev = nf_bridge->physindev;
nf_bridge_update_protocol(skb);
nf_bridge_push_encap_header(skb); nf_bridge_push_encap_header(skb);
NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
br_handle_frame_finish, 1); br_handle_frame_finish, 1);
return 0; return 0;
@ -437,6 +422,10 @@ static struct net_device *setup_pre_routing(struct sk_buff *skb)
nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING; nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
nf_bridge->physindev = skb->dev; nf_bridge->physindev = skb->dev;
skb->dev = bridge_parent(skb->dev); skb->dev = bridge_parent(skb->dev);
if (skb->protocol == htons(ETH_P_8021Q))
nf_bridge->mask |= BRNF_8021Q;
else if (skb->protocol == htons(ETH_P_PPP_SES))
nf_bridge->mask |= BRNF_PPPoE;
return skb->dev; return skb->dev;
} }
@ -535,7 +524,8 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
if (!setup_pre_routing(skb)) if (!setup_pre_routing(skb))
return NF_DROP; return NF_DROP;
NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, skb->protocol = htons(ETH_P_IPV6);
NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
br_nf_pre_routing_finish_ipv6); br_nf_pre_routing_finish_ipv6);
return NF_STOLEN; return NF_STOLEN;
@ -607,8 +597,9 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
if (!setup_pre_routing(skb)) if (!setup_pre_routing(skb))
return NF_DROP; return NF_DROP;
store_orig_dstaddr(skb); store_orig_dstaddr(skb);
skb->protocol = htons(ETH_P_IP);
NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
br_nf_pre_routing_finish); br_nf_pre_routing_finish);
return NF_STOLEN; return NF_STOLEN;
@ -655,8 +646,10 @@ static int br_nf_forward_finish(struct sk_buff *skb)
} else { } else {
in = *((struct net_device **)(skb->cb)); in = *((struct net_device **)(skb->cb));
} }
nf_bridge_update_protocol(skb);
nf_bridge_push_encap_header(skb); nf_bridge_push_encap_header(skb);
NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in,
NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, in,
skb->dev, br_forward_finish, 1); skb->dev, br_forward_finish, 1);
return 0; return 0;
} }
@ -707,6 +700,10 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
/* The physdev module checks on this */ /* The physdev module checks on this */
nf_bridge->mask |= BRNF_BRIDGED; nf_bridge->mask |= BRNF_BRIDGED;
nf_bridge->physoutdev = skb->dev; nf_bridge->physoutdev = skb->dev;
if (pf == PF_INET)
skb->protocol = htons(ETH_P_IP);
else
skb->protocol = htons(ETH_P_IPV6);
NF_HOOK(pf, NF_INET_FORWARD, skb, bridge_parent(in), parent, NF_HOOK(pf, NF_INET_FORWARD, skb, bridge_parent(in), parent,
br_nf_forward_finish); br_nf_forward_finish);
@ -744,60 +741,11 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb,
return NF_STOLEN; return NF_STOLEN;
} }
/* PF_BRIDGE/LOCAL_OUT ***********************************************
*
* This function sees both locally originated IP packets and forwarded
* IP packets (in both cases the destination device is a bridge
* device). It also sees bridged-and-DNAT'ed packets.
*
* If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged
* and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward()
* will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority
* NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor
* will be executed.
*/
static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct net_device *realindev;
struct nf_bridge_info *nf_bridge;
if (!skb->nf_bridge)
return NF_ACCEPT;
/* Need exclusive nf_bridge_info since we might have multiple
* different physoutdevs. */
if (!nf_bridge_unshare(skb))
return NF_DROP;
nf_bridge = skb->nf_bridge;
if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT))
return NF_ACCEPT;
/* Bridged, take PF_BRIDGE/FORWARD.
* (see big note in front of br_nf_pre_routing_finish) */
nf_bridge->physoutdev = skb->dev;
realindev = nf_bridge->physindev;
if (nf_bridge->mask & BRNF_PKT_TYPE) {
skb->pkt_type = PACKET_OTHERHOST;
nf_bridge->mask ^= BRNF_PKT_TYPE;
}
nf_bridge_push_encap_header(skb);
NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev,
br_forward_finish);
return NF_STOLEN;
}
#if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE) #if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE)
static int br_nf_dev_queue_xmit(struct sk_buff *skb) static int br_nf_dev_queue_xmit(struct sk_buff *skb)
{ {
if (skb->nfct != NULL && if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) &&
(skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb)) && skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu &&
skb->len > skb->dev->mtu &&
!skb_is_gso(skb)) !skb_is_gso(skb))
return ip_fragment(skb, br_dev_queue_push_xmit); return ip_fragment(skb, br_dev_queue_push_xmit);
else else
@ -820,21 +768,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
struct net_device *realoutdev = bridge_parent(skb->dev); struct net_device *realoutdev = bridge_parent(skb->dev);
u_int8_t pf; u_int8_t pf;
#ifdef CONFIG_NETFILTER_DEBUG if (!nf_bridge || !(nf_bridge->mask & BRNF_BRIDGED))
/* Be very paranoid. This probably won't happen anymore, but let's
* keep the check just to be sure... */
if (skb_mac_header(skb) < skb->head ||
skb_mac_header(skb) + ETH_HLEN > skb->data) {
printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: "
"bad mac.raw pointer.\n");
goto print_error;
}
#endif
if (!nf_bridge)
return NF_ACCEPT;
if (!(nf_bridge->mask & (BRNF_BRIDGED | BRNF_BRIDGED_DNAT)))
return NF_ACCEPT; return NF_ACCEPT;
if (!realoutdev) if (!realoutdev)
@ -849,13 +783,6 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
else else
return NF_ACCEPT; return NF_ACCEPT;
#ifdef CONFIG_NETFILTER_DEBUG
if (skb_dst(skb) == NULL) {
printk(KERN_INFO "br_netfilter post_routing: skb->dst == NULL\n");
goto print_error;
}
#endif
/* We assume any code from br_dev_queue_push_xmit onwards doesn't care /* We assume any code from br_dev_queue_push_xmit onwards doesn't care
* about the value of skb->pkt_type. */ * about the value of skb->pkt_type. */
if (skb->pkt_type == PACKET_OTHERHOST) { if (skb->pkt_type == PACKET_OTHERHOST) {
@ -865,24 +792,15 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
nf_bridge_pull_encap_header(skb); nf_bridge_pull_encap_header(skb);
nf_bridge_save_header(skb); nf_bridge_save_header(skb);
if (pf == PF_INET)
skb->protocol = htons(ETH_P_IP);
else
skb->protocol = htons(ETH_P_IPV6);
NF_HOOK(pf, NF_INET_POST_ROUTING, skb, NULL, realoutdev, NF_HOOK(pf, NF_INET_POST_ROUTING, skb, NULL, realoutdev,
br_nf_dev_queue_xmit); br_nf_dev_queue_xmit);
return NF_STOLEN; return NF_STOLEN;
#ifdef CONFIG_NETFILTER_DEBUG
print_error:
if (skb->dev != NULL) {
printk("[%s]", skb->dev->name);
if (realoutdev)
printk("[%s]", realoutdev->name);
}
printk(" head:%p, raw:%p, data:%p\n", skb->head, skb_mac_header(skb),
skb->data);
dump_stack();
return NF_ACCEPT;
#endif
} }
/* IP/SABOTAGE *****************************************************/ /* IP/SABOTAGE *****************************************************/
@ -901,10 +819,8 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff *skb,
return NF_ACCEPT; return NF_ACCEPT;
} }
/* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent /* For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because
* PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input. * br_dev_queue_push_xmit is called afterwards */
* For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because
* ip_refrag() can return NF_STOLEN. */
static struct nf_hook_ops br_nf_ops[] __read_mostly = { static struct nf_hook_ops br_nf_ops[] __read_mostly = {
{ {
.hook = br_nf_pre_routing, .hook = br_nf_pre_routing,
@ -934,13 +850,6 @@ static struct nf_hook_ops br_nf_ops[] __read_mostly = {
.hooknum = NF_BR_FORWARD, .hooknum = NF_BR_FORWARD,
.priority = NF_BR_PRI_BRNF, .priority = NF_BR_PRI_BRNF,
}, },
{
.hook = br_nf_local_out,
.owner = THIS_MODULE,
.pf = PF_BRIDGE,
.hooknum = NF_BR_LOCAL_OUT,
.priority = NF_BR_PRI_FIRST,
},
{ {
.hook = br_nf_post_routing, .hook = br_nf_post_routing,
.owner = THIS_MODULE, .owner = THIS_MODULE,

View File

@ -50,7 +50,7 @@ static void br_send_bpdu(struct net_bridge_port *p,
llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr); llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr);
NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
dev_queue_xmit); dev_queue_xmit);
} }

View File

@ -36,14 +36,14 @@ ebt_802_3_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool ebt_802_3_mt_check(const struct xt_mtchk_param *par) static int ebt_802_3_mt_check(const struct xt_mtchk_param *par)
{ {
const struct ebt_802_3_info *info = par->matchinfo; const struct ebt_802_3_info *info = par->matchinfo;
if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK) if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK)
return false; return -EINVAL;
return true; return 0;
} }
static struct xt_match ebt_802_3_mt_reg __read_mostly = { static struct xt_match ebt_802_3_mt_reg __read_mostly = {

View File

@ -7,6 +7,7 @@
* August, 2003 * August, 2003
* *
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/module.h> #include <linux/module.h>
@ -171,7 +172,7 @@ ebt_among_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool ebt_among_mt_check(const struct xt_mtchk_param *par) static int ebt_among_mt_check(const struct xt_mtchk_param *par)
{ {
const struct ebt_among_info *info = par->matchinfo; const struct ebt_among_info *info = par->matchinfo;
const struct ebt_entry_match *em = const struct ebt_entry_match *em =
@ -186,24 +187,20 @@ static bool ebt_among_mt_check(const struct xt_mtchk_param *par)
expected_length += ebt_mac_wormhash_size(wh_src); expected_length += ebt_mac_wormhash_size(wh_src);
if (em->match_size != EBT_ALIGN(expected_length)) { if (em->match_size != EBT_ALIGN(expected_length)) {
printk(KERN_WARNING pr_info("wrong size: %d against expected %d, rounded to %Zd\n",
"ebtables: among: wrong size: %d " em->match_size, expected_length,
"against expected %d, rounded to %Zd\n", EBT_ALIGN(expected_length));
em->match_size, expected_length, return -EINVAL;
EBT_ALIGN(expected_length));
return false;
} }
if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) { if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) {
printk(KERN_WARNING pr_info("dst integrity fail: %x\n", -err);
"ebtables: among: dst integrity fail: %x\n", -err); return -EINVAL;
return false;
} }
if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) { if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) {
printk(KERN_WARNING pr_info("src integrity fail: %x\n", -err);
"ebtables: among: src integrity fail: %x\n", -err); return -EINVAL;
return false;
} }
return true; return 0;
} }
static struct xt_match ebt_among_mt_reg __read_mostly = { static struct xt_match ebt_among_mt_reg __read_mostly = {

View File

@ -100,7 +100,7 @@ ebt_arp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool ebt_arp_mt_check(const struct xt_mtchk_param *par) static int ebt_arp_mt_check(const struct xt_mtchk_param *par)
{ {
const struct ebt_arp_info *info = par->matchinfo; const struct ebt_arp_info *info = par->matchinfo;
const struct ebt_entry *e = par->entryinfo; const struct ebt_entry *e = par->entryinfo;
@ -108,10 +108,10 @@ static bool ebt_arp_mt_check(const struct xt_mtchk_param *par)
if ((e->ethproto != htons(ETH_P_ARP) && if ((e->ethproto != htons(ETH_P_ARP) &&
e->ethproto != htons(ETH_P_RARP)) || e->ethproto != htons(ETH_P_RARP)) ||
e->invflags & EBT_IPROTO) e->invflags & EBT_IPROTO)
return false; return -EINVAL;
if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK) if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK)
return false; return -EINVAL;
return true; return 0;
} }
static struct xt_match ebt_arp_mt_reg __read_mostly = { static struct xt_match ebt_arp_mt_reg __read_mostly = {

View File

@ -57,17 +57,17 @@ ebt_arpreply_tg(struct sk_buff *skb, const struct xt_target_param *par)
return info->target; return info->target;
} }
static bool ebt_arpreply_tg_check(const struct xt_tgchk_param *par) static int ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
{ {
const struct ebt_arpreply_info *info = par->targinfo; const struct ebt_arpreply_info *info = par->targinfo;
const struct ebt_entry *e = par->entryinfo; const struct ebt_entry *e = par->entryinfo;
if (BASE_CHAIN && info->target == EBT_RETURN) if (BASE_CHAIN && info->target == EBT_RETURN)
return false; return -EINVAL;
if (e->ethproto != htons(ETH_P_ARP) || if (e->ethproto != htons(ETH_P_ARP) ||
e->invflags & EBT_IPROTO) e->invflags & EBT_IPROTO)
return false; return -EINVAL;
return true; return 0;
} }
static struct xt_target ebt_arpreply_tg_reg __read_mostly = { static struct xt_target ebt_arpreply_tg_reg __read_mostly = {

View File

@ -26,13 +26,13 @@ ebt_dnat_tg(struct sk_buff *skb, const struct xt_target_param *par)
return info->target; return info->target;
} }
static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par) static int ebt_dnat_tg_check(const struct xt_tgchk_param *par)
{ {
const struct ebt_nat_info *info = par->targinfo; const struct ebt_nat_info *info = par->targinfo;
unsigned int hook_mask; unsigned int hook_mask;
if (BASE_CHAIN && info->target == EBT_RETURN) if (BASE_CHAIN && info->target == EBT_RETURN)
return false; return -EINVAL;
hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS); hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
if ((strcmp(par->table, "nat") != 0 || if ((strcmp(par->table, "nat") != 0 ||
@ -40,10 +40,10 @@ static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par)
(1 << NF_BR_LOCAL_OUT)))) && (1 << NF_BR_LOCAL_OUT)))) &&
(strcmp(par->table, "broute") != 0 || (strcmp(par->table, "broute") != 0 ||
hook_mask & ~(1 << NF_BR_BROUTING))) hook_mask & ~(1 << NF_BR_BROUTING)))
return false; return -EINVAL;
if (INVALID_TARGET) if (INVALID_TARGET)
return false; return -EINVAL;
return true; return 0;
} }
static struct xt_target ebt_dnat_tg_reg __read_mostly = { static struct xt_target ebt_dnat_tg_reg __read_mostly = {

View File

@ -77,31 +77,31 @@ ebt_ip_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool ebt_ip_mt_check(const struct xt_mtchk_param *par) static int ebt_ip_mt_check(const struct xt_mtchk_param *par)
{ {
const struct ebt_ip_info *info = par->matchinfo; const struct ebt_ip_info *info = par->matchinfo;
const struct ebt_entry *e = par->entryinfo; const struct ebt_entry *e = par->entryinfo;
if (e->ethproto != htons(ETH_P_IP) || if (e->ethproto != htons(ETH_P_IP) ||
e->invflags & EBT_IPROTO) e->invflags & EBT_IPROTO)
return false; return -EINVAL;
if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK) if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK)
return false; return -EINVAL;
if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) { if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) {
if (info->invflags & EBT_IP_PROTO) if (info->invflags & EBT_IP_PROTO)
return false; return -EINVAL;
if (info->protocol != IPPROTO_TCP && if (info->protocol != IPPROTO_TCP &&
info->protocol != IPPROTO_UDP && info->protocol != IPPROTO_UDP &&
info->protocol != IPPROTO_UDPLITE && info->protocol != IPPROTO_UDPLITE &&
info->protocol != IPPROTO_SCTP && info->protocol != IPPROTO_SCTP &&
info->protocol != IPPROTO_DCCP) info->protocol != IPPROTO_DCCP)
return false; return -EINVAL;
} }
if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1]) if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
return false; return -EINVAL;
if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1]) if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
return false; return -EINVAL;
return true; return 0;
} }
static struct xt_match ebt_ip_mt_reg __read_mostly = { static struct xt_match ebt_ip_mt_reg __read_mostly = {

View File

@ -4,7 +4,7 @@
* Authors: * Authors:
* Manohar Castelino <manohar.r.castelino@intel.com> * Manohar Castelino <manohar.r.castelino@intel.com>
* Kuo-Lang Tseng <kuo-lang.tseng@intel.com> * Kuo-Lang Tseng <kuo-lang.tseng@intel.com>
* Jan Engelhardt <jengelh@computergmbh.de> * Jan Engelhardt <jengelh@medozas.de>
* *
* Summary: * Summary:
* This is just a modification of the IPv4 code written by * This is just a modification of the IPv4 code written by
@ -35,8 +35,6 @@ ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
struct ipv6hdr _ip6h; struct ipv6hdr _ip6h;
const struct tcpudphdr *pptr; const struct tcpudphdr *pptr;
struct tcpudphdr _ports; struct tcpudphdr _ports;
struct in6_addr tmp_addr;
int i;
ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h); ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h);
if (ih6 == NULL) if (ih6 == NULL)
@ -44,18 +42,10 @@ ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
if (info->bitmask & EBT_IP6_TCLASS && if (info->bitmask & EBT_IP6_TCLASS &&
FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS)) FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS))
return false; return false;
for (i = 0; i < 4; i++) if (FWINV(ipv6_masked_addr_cmp(&ih6->saddr, &info->smsk,
tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] & &info->saddr), EBT_IP6_SOURCE) ||
info->smsk.in6_u.u6_addr32[i]; FWINV(ipv6_masked_addr_cmp(&ih6->daddr, &info->dmsk,
if (info->bitmask & EBT_IP6_SOURCE && &info->daddr), EBT_IP6_DEST))
FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0),
EBT_IP6_SOURCE))
return false;
for (i = 0; i < 4; i++)
tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] &
info->dmsk.in6_u.u6_addr32[i];
if (info->bitmask & EBT_IP6_DEST &&
FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), EBT_IP6_DEST))
return false; return false;
if (info->bitmask & EBT_IP6_PROTO) { if (info->bitmask & EBT_IP6_PROTO) {
uint8_t nexthdr = ih6->nexthdr; uint8_t nexthdr = ih6->nexthdr;
@ -90,30 +80,30 @@ ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool ebt_ip6_mt_check(const struct xt_mtchk_param *par) static int ebt_ip6_mt_check(const struct xt_mtchk_param *par)
{ {
const struct ebt_entry *e = par->entryinfo; const struct ebt_entry *e = par->entryinfo;
struct ebt_ip6_info *info = par->matchinfo; struct ebt_ip6_info *info = par->matchinfo;
if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO) if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO)
return false; return -EINVAL;
if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK) if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK)
return false; return -EINVAL;
if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) { if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) {
if (info->invflags & EBT_IP6_PROTO) if (info->invflags & EBT_IP6_PROTO)
return false; return -EINVAL;
if (info->protocol != IPPROTO_TCP && if (info->protocol != IPPROTO_TCP &&
info->protocol != IPPROTO_UDP && info->protocol != IPPROTO_UDP &&
info->protocol != IPPROTO_UDPLITE && info->protocol != IPPROTO_UDPLITE &&
info->protocol != IPPROTO_SCTP && info->protocol != IPPROTO_SCTP &&
info->protocol != IPPROTO_DCCP) info->protocol != IPPROTO_DCCP)
return false; return -EINVAL;
} }
if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1]) if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1])
return false; return -EINVAL;
if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1]) if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1])
return false; return -EINVAL;
return true; return 0;
} }
static struct xt_match ebt_ip6_mt_reg __read_mostly = { static struct xt_match ebt_ip6_mt_reg __read_mostly = {
@ -139,4 +129,5 @@ static void __exit ebt_ip6_fini(void)
module_init(ebt_ip6_init); module_init(ebt_ip6_init);
module_exit(ebt_ip6_fini); module_exit(ebt_ip6_fini);
MODULE_DESCRIPTION("Ebtables: IPv6 protocol packet match"); MODULE_DESCRIPTION("Ebtables: IPv6 protocol packet match");
MODULE_AUTHOR("Kuo-Lang Tseng <kuo-lang.tseng@intel.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@ -10,6 +10,7 @@
* September, 2003 * September, 2003
* *
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
@ -64,16 +65,16 @@ user2credits(u_int32_t user)
return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE; return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE;
} }
static bool ebt_limit_mt_check(const struct xt_mtchk_param *par) static int ebt_limit_mt_check(const struct xt_mtchk_param *par)
{ {
struct ebt_limit_info *info = par->matchinfo; struct ebt_limit_info *info = par->matchinfo;
/* Check for overflow. */ /* Check for overflow. */
if (info->burst == 0 || if (info->burst == 0 ||
user2credits(info->avg * info->burst) < user2credits(info->avg)) { user2credits(info->avg * info->burst) < user2credits(info->avg)) {
printk("Overflow in ebt_limit, try lower: %u/%u\n", pr_info("overflow, try lower: %u/%u\n",
info->avg, info->burst); info->avg, info->burst);
return false; return -EINVAL;
} }
/* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */ /* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */
@ -81,7 +82,7 @@ static bool ebt_limit_mt_check(const struct xt_mtchk_param *par)
info->credit = user2credits(info->avg * info->burst); info->credit = user2credits(info->avg * info->burst);
info->credit_cap = user2credits(info->avg * info->burst); info->credit_cap = user2credits(info->avg * info->burst);
info->cost = user2credits(info->avg); info->cost = user2credits(info->avg);
return true; return 0;
} }

View File

@ -24,16 +24,16 @@
static DEFINE_SPINLOCK(ebt_log_lock); static DEFINE_SPINLOCK(ebt_log_lock);
static bool ebt_log_tg_check(const struct xt_tgchk_param *par) static int ebt_log_tg_check(const struct xt_tgchk_param *par)
{ {
struct ebt_log_info *info = par->targinfo; struct ebt_log_info *info = par->targinfo;
if (info->bitmask & ~EBT_LOG_MASK) if (info->bitmask & ~EBT_LOG_MASK)
return false; return -EINVAL;
if (info->loglevel >= 8) if (info->loglevel >= 8)
return false; return -EINVAL;
info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0'; info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0';
return true; return 0;
} }
struct tcpudphdr struct tcpudphdr

View File

@ -36,21 +36,21 @@ ebt_mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
return info->target | ~EBT_VERDICT_BITS; return info->target | ~EBT_VERDICT_BITS;
} }
static bool ebt_mark_tg_check(const struct xt_tgchk_param *par) static int ebt_mark_tg_check(const struct xt_tgchk_param *par)
{ {
const struct ebt_mark_t_info *info = par->targinfo; const struct ebt_mark_t_info *info = par->targinfo;
int tmp; int tmp;
tmp = info->target | ~EBT_VERDICT_BITS; tmp = info->target | ~EBT_VERDICT_BITS;
if (BASE_CHAIN && tmp == EBT_RETURN) if (BASE_CHAIN && tmp == EBT_RETURN)
return false; return -EINVAL;
if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
return false; return -EINVAL;
tmp = info->target & ~EBT_VERDICT_BITS; tmp = info->target & ~EBT_VERDICT_BITS;
if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE && if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE) tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
return false; return -EINVAL;
return true; return 0;
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
struct compat_ebt_mark_t_info { struct compat_ebt_mark_t_info {

View File

@ -22,17 +22,17 @@ ebt_mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return ((skb->mark & info->mask) == info->mark) ^ info->invert; return ((skb->mark & info->mask) == info->mark) ^ info->invert;
} }
static bool ebt_mark_mt_check(const struct xt_mtchk_param *par) static int ebt_mark_mt_check(const struct xt_mtchk_param *par)
{ {
const struct ebt_mark_m_info *info = par->matchinfo; const struct ebt_mark_m_info *info = par->matchinfo;
if (info->bitmask & ~EBT_MARK_MASK) if (info->bitmask & ~EBT_MARK_MASK)
return false; return -EINVAL;
if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND)) if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND))
return false; return -EINVAL;
if (!info->bitmask) if (!info->bitmask)
return false; return -EINVAL;
return true; return 0;
} }

View File

@ -35,14 +35,14 @@ ebt_nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
return EBT_CONTINUE; return EBT_CONTINUE;
} }
static bool ebt_nflog_tg_check(const struct xt_tgchk_param *par) static int ebt_nflog_tg_check(const struct xt_tgchk_param *par)
{ {
struct ebt_nflog_info *info = par->targinfo; struct ebt_nflog_info *info = par->targinfo;
if (info->flags & ~EBT_NFLOG_MASK) if (info->flags & ~EBT_NFLOG_MASK)
return false; return -EINVAL;
info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0'; info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0';
return true; return 0;
} }
static struct xt_target ebt_nflog_tg_reg __read_mostly = { static struct xt_target ebt_nflog_tg_reg __read_mostly = {

View File

@ -20,14 +20,14 @@ ebt_pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return (skb->pkt_type == info->pkt_type) ^ info->invert; return (skb->pkt_type == info->pkt_type) ^ info->invert;
} }
static bool ebt_pkttype_mt_check(const struct xt_mtchk_param *par) static int ebt_pkttype_mt_check(const struct xt_mtchk_param *par)
{ {
const struct ebt_pkttype_info *info = par->matchinfo; const struct ebt_pkttype_info *info = par->matchinfo;
if (info->invert != 0 && info->invert != 1) if (info->invert != 0 && info->invert != 1)
return false; return -EINVAL;
/* Allow any pkt_type value */ /* Allow any pkt_type value */
return true; return 0;
} }
static struct xt_match ebt_pkttype_mt_reg __read_mostly = { static struct xt_match ebt_pkttype_mt_reg __read_mostly = {

View File

@ -32,23 +32,23 @@ ebt_redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)
return info->target; return info->target;
} }
static bool ebt_redirect_tg_check(const struct xt_tgchk_param *par) static int ebt_redirect_tg_check(const struct xt_tgchk_param *par)
{ {
const struct ebt_redirect_info *info = par->targinfo; const struct ebt_redirect_info *info = par->targinfo;
unsigned int hook_mask; unsigned int hook_mask;
if (BASE_CHAIN && info->target == EBT_RETURN) if (BASE_CHAIN && info->target == EBT_RETURN)
return false; return -EINVAL;
hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS); hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
if ((strcmp(par->table, "nat") != 0 || if ((strcmp(par->table, "nat") != 0 ||
hook_mask & ~(1 << NF_BR_PRE_ROUTING)) && hook_mask & ~(1 << NF_BR_PRE_ROUTING)) &&
(strcmp(par->table, "broute") != 0 || (strcmp(par->table, "broute") != 0 ||
hook_mask & ~(1 << NF_BR_BROUTING))) hook_mask & ~(1 << NF_BR_BROUTING)))
return false; return -EINVAL;
if (INVALID_TARGET) if (INVALID_TARGET)
return false; return -EINVAL;
return true; return 0;
} }
static struct xt_target ebt_redirect_tg_reg __read_mostly = { static struct xt_target ebt_redirect_tg_reg __read_mostly = {

View File

@ -42,21 +42,21 @@ out:
return info->target | ~EBT_VERDICT_BITS; return info->target | ~EBT_VERDICT_BITS;
} }
static bool ebt_snat_tg_check(const struct xt_tgchk_param *par) static int ebt_snat_tg_check(const struct xt_tgchk_param *par)
{ {
const struct ebt_nat_info *info = par->targinfo; const struct ebt_nat_info *info = par->targinfo;
int tmp; int tmp;
tmp = info->target | ~EBT_VERDICT_BITS; tmp = info->target | ~EBT_VERDICT_BITS;
if (BASE_CHAIN && tmp == EBT_RETURN) if (BASE_CHAIN && tmp == EBT_RETURN)
return false; return -EINVAL;
if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
return false; return -EINVAL;
tmp = info->target | EBT_VERDICT_BITS; tmp = info->target | EBT_VERDICT_BITS;
if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT) if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT)
return false; return -EINVAL;
return true; return 0;
} }
static struct xt_target ebt_snat_tg_reg __read_mostly = { static struct xt_target ebt_snat_tg_reg __read_mostly = {

View File

@ -153,7 +153,7 @@ ebt_stp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool ebt_stp_mt_check(const struct xt_mtchk_param *par) static int ebt_stp_mt_check(const struct xt_mtchk_param *par)
{ {
const struct ebt_stp_info *info = par->matchinfo; const struct ebt_stp_info *info = par->matchinfo;
const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00}; const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00};
@ -162,13 +162,13 @@ static bool ebt_stp_mt_check(const struct xt_mtchk_param *par)
if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK || if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK ||
!(info->bitmask & EBT_STP_MASK)) !(info->bitmask & EBT_STP_MASK))
return false; return -EINVAL;
/* Make sure the match only receives stp frames */ /* Make sure the match only receives stp frames */
if (compare_ether_addr(e->destmac, bridge_ula) || if (compare_ether_addr(e->destmac, bridge_ula) ||
compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC)) compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC))
return false; return -EINVAL;
return true; return 0;
} }
static struct xt_match ebt_stp_mt_reg __read_mostly = { static struct xt_match ebt_stp_mt_reg __read_mostly = {

View File

@ -27,7 +27,7 @@
* flushed even if it is not full yet. * flushed even if it is not full yet.
* *
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
@ -44,9 +44,6 @@
#include <net/sock.h> #include <net/sock.h>
#include "../br_private.h" #include "../br_private.h"
#define PRINTR(format, args...) do { if (net_ratelimit()) \
printk(format , ## args); } while (0)
static unsigned int nlbufsiz = NLMSG_GOODSIZE; static unsigned int nlbufsiz = NLMSG_GOODSIZE;
module_param(nlbufsiz, uint, 0600); module_param(nlbufsiz, uint, 0600);
MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) " MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) "
@ -107,15 +104,14 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
n = max(size, nlbufsiz); n = max(size, nlbufsiz);
skb = alloc_skb(n, GFP_ATOMIC); skb = alloc_skb(n, GFP_ATOMIC);
if (!skb) { if (!skb) {
PRINTR(KERN_ERR "ebt_ulog: can't alloc whole buffer " pr_debug("cannot alloc whole buffer of size %ub!\n", n);
"of size %ub!\n", n);
if (n > size) { if (n > size) {
/* try to allocate only as much as we need for /* try to allocate only as much as we need for
* current packet */ * current packet */
skb = alloc_skb(size, GFP_ATOMIC); skb = alloc_skb(size, GFP_ATOMIC);
if (!skb) if (!skb)
PRINTR(KERN_ERR "ebt_ulog: can't even allocate " pr_debug("cannot even allocate "
"buffer of size %ub\n", size); "buffer of size %ub\n", size);
} }
} }
@ -142,8 +138,7 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
size = NLMSG_SPACE(sizeof(*pm) + copy_len); size = NLMSG_SPACE(sizeof(*pm) + copy_len);
if (size > nlbufsiz) { if (size > nlbufsiz) {
PRINTR("ebt_ulog: Size %Zd needed, but nlbufsiz=%d\n", pr_debug("Size %Zd needed, but nlbufsiz=%d\n", size, nlbufsiz);
size, nlbufsiz);
return; return;
} }
@ -217,8 +212,8 @@ unlock:
return; return;
nlmsg_failure: nlmsg_failure:
printk(KERN_CRIT "ebt_ulog: error during NLMSG_PUT. This should " pr_debug("error during NLMSG_PUT. This should "
"not happen, please report to author.\n"); "not happen, please report to author.\n");
goto unlock; goto unlock;
alloc_failure: alloc_failure:
goto unlock; goto unlock;
@ -255,19 +250,19 @@ ebt_ulog_tg(struct sk_buff *skb, const struct xt_target_param *par)
return EBT_CONTINUE; return EBT_CONTINUE;
} }
static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par) static int ebt_ulog_tg_check(const struct xt_tgchk_param *par)
{ {
struct ebt_ulog_info *uloginfo = par->targinfo; struct ebt_ulog_info *uloginfo = par->targinfo;
if (uloginfo->nlgroup > 31) if (uloginfo->nlgroup > 31)
return false; return -EINVAL;
uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0'; uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0';
if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN) if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN)
uloginfo->qthreshold = EBT_ULOG_MAX_QLEN; uloginfo->qthreshold = EBT_ULOG_MAX_QLEN;
return true; return 0;
} }
static struct xt_target ebt_ulog_tg_reg __read_mostly = { static struct xt_target ebt_ulog_tg_reg __read_mostly = {
@ -292,8 +287,8 @@ static int __init ebt_ulog_init(void)
int i; int i;
if (nlbufsiz >= 128*1024) { if (nlbufsiz >= 128*1024) {
printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB," pr_warning("Netlink buffer has to be <= 128kB,"
" please try a smaller nlbufsiz parameter.\n"); " please try a smaller nlbufsiz parameter.\n");
return -EINVAL; return -EINVAL;
} }
@ -306,13 +301,10 @@ static int __init ebt_ulog_init(void)
ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
EBT_ULOG_MAXNLGROUPS, NULL, NULL, EBT_ULOG_MAXNLGROUPS, NULL, NULL,
THIS_MODULE); THIS_MODULE);
if (!ebtulognl) { if (!ebtulognl)
printk(KERN_WARNING KBUILD_MODNAME ": out of memory trying to "
"call netlink_kernel_create\n");
ret = -ENOMEM; ret = -ENOMEM;
} else if ((ret = xt_register_target(&ebt_ulog_tg_reg)) != 0) { else if ((ret = xt_register_target(&ebt_ulog_tg_reg)) != 0)
netlink_kernel_release(ebtulognl); netlink_kernel_release(ebtulognl);
}
if (ret == 0) if (ret == 0)
nf_log_register(NFPROTO_BRIDGE, &ebt_ulog_logger); nf_log_register(NFPROTO_BRIDGE, &ebt_ulog_logger);

View File

@ -26,17 +26,12 @@
#include <linux/netfilter_bridge/ebtables.h> #include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_vlan.h> #include <linux/netfilter_bridge/ebt_vlan.h>
static int debug;
#define MODULE_VERS "0.6" #define MODULE_VERS "0.6"
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "debug=1 is turn on debug messages");
MODULE_AUTHOR("Nick Fedchik <nick@fedchik.org.ua>"); MODULE_AUTHOR("Nick Fedchik <nick@fedchik.org.ua>");
MODULE_DESCRIPTION("Ebtables: 802.1Q VLAN tag match"); MODULE_DESCRIPTION("Ebtables: 802.1Q VLAN tag match");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args)
#define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_ #define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_
#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return false; } #define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return false; }
@ -84,32 +79,31 @@ ebt_vlan_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par) static int ebt_vlan_mt_check(const struct xt_mtchk_param *par)
{ {
struct ebt_vlan_info *info = par->matchinfo; struct ebt_vlan_info *info = par->matchinfo;
const struct ebt_entry *e = par->entryinfo; const struct ebt_entry *e = par->entryinfo;
/* Is it 802.1Q frame checked? */ /* Is it 802.1Q frame checked? */
if (e->ethproto != htons(ETH_P_8021Q)) { if (e->ethproto != htons(ETH_P_8021Q)) {
DEBUG_MSG pr_debug("passed entry proto %2.4X is not 802.1Q (8100)\n",
("passed entry proto %2.4X is not 802.1Q (8100)\n", ntohs(e->ethproto));
(unsigned short) ntohs(e->ethproto)); return -EINVAL;
return false;
} }
/* Check for bitmask range /* Check for bitmask range
* True if even one bit is out of mask */ * True if even one bit is out of mask */
if (info->bitmask & ~EBT_VLAN_MASK) { if (info->bitmask & ~EBT_VLAN_MASK) {
DEBUG_MSG("bitmask %2X is out of mask (%2X)\n", pr_debug("bitmask %2X is out of mask (%2X)\n",
info->bitmask, EBT_VLAN_MASK); info->bitmask, EBT_VLAN_MASK);
return false; return -EINVAL;
} }
/* Check for inversion flags range */ /* Check for inversion flags range */
if (info->invflags & ~EBT_VLAN_MASK) { if (info->invflags & ~EBT_VLAN_MASK) {
DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n", pr_debug("inversion flags %2X is out of mask (%2X)\n",
info->invflags, EBT_VLAN_MASK); info->invflags, EBT_VLAN_MASK);
return false; return -EINVAL;
} }
/* Reserved VLAN ID (VID) values /* Reserved VLAN ID (VID) values
@ -121,10 +115,9 @@ static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
if (GET_BITMASK(EBT_VLAN_ID)) { if (GET_BITMASK(EBT_VLAN_ID)) {
if (!!info->id) { /* if id!=0 => check vid range */ if (!!info->id) { /* if id!=0 => check vid range */
if (info->id > VLAN_GROUP_ARRAY_LEN) { if (info->id > VLAN_GROUP_ARRAY_LEN) {
DEBUG_MSG pr_debug("id %d is out of range (1-4096)\n",
("id %d is out of range (1-4096)\n", info->id);
info->id); return -EINVAL;
return false;
} }
/* Note: This is valid VLAN-tagged frame point. /* Note: This is valid VLAN-tagged frame point.
* Any value of user_priority are acceptable, * Any value of user_priority are acceptable,
@ -137,9 +130,9 @@ static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
if (GET_BITMASK(EBT_VLAN_PRIO)) { if (GET_BITMASK(EBT_VLAN_PRIO)) {
if ((unsigned char) info->prio > 7) { if ((unsigned char) info->prio > 7) {
DEBUG_MSG("prio %d is out of range (0-7)\n", pr_debug("prio %d is out of range (0-7)\n",
info->prio); info->prio);
return false; return -EINVAL;
} }
} }
/* Check for encapsulated proto range - it is possible to be /* Check for encapsulated proto range - it is possible to be
@ -147,14 +140,13 @@ static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
* if_ether.h: ETH_ZLEN 60 - Min. octets in frame sans FCS */ * if_ether.h: ETH_ZLEN 60 - Min. octets in frame sans FCS */
if (GET_BITMASK(EBT_VLAN_ENCAP)) { if (GET_BITMASK(EBT_VLAN_ENCAP)) {
if ((unsigned short) ntohs(info->encap) < ETH_ZLEN) { if ((unsigned short) ntohs(info->encap) < ETH_ZLEN) {
DEBUG_MSG pr_debug("encap frame length %d is less than "
("encap frame length %d is less than minimal\n", "minimal\n", ntohs(info->encap));
ntohs(info->encap)); return -EINVAL;
return false;
} }
} }
return true; return 0;
} }
static struct xt_match ebt_vlan_mt_reg __read_mostly = { static struct xt_match ebt_vlan_mt_reg __read_mostly = {
@ -169,9 +161,7 @@ static struct xt_match ebt_vlan_mt_reg __read_mostly = {
static int __init ebt_vlan_init(void) static int __init ebt_vlan_init(void)
{ {
DEBUG_MSG("ebtables 802.1Q extension module v" pr_debug("ebtables 802.1Q extension module v" MODULE_VERS "\n");
MODULE_VERS "\n");
DEBUG_MSG("module debug=%d\n", !!debug);
return xt_register_match(&ebt_vlan_mt_reg); return xt_register_match(&ebt_vlan_mt_reg);
} }

View File

@ -14,8 +14,7 @@
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
@ -363,12 +362,9 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par,
left - sizeof(struct ebt_entry_match) < m->match_size) left - sizeof(struct ebt_entry_match) < m->match_size)
return -EINVAL; return -EINVAL;
match = try_then_request_module(xt_find_match(NFPROTO_BRIDGE, match = xt_request_find_match(NFPROTO_BRIDGE, m->u.name, 0);
m->u.name, 0), "ebt_%s", m->u.name);
if (IS_ERR(match)) if (IS_ERR(match))
return PTR_ERR(match); return PTR_ERR(match);
if (match == NULL)
return -ENOENT;
m->u.match = match; m->u.match = match;
par->match = match; par->match = match;
@ -397,13 +393,9 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par,
left - sizeof(struct ebt_entry_watcher) < w->watcher_size) left - sizeof(struct ebt_entry_watcher) < w->watcher_size)
return -EINVAL; return -EINVAL;
watcher = try_then_request_module( watcher = xt_request_find_target(NFPROTO_BRIDGE, w->u.name, 0);
xt_find_target(NFPROTO_BRIDGE, w->u.name, 0),
"ebt_%s", w->u.name);
if (IS_ERR(watcher)) if (IS_ERR(watcher))
return PTR_ERR(watcher); return PTR_ERR(watcher);
if (watcher == NULL)
return -ENOENT;
w->u.watcher = watcher; w->u.watcher = watcher;
par->target = watcher; par->target = watcher;
@ -716,15 +708,10 @@ ebt_check_entry(struct ebt_entry *e, struct net *net,
t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
gap = e->next_offset - e->target_offset; gap = e->next_offset - e->target_offset;
target = try_then_request_module( target = xt_request_find_target(NFPROTO_BRIDGE, t->u.name, 0);
xt_find_target(NFPROTO_BRIDGE, t->u.name, 0),
"ebt_%s", t->u.name);
if (IS_ERR(target)) { if (IS_ERR(target)) {
ret = PTR_ERR(target); ret = PTR_ERR(target);
goto cleanup_watchers; goto cleanup_watchers;
} else if (target == NULL) {
ret = -ENOENT;
goto cleanup_watchers;
} }
t->u.target = target; t->u.target = target;
@ -2128,7 +2115,7 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base,
return ret; return ret;
new_offset += ret; new_offset += ret;
if (offsets_update && new_offset) { if (offsets_update && new_offset) {
pr_debug("ebtables: change offset %d to %d\n", pr_debug("change offset %d to %d\n",
offsets_update[i], offsets[j] + new_offset); offsets_update[i], offsets[j] + new_offset);
offsets_update[i] = offsets[j] + new_offset; offsets_update[i] = offsets[j] + new_offset;
} }

View File

@ -266,7 +266,8 @@ static int dn_long_output(struct sk_buff *skb)
skb_reset_network_header(skb); skb_reset_network_header(skb);
return NF_HOOK(PF_DECnet, NF_DN_POST_ROUTING, skb, NULL, neigh->dev, dn_neigh_output_packet); return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING, skb, NULL,
neigh->dev, dn_neigh_output_packet);
} }
static int dn_short_output(struct sk_buff *skb) static int dn_short_output(struct sk_buff *skb)
@ -305,7 +306,8 @@ static int dn_short_output(struct sk_buff *skb)
skb_reset_network_header(skb); skb_reset_network_header(skb);
return NF_HOOK(PF_DECnet, NF_DN_POST_ROUTING, skb, NULL, neigh->dev, dn_neigh_output_packet); return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING, skb, NULL,
neigh->dev, dn_neigh_output_packet);
} }
/* /*
@ -347,7 +349,8 @@ static int dn_phase3_output(struct sk_buff *skb)
skb_reset_network_header(skb); skb_reset_network_header(skb);
return NF_HOOK(PF_DECnet, NF_DN_POST_ROUTING, skb, NULL, neigh->dev, dn_neigh_output_packet); return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING, skb, NULL,
neigh->dev, dn_neigh_output_packet);
} }
/* /*

View File

@ -810,7 +810,8 @@ free_out:
int dn_nsp_rx(struct sk_buff *skb) int dn_nsp_rx(struct sk_buff *skb)
{ {
return NF_HOOK(PF_DECnet, NF_DN_LOCAL_IN, skb, skb->dev, NULL, dn_nsp_rx_packet); return NF_HOOK(NFPROTO_DECNET, NF_DN_LOCAL_IN, skb, skb->dev, NULL,
dn_nsp_rx_packet);
} }
/* /*

View File

@ -518,7 +518,8 @@ static int dn_route_rx_long(struct sk_buff *skb)
ptr++; ptr++;
cb->hops = *ptr++; /* Visit Count */ cb->hops = *ptr++; /* Visit Count */
return NF_HOOK(PF_DECnet, NF_DN_PRE_ROUTING, skb, skb->dev, NULL, dn_route_rx_packet); return NF_HOOK(NFPROTO_DECNET, NF_DN_PRE_ROUTING, skb, skb->dev, NULL,
dn_route_rx_packet);
drop_it: drop_it:
kfree_skb(skb); kfree_skb(skb);
@ -544,7 +545,8 @@ static int dn_route_rx_short(struct sk_buff *skb)
ptr += 2; ptr += 2;
cb->hops = *ptr & 0x3f; cb->hops = *ptr & 0x3f;
return NF_HOOK(PF_DECnet, NF_DN_PRE_ROUTING, skb, skb->dev, NULL, dn_route_rx_packet); return NF_HOOK(NFPROTO_DECNET, NF_DN_PRE_ROUTING, skb, skb->dev, NULL,
dn_route_rx_packet);
drop_it: drop_it:
kfree_skb(skb); kfree_skb(skb);
@ -646,16 +648,24 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type
switch(flags & DN_RT_CNTL_MSK) { switch(flags & DN_RT_CNTL_MSK) {
case DN_RT_PKT_HELO: case DN_RT_PKT_HELO:
return NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_route_ptp_hello); return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO,
skb, skb->dev, NULL,
dn_route_ptp_hello);
case DN_RT_PKT_L1RT: case DN_RT_PKT_L1RT:
case DN_RT_PKT_L2RT: case DN_RT_PKT_L2RT:
return NF_HOOK(PF_DECnet, NF_DN_ROUTE, skb, skb->dev, NULL, dn_route_discard); return NF_HOOK(NFPROTO_DECNET, NF_DN_ROUTE,
skb, skb->dev, NULL,
dn_route_discard);
case DN_RT_PKT_ERTH: case DN_RT_PKT_ERTH:
return NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_router_hello); return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO,
skb, skb->dev, NULL,
dn_neigh_router_hello);
case DN_RT_PKT_EEDH: case DN_RT_PKT_EEDH:
return NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_endnode_hello); return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO,
skb, skb->dev, NULL,
dn_neigh_endnode_hello);
} }
} else { } else {
if (dn->parms.state != DN_DEV_S_RU) if (dn->parms.state != DN_DEV_S_RU)
@ -704,7 +714,8 @@ static int dn_output(struct sk_buff *skb)
cb->rt_flags |= DN_RT_F_IE; cb->rt_flags |= DN_RT_F_IE;
cb->hops = 0; cb->hops = 0;
return NF_HOOK(PF_DECnet, NF_DN_LOCAL_OUT, skb, NULL, dev, neigh->output); return NF_HOOK(NFPROTO_DECNET, NF_DN_LOCAL_OUT, skb, NULL, dev,
neigh->output);
error: error:
if (net_ratelimit()) if (net_ratelimit())
@ -753,7 +764,8 @@ static int dn_forward(struct sk_buff *skb)
if (rt->rt_flags & RTCF_DOREDIRECT) if (rt->rt_flags & RTCF_DOREDIRECT)
cb->rt_flags |= DN_RT_F_IE; cb->rt_flags |= DN_RT_F_IE;
return NF_HOOK(PF_DECnet, NF_DN_FORWARD, skb, dev, skb->dev, neigh->output); return NF_HOOK(NFPROTO_DECNET, NF_DN_FORWARD, skb, dev, skb->dev,
neigh->output);
drop: drop:
kfree_skb(skb); kfree_skb(skb);

View File

@ -112,8 +112,8 @@ int ip_forward(struct sk_buff *skb)
skb->priority = rt_tos2priority(iph->tos); skb->priority = rt_tos2priority(iph->tos);
return NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, rt->u.dst.dev, return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, skb, skb->dev,
ip_forward_finish); rt->u.dst.dev, ip_forward_finish);
sr_failed: sr_failed:
/* /*

View File

@ -266,7 +266,7 @@ int ip_local_deliver(struct sk_buff *skb)
return 0; return 0;
} }
return NF_HOOK(PF_INET, NF_INET_LOCAL_IN, skb, skb->dev, NULL, return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN, skb, skb->dev, NULL,
ip_local_deliver_finish); ip_local_deliver_finish);
} }
@ -444,7 +444,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
/* Must drop socket now because of tproxy. */ /* Must drop socket now because of tproxy. */
skb_orphan(skb); skb_orphan(skb);
return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, dev, NULL, return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, dev, NULL,
ip_rcv_finish); ip_rcv_finish);
inhdr_error: inhdr_error:

View File

@ -96,8 +96,8 @@ int __ip_local_out(struct sk_buff *skb)
iph->tot_len = htons(skb->len); iph->tot_len = htons(skb->len);
ip_send_check(iph); ip_send_check(iph);
return nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev, return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL,
dst_output); skb_dst(skb)->dev, dst_output);
} }
int ip_local_out(struct sk_buff *skb) int ip_local_out(struct sk_buff *skb)
@ -272,8 +272,8 @@ int ip_mc_output(struct sk_buff *skb)
) { ) {
struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
if (newskb) if (newskb)
NF_HOOK(PF_INET, NF_INET_POST_ROUTING, newskb, NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING,
NULL, newskb->dev, newskb, NULL, newskb->dev,
ip_dev_loopback_xmit); ip_dev_loopback_xmit);
} }
@ -288,12 +288,12 @@ int ip_mc_output(struct sk_buff *skb)
if (rt->rt_flags&RTCF_BROADCAST) { if (rt->rt_flags&RTCF_BROADCAST) {
struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
if (newskb) if (newskb)
NF_HOOK(PF_INET, NF_INET_POST_ROUTING, newskb, NULL, NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, newskb,
newskb->dev, ip_dev_loopback_xmit); NULL, newskb->dev, ip_dev_loopback_xmit);
} }
return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, NULL, skb->dev, return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL,
ip_finish_output, skb->dev, ip_finish_output,
!(IPCB(skb)->flags & IPSKB_REROUTED)); !(IPCB(skb)->flags & IPSKB_REROUTED));
} }
@ -306,7 +306,7 @@ int ip_output(struct sk_buff *skb)
skb->dev = dev; skb->dev = dev;
skb->protocol = htons(ETH_P_IP); skb->protocol = htons(ETH_P_IP);
return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, NULL, dev, return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL, dev,
ip_finish_output, ip_finish_output,
!(IPCB(skb)->flags & IPSKB_REROUTED)); !(IPCB(skb)->flags & IPSKB_REROUTED));
} }
@ -469,6 +469,10 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
hlen = iph->ihl * 4; hlen = iph->ihl * 4;
mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */ mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */
#ifdef CONFIG_BRIDGE_NETFILTER
if (skb->nf_bridge)
mtu -= nf_bridge_mtu_reduction(skb);
#endif
IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE; IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE;
/* When frag_list is given, use it. First, check its validity: /* When frag_list is given, use it. First, check its validity:

View File

@ -1599,7 +1599,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
* not mrouter) cannot join to more than one interface - it will * not mrouter) cannot join to more than one interface - it will
* result in receiving multiple packets. * result in receiving multiple packets.
*/ */
NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, dev, NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, skb, skb->dev, dev,
ipmr_forward_finish); ipmr_forward_finish);
return; return;

View File

@ -523,13 +523,11 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size)
return ret; return ret;
t = arpt_get_target(e); t = arpt_get_target(e);
target = try_then_request_module(xt_find_target(NFPROTO_ARP, target = xt_request_find_target(NFPROTO_ARP, t->u.user.name,
t->u.user.name, t->u.user.revision);
t->u.user.revision), if (IS_ERR(target)) {
"arpt_%s", t->u.user.name);
if (IS_ERR(target) || !target) {
duprintf("find_check_entry: `%s' not found\n", t->u.user.name); duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
ret = target ? PTR_ERR(target) : -ENOENT; ret = PTR_ERR(target);
goto out; goto out;
} }
t->u.kernel.target = target; t->u.kernel.target = target;
@ -651,6 +649,9 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0,
if (ret != 0) if (ret != 0)
break; break;
++i; ++i;
if (strcmp(arpt_get_target(iter)->u.user.name,
XT_ERROR_TARGET) == 0)
++newinfo->stacksize;
} }
duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret); duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret);
if (ret != 0) if (ret != 0)
@ -1252,14 +1253,12 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
entry_offset = (void *)e - (void *)base; entry_offset = (void *)e - (void *)base;
t = compat_arpt_get_target(e); t = compat_arpt_get_target(e);
target = try_then_request_module(xt_find_target(NFPROTO_ARP, target = xt_request_find_target(NFPROTO_ARP, t->u.user.name,
t->u.user.name, t->u.user.revision);
t->u.user.revision), if (IS_ERR(target)) {
"arpt_%s", t->u.user.name);
if (IS_ERR(target) || !target) {
duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
t->u.user.name); t->u.user.name);
ret = target ? PTR_ERR(target) : -ENOENT; ret = PTR_ERR(target);
goto out; goto out;
} }
t->u.kernel.target = target; t->u.kernel.target = target;
@ -1778,8 +1777,7 @@ struct xt_table *arpt_register_table(struct net *net,
{ {
int ret; int ret;
struct xt_table_info *newinfo; struct xt_table_info *newinfo;
struct xt_table_info bootstrap struct xt_table_info bootstrap = {0};
= { 0, 0, 0, { 0 }, { 0 }, { } };
void *loc_cpu_entry; void *loc_cpu_entry;
struct xt_table *new_table; struct xt_table *new_table;

View File

@ -54,7 +54,7 @@ target(struct sk_buff *skb, const struct xt_target_param *par)
return mangle->target; return mangle->target;
} }
static bool checkentry(const struct xt_tgchk_param *par) static int checkentry(const struct xt_tgchk_param *par)
{ {
const struct arpt_mangle *mangle = par->targinfo; const struct arpt_mangle *mangle = par->targinfo;

View File

@ -161,8 +161,7 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
break; break;
case IPQ_COPY_PACKET: case IPQ_COPY_PACKET:
if ((entry->skb->ip_summed == CHECKSUM_PARTIAL || if (entry->skb->ip_summed == CHECKSUM_PARTIAL &&
entry->skb->ip_summed == CHECKSUM_COMPLETE) &&
(*errp = skb_checksum_help(entry->skb))) { (*errp = skb_checksum_help(entry->skb))) {
read_unlock_bh(&queue_lock); read_unlock_bh(&queue_lock);
return NULL; return NULL;

View File

@ -39,13 +39,13 @@ MODULE_DESCRIPTION("IPv4 packet filter");
/*#define DEBUG_IP_FIREWALL_USER*/ /*#define DEBUG_IP_FIREWALL_USER*/
#ifdef DEBUG_IP_FIREWALL #ifdef DEBUG_IP_FIREWALL
#define dprintf(format, args...) printk(format , ## args) #define dprintf(format, args...) pr_info(format , ## args)
#else #else
#define dprintf(format, args...) #define dprintf(format, args...)
#endif #endif
#ifdef DEBUG_IP_FIREWALL_USER #ifdef DEBUG_IP_FIREWALL_USER
#define duprintf(format, args...) printk(format , ## args) #define duprintf(format, args...) pr_info(format , ## args)
#else #else
#define duprintf(format, args...) #define duprintf(format, args...)
#endif #endif
@ -168,8 +168,7 @@ static unsigned int
ipt_error(struct sk_buff *skb, const struct xt_target_param *par) ipt_error(struct sk_buff *skb, const struct xt_target_param *par)
{ {
if (net_ratelimit()) if (net_ratelimit())
printk("ip_tables: error: `%s'\n", pr_info("error: `%s'\n", (const char *)par->targinfo);
(const char *)par->targinfo);
return NF_DROP; return NF_DROP;
} }
@ -322,8 +321,6 @@ ipt_do_table(struct sk_buff *skb,
const struct net_device *out, const struct net_device *out,
struct xt_table *table) struct xt_table *table)
{ {
#define tb_comefrom ((struct ipt_entry *)table_base)->comefrom
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
const struct iphdr *ip; const struct iphdr *ip;
bool hotdrop = false; bool hotdrop = false;
@ -331,7 +328,8 @@ ipt_do_table(struct sk_buff *skb,
unsigned int verdict = NF_DROP; unsigned int verdict = NF_DROP;
const char *indev, *outdev; const char *indev, *outdev;
const void *table_base; const void *table_base;
struct ipt_entry *e, *back; struct ipt_entry *e, **jumpstack;
unsigned int *stackptr, origptr, cpu;
const struct xt_table_info *private; const struct xt_table_info *private;
struct xt_match_param mtpar; struct xt_match_param mtpar;
struct xt_target_param tgpar; struct xt_target_param tgpar;
@ -357,19 +355,23 @@ ipt_do_table(struct sk_buff *skb,
IP_NF_ASSERT(table->valid_hooks & (1 << hook)); IP_NF_ASSERT(table->valid_hooks & (1 << hook));
xt_info_rdlock_bh(); xt_info_rdlock_bh();
private = table->private; private = table->private;
table_base = private->entries[smp_processor_id()]; cpu = smp_processor_id();
table_base = private->entries[cpu];
jumpstack = (struct ipt_entry **)private->jumpstack[cpu];
stackptr = &private->stackptr[cpu];
origptr = *stackptr;
e = get_entry(table_base, private->hook_entry[hook]); e = get_entry(table_base, private->hook_entry[hook]);
/* For return from builtin chain */ pr_debug("Entering %s(hook %u); sp at %u (UF %p)\n",
back = get_entry(table_base, private->underflow[hook]); table->name, hook, origptr,
get_entry(table_base, private->underflow[hook]));
do { do {
const struct ipt_entry_target *t; const struct ipt_entry_target *t;
const struct xt_entry_match *ematch; const struct xt_entry_match *ematch;
IP_NF_ASSERT(e); IP_NF_ASSERT(e);
IP_NF_ASSERT(back);
if (!ip_packet_match(ip, indev, outdev, if (!ip_packet_match(ip, indev, outdev,
&e->ip, mtpar.fragoff)) { &e->ip, mtpar.fragoff)) {
no_match: no_match:
@ -404,41 +406,39 @@ ipt_do_table(struct sk_buff *skb,
verdict = (unsigned)(-v) - 1; verdict = (unsigned)(-v) - 1;
break; break;
} }
e = back; if (*stackptr == 0) {
back = get_entry(table_base, back->comefrom); e = get_entry(table_base,
private->underflow[hook]);
pr_debug("Underflow (this is normal) "
"to %p\n", e);
} else {
e = jumpstack[--*stackptr];
pr_debug("Pulled %p out from pos %u\n",
e, *stackptr);
e = ipt_next_entry(e);
}
continue; continue;
} }
if (table_base + v != ipt_next_entry(e) && if (table_base + v != ipt_next_entry(e) &&
!(e->ip.flags & IPT_F_GOTO)) { !(e->ip.flags & IPT_F_GOTO)) {
/* Save old back ptr in next entry */ if (*stackptr >= private->stacksize) {
struct ipt_entry *next = ipt_next_entry(e); verdict = NF_DROP;
next->comefrom = (void *)back - table_base; break;
/* set back pointer to next entry */ }
back = next; jumpstack[(*stackptr)++] = e;
pr_debug("Pushed %p into pos %u\n",
e, *stackptr - 1);
} }
e = get_entry(table_base, v); e = get_entry(table_base, v);
continue; continue;
} }
/* Targets which reenter must return
abs. verdicts */
tgpar.target = t->u.kernel.target; tgpar.target = t->u.kernel.target;
tgpar.targinfo = t->data; tgpar.targinfo = t->data;
#ifdef CONFIG_NETFILTER_DEBUG
tb_comefrom = 0xeeeeeeec;
#endif
verdict = t->u.kernel.target->target(skb, &tgpar); verdict = t->u.kernel.target->target(skb, &tgpar);
#ifdef CONFIG_NETFILTER_DEBUG
if (tb_comefrom != 0xeeeeeeec && verdict == IPT_CONTINUE) {
printk("Target %s reentered!\n",
t->u.kernel.target->name);
verdict = NF_DROP;
}
tb_comefrom = 0x57acc001;
#endif
/* Target might have changed stuff. */ /* Target might have changed stuff. */
ip = ip_hdr(skb); ip = ip_hdr(skb);
if (verdict == IPT_CONTINUE) if (verdict == IPT_CONTINUE)
@ -448,7 +448,9 @@ ipt_do_table(struct sk_buff *skb,
break; break;
} while (!hotdrop); } while (!hotdrop);
xt_info_rdunlock_bh(); xt_info_rdunlock_bh();
pr_debug("Exiting %s; resetting sp from %u to %u\n",
__func__, *stackptr, origptr);
*stackptr = origptr;
#ifdef DEBUG_ALLOW_ALL #ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT; return NF_ACCEPT;
#else #else
@ -456,8 +458,6 @@ ipt_do_table(struct sk_buff *skb,
return NF_DROP; return NF_DROP;
else return verdict; else return verdict;
#endif #endif
#undef tb_comefrom
} }
/* Figures out from what hook each rule can be called: returns 0 if /* Figures out from what hook each rule can be called: returns 0 if
@ -591,7 +591,7 @@ check_entry(const struct ipt_entry *e, const char *name)
const struct ipt_entry_target *t; const struct ipt_entry_target *t;
if (!ip_checkentry(&e->ip)) { if (!ip_checkentry(&e->ip)) {
duprintf("ip_tables: ip check failed %p %s.\n", e, name); duprintf("ip check failed %p %s.\n", e, name);
return -EINVAL; return -EINVAL;
} }
@ -618,8 +618,7 @@ check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par)
ret = xt_check_match(par, m->u.match_size - sizeof(*m), ret = xt_check_match(par, m->u.match_size - sizeof(*m),
ip->proto, ip->invflags & IPT_INV_PROTO); ip->proto, ip->invflags & IPT_INV_PROTO);
if (ret < 0) { if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n", duprintf("check failed for `%s'.\n", par.match->name);
par.match->name);
return ret; return ret;
} }
return 0; return 0;
@ -631,12 +630,11 @@ find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par)
struct xt_match *match; struct xt_match *match;
int ret; int ret;
match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name,
m->u.user.revision), m->u.user.revision);
"ipt_%s", m->u.user.name); if (IS_ERR(match)) {
if (IS_ERR(match) || !match) {
duprintf("find_check_match: `%s' not found\n", m->u.user.name); duprintf("find_check_match: `%s' not found\n", m->u.user.name);
return match ? PTR_ERR(match) : -ENOENT; return PTR_ERR(match);
} }
m->u.kernel.match = match; m->u.kernel.match = match;
@ -667,7 +665,7 @@ static int check_target(struct ipt_entry *e, struct net *net, const char *name)
ret = xt_check_target(&par, t->u.target_size - sizeof(*t), ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
e->ip.proto, e->ip.invflags & IPT_INV_PROTO); e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
if (ret < 0) { if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n", duprintf("check failed for `%s'.\n",
t->u.kernel.target->name); t->u.kernel.target->name);
return ret; return ret;
} }
@ -703,13 +701,11 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
} }
t = ipt_get_target(e); t = ipt_get_target(e);
target = try_then_request_module(xt_find_target(AF_INET, target = xt_request_find_target(NFPROTO_IPV4, t->u.user.name,
t->u.user.name, t->u.user.revision);
t->u.user.revision), if (IS_ERR(target)) {
"ipt_%s", t->u.user.name);
if (IS_ERR(target) || !target) {
duprintf("find_check_entry: `%s' not found\n", t->u.user.name); duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
ret = target ? PTR_ERR(target) : -ENOENT; ret = PTR_ERR(target);
goto cleanup_matches; goto cleanup_matches;
} }
t->u.kernel.target = target; t->u.kernel.target = target;
@ -843,6 +839,9 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
if (ret != 0) if (ret != 0)
return ret; return ret;
++i; ++i;
if (strcmp(ipt_get_target(iter)->u.user.name,
XT_ERROR_TARGET) == 0)
++newinfo->stacksize;
} }
if (i != repl->num_entries) { if (i != repl->num_entries) {
@ -1311,7 +1310,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
if (ret != 0) if (ret != 0)
goto free_newinfo; goto free_newinfo;
duprintf("ip_tables: Translated table\n"); duprintf("Translated table\n");
ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo, ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, tmp.counters); tmp.num_counters, tmp.counters);
@ -1476,13 +1475,12 @@ compat_find_calc_match(struct ipt_entry_match *m,
{ {
struct xt_match *match; struct xt_match *match;
match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name,
m->u.user.revision), m->u.user.revision);
"ipt_%s", m->u.user.name); if (IS_ERR(match)) {
if (IS_ERR(match) || !match) {
duprintf("compat_check_calc_match: `%s' not found\n", duprintf("compat_check_calc_match: `%s' not found\n",
m->u.user.name); m->u.user.name);
return match ? PTR_ERR(match) : -ENOENT; return PTR_ERR(match);
} }
m->u.kernel.match = match; m->u.kernel.match = match;
*size += xt_compat_match_offset(match); *size += xt_compat_match_offset(match);
@ -1549,14 +1547,12 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
} }
t = compat_ipt_get_target(e); t = compat_ipt_get_target(e);
target = try_then_request_module(xt_find_target(AF_INET, target = xt_request_find_target(NFPROTO_IPV4, t->u.user.name,
t->u.user.name, t->u.user.revision);
t->u.user.revision), if (IS_ERR(target)) {
"ipt_%s", t->u.user.name);
if (IS_ERR(target) || !target) {
duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
t->u.user.name); t->u.user.name);
ret = target ? PTR_ERR(target) : -ENOENT; ret = PTR_ERR(target);
goto release_matches; goto release_matches;
} }
t->u.kernel.target = target; t->u.kernel.target = target;
@ -2094,8 +2090,7 @@ struct xt_table *ipt_register_table(struct net *net,
{ {
int ret; int ret;
struct xt_table_info *newinfo; struct xt_table_info *newinfo;
struct xt_table_info bootstrap struct xt_table_info bootstrap = {0};
= { 0, 0, 0, { 0 }, { 0 }, { } };
void *loc_cpu_entry; void *loc_cpu_entry;
struct xt_table *new_table; struct xt_table *new_table;
@ -2184,12 +2179,12 @@ icmp_match(const struct sk_buff *skb, const struct xt_match_param *par)
!!(icmpinfo->invflags&IPT_ICMP_INV)); !!(icmpinfo->invflags&IPT_ICMP_INV));
} }
static bool icmp_checkentry(const struct xt_mtchk_param *par) static int icmp_checkentry(const struct xt_mtchk_param *par)
{ {
const struct ipt_icmp *icmpinfo = par->matchinfo; const struct ipt_icmp *icmpinfo = par->matchinfo;
/* Must specify no unknown invflags */ /* Must specify no unknown invflags */
return !(icmpinfo->invflags & ~IPT_ICMP_INV); return (icmpinfo->invflags & ~IPT_ICMP_INV) ? -EINVAL : 0;
} }
/* The built-in targets: standard (NULL) and error. */ /* The built-in targets: standard (NULL) and error. */
@ -2276,7 +2271,7 @@ static int __init ip_tables_init(void)
if (ret < 0) if (ret < 0)
goto err5; goto err5;
printk(KERN_INFO "ip_tables: (C) 2000-2006 Netfilter Core Team\n"); pr_info("(C) 2000-2006 Netfilter Core Team\n");
return 0; return 0;
err5: err5:

View File

@ -9,6 +9,7 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/jhash.h> #include <linux/jhash.h>
@ -239,8 +240,7 @@ clusterip_hashfn(const struct sk_buff *skb,
break; break;
default: default:
if (net_ratelimit()) if (net_ratelimit())
printk(KERN_NOTICE "CLUSTERIP: unknown protocol `%u'\n", pr_info("unknown protocol %u\n", iph->protocol);
iph->protocol);
sport = dport = 0; sport = dport = 0;
} }
@ -262,7 +262,7 @@ clusterip_hashfn(const struct sk_buff *skb,
hashval = 0; hashval = 0;
/* This cannot happen, unless the check function wasn't called /* This cannot happen, unless the check function wasn't called
* at rule load time */ * at rule load time */
printk("CLUSTERIP: unknown mode `%u'\n", config->hash_mode); pr_info("unknown mode %u\n", config->hash_mode);
BUG(); BUG();
break; break;
} }
@ -295,7 +295,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par)
ct = nf_ct_get(skb, &ctinfo); ct = nf_ct_get(skb, &ctinfo);
if (ct == NULL) { if (ct == NULL) {
printk(KERN_ERR "CLUSTERIP: no conntrack!\n"); pr_info("no conntrack!\n");
/* FIXME: need to drop invalid ones, since replies /* FIXME: need to drop invalid ones, since replies
* to outgoing connections of other nodes will be * to outgoing connections of other nodes will be
* marked as INVALID */ * marked as INVALID */
@ -348,25 +348,24 @@ clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par)
return XT_CONTINUE; return XT_CONTINUE;
} }
static bool clusterip_tg_check(const struct xt_tgchk_param *par) static int clusterip_tg_check(const struct xt_tgchk_param *par)
{ {
struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
const struct ipt_entry *e = par->entryinfo; const struct ipt_entry *e = par->entryinfo;
struct clusterip_config *config; struct clusterip_config *config;
int ret;
if (cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP && if (cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP &&
cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT && cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT &&
cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) { cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) {
printk(KERN_WARNING "CLUSTERIP: unknown mode `%u'\n", pr_info("unknown mode %u\n", cipinfo->hash_mode);
cipinfo->hash_mode); return -EINVAL;
return false;
} }
if (e->ip.dmsk.s_addr != htonl(0xffffffff) || if (e->ip.dmsk.s_addr != htonl(0xffffffff) ||
e->ip.dst.s_addr == 0) { e->ip.dst.s_addr == 0) {
printk(KERN_ERR "CLUSTERIP: Please specify destination IP\n"); pr_info("Please specify destination IP\n");
return false; return -EINVAL;
} }
/* FIXME: further sanity checks */ /* FIXME: further sanity checks */
@ -374,41 +373,41 @@ static bool clusterip_tg_check(const struct xt_tgchk_param *par)
config = clusterip_config_find_get(e->ip.dst.s_addr, 1); config = clusterip_config_find_get(e->ip.dst.s_addr, 1);
if (!config) { if (!config) {
if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) { if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) {
printk(KERN_WARNING "CLUSTERIP: no config found for %pI4, need 'new'\n", &e->ip.dst.s_addr); pr_info("no config found for %pI4, need 'new'\n",
return false; &e->ip.dst.s_addr);
return -EINVAL;
} else { } else {
struct net_device *dev; struct net_device *dev;
if (e->ip.iniface[0] == '\0') { if (e->ip.iniface[0] == '\0') {
printk(KERN_WARNING "CLUSTERIP: Please specify an interface name\n"); pr_info("Please specify an interface name\n");
return false; return -EINVAL;
} }
dev = dev_get_by_name(&init_net, e->ip.iniface); dev = dev_get_by_name(&init_net, e->ip.iniface);
if (!dev) { if (!dev) {
printk(KERN_WARNING "CLUSTERIP: no such interface %s\n", e->ip.iniface); pr_info("no such interface %s\n",
return false; e->ip.iniface);
return -ENOENT;
} }
config = clusterip_config_init(cipinfo, config = clusterip_config_init(cipinfo,
e->ip.dst.s_addr, dev); e->ip.dst.s_addr, dev);
if (!config) { if (!config) {
printk(KERN_WARNING "CLUSTERIP: cannot allocate config\n"); pr_info("cannot allocate config\n");
dev_put(dev); dev_put(dev);
return false; return -ENOMEM;
} }
dev_mc_add(config->dev, config->clustermac); dev_mc_add(config->dev, config->clustermac);
} }
} }
cipinfo->config = config; cipinfo->config = config;
if (nf_ct_l3proto_try_module_get(par->target->family) < 0) { ret = nf_ct_l3proto_try_module_get(par->family);
printk(KERN_WARNING "can't load conntrack support for " if (ret < 0)
"proto=%u\n", par->target->family); pr_info("cannot load conntrack support for proto=%u\n",
return false; par->family);
} return ret;
return true;
} }
/* drop reference count of cluster config when rule is deleted */ /* drop reference count of cluster config when rule is deleted */
@ -422,7 +421,7 @@ static void clusterip_tg_destroy(const struct xt_tgdtor_param *par)
clusterip_config_put(cipinfo->config); clusterip_config_put(cipinfo->config);
nf_ct_l3proto_module_put(par->target->family); nf_ct_l3proto_module_put(par->family);
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
@ -479,8 +478,8 @@ static void arp_print(struct arp_payload *payload)
} }
hbuffer[--k]='\0'; hbuffer[--k]='\0';
printk("src %pI4@%s, dst %pI4\n", pr_debug("src %pI4@%s, dst %pI4\n",
&payload->src_ip, hbuffer, &payload->dst_ip); &payload->src_ip, hbuffer, &payload->dst_ip);
} }
#endif #endif
@ -519,7 +518,7 @@ arp_mangle(unsigned int hook,
* this wouldn't work, since we didn't subscribe the mcast group on * this wouldn't work, since we didn't subscribe the mcast group on
* other interfaces */ * other interfaces */
if (c->dev != out) { if (c->dev != out) {
pr_debug("CLUSTERIP: not mangling arp reply on different " pr_debug("not mangling arp reply on different "
"interface: cip'%s'-skb'%s'\n", "interface: cip'%s'-skb'%s'\n",
c->dev->name, out->name); c->dev->name, out->name);
clusterip_config_put(c); clusterip_config_put(c);
@ -530,7 +529,7 @@ arp_mangle(unsigned int hook,
memcpy(payload->src_hw, c->clustermac, arp->ar_hln); memcpy(payload->src_hw, c->clustermac, arp->ar_hln);
#ifdef DEBUG #ifdef DEBUG
pr_debug(KERN_DEBUG "CLUSTERIP mangled arp reply: "); pr_debug("mangled arp reply: ");
arp_print(payload); arp_print(payload);
#endif #endif
@ -601,7 +600,8 @@ static void *clusterip_seq_next(struct seq_file *s, void *v, loff_t *pos)
static void clusterip_seq_stop(struct seq_file *s, void *v) static void clusterip_seq_stop(struct seq_file *s, void *v)
{ {
kfree(v); if (!IS_ERR(v))
kfree(v);
} }
static int clusterip_seq_show(struct seq_file *s, void *v) static int clusterip_seq_show(struct seq_file *s, void *v)
@ -706,13 +706,13 @@ static int __init clusterip_tg_init(void)
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", init_net.proc_net); clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", init_net.proc_net);
if (!clusterip_procdir) { if (!clusterip_procdir) {
printk(KERN_ERR "CLUSTERIP: Unable to proc dir entry\n"); pr_err("Unable to proc dir entry\n");
ret = -ENOMEM; ret = -ENOMEM;
goto cleanup_hook; goto cleanup_hook;
} }
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
printk(KERN_NOTICE "ClusterIP Version %s loaded successfully\n", pr_info("ClusterIP Version %s loaded successfully\n",
CLUSTERIP_VERSION); CLUSTERIP_VERSION);
return 0; return 0;
@ -727,8 +727,7 @@ cleanup_target:
static void __exit clusterip_tg_exit(void) static void __exit clusterip_tg_exit(void)
{ {
printk(KERN_NOTICE "ClusterIP Version %s unloading\n", pr_info("ClusterIP Version %s unloading\n", CLUSTERIP_VERSION);
CLUSTERIP_VERSION);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent); remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent);
#endif #endif

View File

@ -6,7 +6,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/in.h> #include <linux/in.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
@ -93,28 +93,25 @@ ecn_tg(struct sk_buff *skb, const struct xt_target_param *par)
return XT_CONTINUE; return XT_CONTINUE;
} }
static bool ecn_tg_check(const struct xt_tgchk_param *par) static int ecn_tg_check(const struct xt_tgchk_param *par)
{ {
const struct ipt_ECN_info *einfo = par->targinfo; const struct ipt_ECN_info *einfo = par->targinfo;
const struct ipt_entry *e = par->entryinfo; const struct ipt_entry *e = par->entryinfo;
if (einfo->operation & IPT_ECN_OP_MASK) { if (einfo->operation & IPT_ECN_OP_MASK) {
printk(KERN_WARNING "ECN: unsupported ECN operation %x\n", pr_info("unsupported ECN operation %x\n", einfo->operation);
einfo->operation); return -EINVAL;
return false;
} }
if (einfo->ip_ect & ~IPT_ECN_IP_MASK) { if (einfo->ip_ect & ~IPT_ECN_IP_MASK) {
printk(KERN_WARNING "ECN: new ECT codepoint %x out of mask\n", pr_info("new ECT codepoint %x out of mask\n", einfo->ip_ect);
einfo->ip_ect); return -EINVAL;
return false;
} }
if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) && if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) &&
(e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) { (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) {
printk(KERN_WARNING "ECN: cannot use TCP operations on a " pr_info("cannot use TCP operations on a non-tcp rule\n");
"non-tcp rule\n"); return -EINVAL;
return false;
} }
return true; return 0;
} }
static struct xt_target ecn_tg_reg __read_mostly = { static struct xt_target ecn_tg_reg __read_mostly = {

View File

@ -9,7 +9,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
@ -367,7 +367,7 @@ static struct nf_loginfo default_loginfo = {
.type = NF_LOG_TYPE_LOG, .type = NF_LOG_TYPE_LOG,
.u = { .u = {
.log = { .log = {
.level = 0, .level = 5,
.logflags = NF_LOG_MASK, .logflags = NF_LOG_MASK,
}, },
}, },
@ -439,20 +439,19 @@ log_tg(struct sk_buff *skb, const struct xt_target_param *par)
return XT_CONTINUE; return XT_CONTINUE;
} }
static bool log_tg_check(const struct xt_tgchk_param *par) static int log_tg_check(const struct xt_tgchk_param *par)
{ {
const struct ipt_log_info *loginfo = par->targinfo; const struct ipt_log_info *loginfo = par->targinfo;
if (loginfo->level >= 8) { if (loginfo->level >= 8) {
pr_debug("LOG: level %u >= 8\n", loginfo->level); pr_debug("level %u >= 8\n", loginfo->level);
return false; return -EINVAL;
} }
if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') { if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
pr_debug("LOG: prefix term %i\n", pr_debug("prefix is not null-terminated\n");
loginfo->prefix[sizeof(loginfo->prefix)-1]); return -EINVAL;
return false;
} }
return true; return 0;
} }
static struct xt_target log_tg_reg __read_mostly = { static struct xt_target log_tg_reg __read_mostly = {

View File

@ -8,7 +8,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/types.h> #include <linux/types.h>
#include <linux/inetdevice.h> #include <linux/inetdevice.h>
#include <linux/ip.h> #include <linux/ip.h>
@ -28,19 +28,19 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
MODULE_DESCRIPTION("Xtables: automatic-address SNAT"); MODULE_DESCRIPTION("Xtables: automatic-address SNAT");
/* FIXME: Multiple targets. --RR */ /* FIXME: Multiple targets. --RR */
static bool masquerade_tg_check(const struct xt_tgchk_param *par) static int masquerade_tg_check(const struct xt_tgchk_param *par)
{ {
const struct nf_nat_multi_range_compat *mr = par->targinfo; const struct nf_nat_multi_range_compat *mr = par->targinfo;
if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
pr_debug("masquerade_check: bad MAP_IPS.\n"); pr_debug("bad MAP_IPS.\n");
return false; return -EINVAL;
} }
if (mr->rangesize != 1) { if (mr->rangesize != 1) {
pr_debug("masquerade_check: bad rangesize %u\n", mr->rangesize); pr_debug("bad rangesize %u\n", mr->rangesize);
return false; return -EINVAL;
} }
return true; return 0;
} }
static unsigned int static unsigned int
@ -72,7 +72,7 @@ masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par)
rt = skb_rtable(skb); rt = skb_rtable(skb);
newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE); newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
if (!newsrc) { if (!newsrc) {
printk("MASQUERADE: %s ate my IP address\n", par->out->name); pr_info("%s ate my IP address\n", par->out->name);
return NF_DROP; return NF_DROP;
} }

View File

@ -9,7 +9,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
@ -22,19 +22,19 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets"); MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets");
static bool netmap_tg_check(const struct xt_tgchk_param *par) static int netmap_tg_check(const struct xt_tgchk_param *par)
{ {
const struct nf_nat_multi_range_compat *mr = par->targinfo; const struct nf_nat_multi_range_compat *mr = par->targinfo;
if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
pr_debug("NETMAP:check: bad MAP_IPS.\n"); pr_debug("bad MAP_IPS.\n");
return false; return -EINVAL;
} }
if (mr->rangesize != 1) { if (mr->rangesize != 1) {
pr_debug("NETMAP:check: bad rangesize %u.\n", mr->rangesize); pr_debug("bad rangesize %u.\n", mr->rangesize);
return false; return -EINVAL;
} }
return true; return 0;
} }
static unsigned int static unsigned int

View File

@ -6,7 +6,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/types.h> #include <linux/types.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/timer.h> #include <linux/timer.h>
@ -26,19 +26,19 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
/* FIXME: Take multiple ranges --RR */ /* FIXME: Take multiple ranges --RR */
static bool redirect_tg_check(const struct xt_tgchk_param *par) static int redirect_tg_check(const struct xt_tgchk_param *par)
{ {
const struct nf_nat_multi_range_compat *mr = par->targinfo; const struct nf_nat_multi_range_compat *mr = par->targinfo;
if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
pr_debug("redirect_check: bad MAP_IPS.\n"); pr_debug("bad MAP_IPS.\n");
return false; return -EINVAL;
} }
if (mr->rangesize != 1) { if (mr->rangesize != 1) {
pr_debug("redirect_check: bad rangesize %u.\n", mr->rangesize); pr_debug("bad rangesize %u.\n", mr->rangesize);
return false; return -EINVAL;
} }
return true; return 0;
} }
static unsigned int static unsigned int

View File

@ -9,7 +9,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/slab.h> #include <linux/slab.h>
@ -140,9 +140,6 @@ reject_tg(struct sk_buff *skb, const struct xt_target_param *par)
{ {
const struct ipt_reject_info *reject = par->targinfo; const struct ipt_reject_info *reject = par->targinfo;
/* WARNING: This code causes reentry within iptables.
This means that the iptables jump stack is now crap. We
must return an absolute verdict. --RR */
switch (reject->with) { switch (reject->with) {
case IPT_ICMP_NET_UNREACHABLE: case IPT_ICMP_NET_UNREACHABLE:
send_unreach(skb, ICMP_NET_UNREACH); send_unreach(skb, ICMP_NET_UNREACH);
@ -175,23 +172,23 @@ reject_tg(struct sk_buff *skb, const struct xt_target_param *par)
return NF_DROP; return NF_DROP;
} }
static bool reject_tg_check(const struct xt_tgchk_param *par) static int reject_tg_check(const struct xt_tgchk_param *par)
{ {
const struct ipt_reject_info *rejinfo = par->targinfo; const struct ipt_reject_info *rejinfo = par->targinfo;
const struct ipt_entry *e = par->entryinfo; const struct ipt_entry *e = par->entryinfo;
if (rejinfo->with == IPT_ICMP_ECHOREPLY) { if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
printk("ipt_REJECT: ECHOREPLY no longer supported.\n"); pr_info("ECHOREPLY no longer supported.\n");
return false; return -EINVAL;
} else if (rejinfo->with == IPT_TCP_RESET) { } else if (rejinfo->with == IPT_TCP_RESET) {
/* Must specify that it's a TCP packet */ /* Must specify that it's a TCP packet */
if (e->ip.proto != IPPROTO_TCP || if (e->ip.proto != IPPROTO_TCP ||
(e->ip.invflags & XT_INV_PROTO)) { (e->ip.invflags & XT_INV_PROTO)) {
printk("ipt_REJECT: TCP_RESET invalid for non-tcp\n"); pr_info("TCP_RESET invalid for non-tcp\n");
return false; return -EINVAL;
} }
} }
return true; return 0;
} }
static struct xt_target reject_tg_reg __read_mostly = { static struct xt_target reject_tg_reg __read_mostly = {

View File

@ -29,7 +29,7 @@
* Specify, after how many hundredths of a second the queue should be * Specify, after how many hundredths of a second the queue should be
* flushed even if it is not full yet. * flushed even if it is not full yet.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/socket.h> #include <linux/socket.h>
@ -57,8 +57,6 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG);
#define ULOG_NL_EVENT 111 /* Harald's favorite number */ #define ULOG_NL_EVENT 111 /* Harald's favorite number */
#define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */ #define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */
#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0)
static unsigned int nlbufsiz = NLMSG_GOODSIZE; static unsigned int nlbufsiz = NLMSG_GOODSIZE;
module_param(nlbufsiz, uint, 0400); module_param(nlbufsiz, uint, 0400);
MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); MODULE_PARM_DESC(nlbufsiz, "netlink buffer size");
@ -91,12 +89,12 @@ static void ulog_send(unsigned int nlgroupnum)
ulog_buff_t *ub = &ulog_buffers[nlgroupnum]; ulog_buff_t *ub = &ulog_buffers[nlgroupnum];
if (timer_pending(&ub->timer)) { if (timer_pending(&ub->timer)) {
pr_debug("ipt_ULOG: ulog_send: timer was pending, deleting\n"); pr_debug("ulog_send: timer was pending, deleting\n");
del_timer(&ub->timer); del_timer(&ub->timer);
} }
if (!ub->skb) { if (!ub->skb) {
pr_debug("ipt_ULOG: ulog_send: nothing to send\n"); pr_debug("ulog_send: nothing to send\n");
return; return;
} }
@ -105,7 +103,7 @@ static void ulog_send(unsigned int nlgroupnum)
ub->lastnlh->nlmsg_type = NLMSG_DONE; ub->lastnlh->nlmsg_type = NLMSG_DONE;
NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1; NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1;
pr_debug("ipt_ULOG: throwing %d packets to netlink group %u\n", pr_debug("throwing %d packets to netlink group %u\n",
ub->qlen, nlgroupnum + 1); ub->qlen, nlgroupnum + 1);
netlink_broadcast(nflognl, ub->skb, 0, nlgroupnum + 1, GFP_ATOMIC); netlink_broadcast(nflognl, ub->skb, 0, nlgroupnum + 1, GFP_ATOMIC);
@ -118,7 +116,7 @@ static void ulog_send(unsigned int nlgroupnum)
/* timer function to flush queue in flushtimeout time */ /* timer function to flush queue in flushtimeout time */
static void ulog_timer(unsigned long data) static void ulog_timer(unsigned long data)
{ {
pr_debug("ipt_ULOG: timer function called, calling ulog_send\n"); pr_debug("timer function called, calling ulog_send\n");
/* lock to protect against somebody modifying our structure /* lock to protect against somebody modifying our structure
* from ipt_ulog_target at the same time */ * from ipt_ulog_target at the same time */
@ -139,7 +137,7 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
n = max(size, nlbufsiz); n = max(size, nlbufsiz);
skb = alloc_skb(n, GFP_ATOMIC); skb = alloc_skb(n, GFP_ATOMIC);
if (!skb) { if (!skb) {
PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", n); pr_debug("cannot alloc whole buffer %ub!\n", n);
if (n > size) { if (n > size) {
/* try to allocate only as much as we need for /* try to allocate only as much as we need for
@ -147,8 +145,7 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
skb = alloc_skb(size, GFP_ATOMIC); skb = alloc_skb(size, GFP_ATOMIC);
if (!skb) if (!skb)
PRINTR("ipt_ULOG: can't even allocate %ub\n", pr_debug("cannot even allocate %ub\n", size);
size);
} }
} }
@ -199,8 +196,7 @@ static void ipt_ulog_packet(unsigned int hooknum,
goto alloc_failure; goto alloc_failure;
} }
pr_debug("ipt_ULOG: qlen %d, qthreshold %Zu\n", ub->qlen, pr_debug("qlen %d, qthreshold %Zu\n", ub->qlen, loginfo->qthreshold);
loginfo->qthreshold);
/* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */ /* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */
nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT, nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT,
@ -273,11 +269,9 @@ static void ipt_ulog_packet(unsigned int hooknum,
return; return;
nlmsg_failure: nlmsg_failure:
PRINTR("ipt_ULOG: error during NLMSG_PUT\n"); pr_debug("error during NLMSG_PUT\n");
alloc_failure: alloc_failure:
PRINTR("ipt_ULOG: Error building netlink message\n"); pr_debug("Error building netlink message\n");
spin_unlock_bh(&ulog_lock); spin_unlock_bh(&ulog_lock);
} }
@ -314,21 +308,20 @@ static void ipt_logfn(u_int8_t pf,
ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
} }
static bool ulog_tg_check(const struct xt_tgchk_param *par) static int ulog_tg_check(const struct xt_tgchk_param *par)
{ {
const struct ipt_ulog_info *loginfo = par->targinfo; const struct ipt_ulog_info *loginfo = par->targinfo;
if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
pr_debug("ipt_ULOG: prefix term %i\n", pr_debug("prefix not null-terminated\n");
loginfo->prefix[sizeof(loginfo->prefix) - 1]); return -EINVAL;
return false;
} }
if (loginfo->qthreshold > ULOG_MAX_QLEN) { if (loginfo->qthreshold > ULOG_MAX_QLEN) {
pr_debug("ipt_ULOG: queue threshold %Zu > MAX_QLEN\n", pr_debug("queue threshold %Zu > MAX_QLEN\n",
loginfo->qthreshold); loginfo->qthreshold);
return false; return -EINVAL;
} }
return true; return 0;
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
@ -390,10 +383,10 @@ static int __init ulog_tg_init(void)
{ {
int ret, i; int ret, i;
pr_debug("ipt_ULOG: init module\n"); pr_debug("init module\n");
if (nlbufsiz > 128*1024) { if (nlbufsiz > 128*1024) {
printk("Netlink buffer has to be <= 128kB\n"); pr_warning("Netlink buffer has to be <= 128kB\n");
return -EINVAL; return -EINVAL;
} }
@ -423,7 +416,7 @@ static void __exit ulog_tg_exit(void)
ulog_buff_t *ub; ulog_buff_t *ub;
int i; int i;
pr_debug("ipt_ULOG: cleanup_module\n"); pr_debug("cleanup_module\n");
if (nflog) if (nflog)
nf_log_unregister(&ipt_ulog_logger); nf_log_unregister(&ipt_ulog_logger);

View File

@ -8,7 +8,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
@ -70,34 +70,34 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
return ret; return ret;
} }
static bool addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
{ {
struct ipt_addrtype_info_v1 *info = par->matchinfo; struct ipt_addrtype_info_v1 *info = par->matchinfo;
if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&
info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
printk(KERN_ERR "ipt_addrtype: both incoming and outgoing " pr_info("both incoming and outgoing "
"interface limitation cannot be selected\n"); "interface limitation cannot be selected\n");
return false; return -EINVAL;
} }
if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_LOCAL_IN)) && (1 << NF_INET_LOCAL_IN)) &&
info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
printk(KERN_ERR "ipt_addrtype: output interface limitation " pr_info("output interface limitation "
"not valid in PRE_ROUTING and INPUT\n"); "not valid in PREROUTING and INPUT\n");
return false; return -EINVAL;
} }
if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) | if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
(1 << NF_INET_LOCAL_OUT)) && (1 << NF_INET_LOCAL_OUT)) &&
info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
printk(KERN_ERR "ipt_addrtype: input interface limitation " pr_info("input interface limitation "
"not valid in POST_ROUTING and OUTPUT\n"); "not valid in POSTROUTING and OUTPUT\n");
return false; return -EINVAL;
} }
return true; return 0;
} }
static struct xt_match addrtype_mt_reg[] __read_mostly = { static struct xt_match addrtype_mt_reg[] __read_mostly = {

View File

@ -5,7 +5,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/in.h> #include <linux/in.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
@ -18,21 +18,15 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>"); MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>");
MODULE_DESCRIPTION("Xtables: IPv4 IPsec-AH SPI match"); MODULE_DESCRIPTION("Xtables: IPv4 IPsec-AH SPI match");
#ifdef DEBUG_CONNTRACK
#define duprintf(format, args...) printk(format , ## args)
#else
#define duprintf(format, args...)
#endif
/* Returns 1 if the spi is matched by the range, 0 otherwise */ /* Returns 1 if the spi is matched by the range, 0 otherwise */
static inline bool static inline bool
spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert) spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
{ {
bool r; bool r;
duprintf("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ', pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n",
min,spi,max); invert ? '!' : ' ', min, spi, max);
r=(spi >= min && spi <= max) ^ invert; r=(spi >= min && spi <= max) ^ invert;
duprintf(" result %s\n",r? "PASS" : "FAILED"); pr_debug(" result %s\n", r ? "PASS" : "FAILED");
return r; return r;
} }
@ -51,7 +45,7 @@ static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par)
/* We've been asked to examine this packet, and we /* We've been asked to examine this packet, and we
* can't. Hence, no choice but to drop. * can't. Hence, no choice but to drop.
*/ */
duprintf("Dropping evil AH tinygram.\n"); pr_debug("Dropping evil AH tinygram.\n");
*par->hotdrop = true; *par->hotdrop = true;
return 0; return 0;
} }
@ -61,16 +55,16 @@ static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par)
!!(ahinfo->invflags & IPT_AH_INV_SPI)); !!(ahinfo->invflags & IPT_AH_INV_SPI));
} }
static bool ah_mt_check(const struct xt_mtchk_param *par) static int ah_mt_check(const struct xt_mtchk_param *par)
{ {
const struct ipt_ah *ahinfo = par->matchinfo; const struct ipt_ah *ahinfo = par->matchinfo;
/* Must specify no unknown invflags */ /* Must specify no unknown invflags */
if (ahinfo->invflags & ~IPT_AH_INV_MASK) { if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
duprintf("ipt_ah: unknown flags %X\n", ahinfo->invflags); pr_debug("unknown flags %X\n", ahinfo->invflags);
return false; return -EINVAL;
} }
return true; return 0;
} }
static struct xt_match ah_mt_reg __read_mostly = { static struct xt_match ah_mt_reg __read_mostly = {

View File

@ -6,7 +6,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/in.h> #include <linux/in.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <net/ip.h> #include <net/ip.h>
@ -85,25 +85,24 @@ static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par)
return true; return true;
} }
static bool ecn_mt_check(const struct xt_mtchk_param *par) static int ecn_mt_check(const struct xt_mtchk_param *par)
{ {
const struct ipt_ecn_info *info = par->matchinfo; const struct ipt_ecn_info *info = par->matchinfo;
const struct ipt_ip *ip = par->entryinfo; const struct ipt_ip *ip = par->entryinfo;
if (info->operation & IPT_ECN_OP_MATCH_MASK) if (info->operation & IPT_ECN_OP_MATCH_MASK)
return false; return -EINVAL;
if (info->invert & IPT_ECN_OP_MATCH_MASK) if (info->invert & IPT_ECN_OP_MATCH_MASK)
return false; return -EINVAL;
if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) && if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) &&
ip->proto != IPPROTO_TCP) { ip->proto != IPPROTO_TCP) {
printk(KERN_WARNING "ipt_ecn: can't match TCP bits in rule for" pr_info("cannot match TCP bits in rule for non-tcp packets\n");
" non-tcp packets\n"); return -EINVAL;
return false;
} }
return true; return 0;
} }
static struct xt_match ecn_mt_reg __read_mostly = { static struct xt_match ecn_mt_reg __read_mostly = {

View File

@ -336,12 +336,12 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v)
const struct ip_conntrack_stat *st = v; const struct ip_conntrack_stat *st = v;
if (v == SEQ_START_TOKEN) { if (v == SEQ_START_TOKEN) {
seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete\n"); seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete search_restart\n");
return 0; return 0;
} }
seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x " seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x "
"%08x %08x %08x %08x %08x %08x %08x %08x \n", "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
nr_conntracks, nr_conntracks,
st->searched, st->searched,
st->found, st->found,
@ -358,7 +358,8 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v)
st->expect_new, st->expect_new,
st->expect_create, st->expect_create,
st->expect_delete st->expect_delete,
st->search_restart
); );
return 0; return 0;
} }

View File

@ -10,7 +10,6 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/tcp.h> #include <linux/tcp.h>
#include <net/tcp.h> #include <net/tcp.h>

View File

@ -7,6 +7,7 @@
*/ */
/* Everything about the rules for NAT. */ /* Everything about the rules for NAT. */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/types.h> #include <linux/types.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/netfilter.h> #include <linux/netfilter.h>
@ -74,28 +75,28 @@ ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par)
return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST); return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST);
} }
static bool ipt_snat_checkentry(const struct xt_tgchk_param *par) static int ipt_snat_checkentry(const struct xt_tgchk_param *par)
{ {
const struct nf_nat_multi_range_compat *mr = par->targinfo; const struct nf_nat_multi_range_compat *mr = par->targinfo;
/* Must be a valid range */ /* Must be a valid range */
if (mr->rangesize != 1) { if (mr->rangesize != 1) {
printk("SNAT: multiple ranges no longer supported\n"); pr_info("SNAT: multiple ranges no longer supported\n");
return false; return -EINVAL;
} }
return true; return 0;
} }
static bool ipt_dnat_checkentry(const struct xt_tgchk_param *par) static int ipt_dnat_checkentry(const struct xt_tgchk_param *par)
{ {
const struct nf_nat_multi_range_compat *mr = par->targinfo; const struct nf_nat_multi_range_compat *mr = par->targinfo;
/* Must be a valid range */ /* Must be a valid range */
if (mr->rangesize != 1) { if (mr->rangesize != 1) {
printk("DNAT: multiple ranges no longer supported\n"); pr_info("DNAT: multiple ranges no longer supported\n");
return false; return -EINVAL;
} }
return true; return 0;
} }
unsigned int unsigned int

View File

@ -138,9 +138,8 @@ nf_nat_fn(unsigned int hooknum,
ret = nf_nat_rule_find(skb, hooknum, in, out, ret = nf_nat_rule_find(skb, hooknum, in, out,
ct); ct);
if (ret != NF_ACCEPT) { if (ret != NF_ACCEPT)
return ret; return ret;
}
} else } else
pr_debug("Already setup manip %s for ct %p\n", pr_debug("Already setup manip %s for ct %p\n",
maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST", maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",

View File

@ -6,7 +6,6 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/udp.h> #include <linux/udp.h>
#include <net/netfilter/nf_nat_helper.h> #include <net/netfilter/nf_nat_helper.h>

View File

@ -381,8 +381,8 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
icmp_out_count(net, ((struct icmphdr *) icmp_out_count(net, ((struct icmphdr *)
skb_transport_header(skb))->type); skb_transport_header(skb))->type);
err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL,
dst_output); rt->u.dst.dev, dst_output);
if (err > 0) if (err > 0)
err = net_xmit_errno(err); err = net_xmit_errno(err);
if (err) if (err)

View File

@ -61,7 +61,7 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
iph->tot_len = htons(skb->len); iph->tot_len = htons(skb->len);
ip_send_check(iph); ip_send_check(iph);
NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
xfrm4_rcv_encap_finish); xfrm4_rcv_encap_finish);
return 0; return 0;
} }

View File

@ -86,7 +86,7 @@ static int xfrm4_output_finish(struct sk_buff *skb)
int xfrm4_output(struct sk_buff *skb) int xfrm4_output(struct sk_buff *skb)
{ {
return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb,
NULL, skb_dst(skb)->dev, xfrm4_output_finish, NULL, skb_dst(skb)->dev, xfrm4_output_finish,
!(IPCB(skb)->flags & IPSKB_REROUTED)); !(IPCB(skb)->flags & IPSKB_REROUTED));
} }

View File

@ -143,7 +143,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
/* Must drop socket now because of tproxy. */ /* Must drop socket now because of tproxy. */
skb_orphan(skb); skb_orphan(skb);
return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL, return NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, skb, dev, NULL,
ip6_rcv_finish); ip6_rcv_finish);
err: err:
IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INHDRERRORS); IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INHDRERRORS);
@ -236,7 +236,7 @@ discard:
int ip6_input(struct sk_buff *skb) int ip6_input(struct sk_buff *skb)
{ {
return NF_HOOK(PF_INET6, NF_INET_LOCAL_IN, skb, skb->dev, NULL, return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_IN, skb, skb->dev, NULL,
ip6_input_finish); ip6_input_finish);
} }

View File

@ -67,8 +67,8 @@ int __ip6_local_out(struct sk_buff *skb)
len = 0; len = 0;
ipv6_hdr(skb)->payload_len = htons(len); ipv6_hdr(skb)->payload_len = htons(len);
return nf_hook(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev, return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL,
dst_output); skb_dst(skb)->dev, dst_output);
} }
int ip6_local_out(struct sk_buff *skb) int ip6_local_out(struct sk_buff *skb)
@ -83,22 +83,6 @@ int ip6_local_out(struct sk_buff *skb)
} }
EXPORT_SYMBOL_GPL(ip6_local_out); EXPORT_SYMBOL_GPL(ip6_local_out);
static int ip6_output_finish(struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
if (dst->hh)
return neigh_hh_output(dst->hh, skb);
else if (dst->neighbour)
return dst->neighbour->output(skb);
IP6_INC_STATS_BH(dev_net(dst->dev),
ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
kfree_skb(skb);
return -EINVAL;
}
/* dev_loopback_xmit for use with netfilter. */ /* dev_loopback_xmit for use with netfilter. */
static int ip6_dev_loopback_xmit(struct sk_buff *newskb) static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
{ {
@ -112,8 +96,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
return 0; return 0;
} }
static int ip6_finish_output2(struct sk_buff *skb)
static int ip6_output2(struct sk_buff *skb)
{ {
struct dst_entry *dst = skb_dst(skb); struct dst_entry *dst = skb_dst(skb);
struct net_device *dev = dst->dev; struct net_device *dev = dst->dev;
@ -135,8 +118,8 @@ static int ip6_output2(struct sk_buff *skb)
is not supported in any case. is not supported in any case.
*/ */
if (newskb) if (newskb)
NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, newskb, NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING,
NULL, newskb->dev, newskb, NULL, newskb->dev,
ip6_dev_loopback_xmit); ip6_dev_loopback_xmit);
if (ipv6_hdr(skb)->hop_limit == 0) { if (ipv6_hdr(skb)->hop_limit == 0) {
@ -151,8 +134,15 @@ static int ip6_output2(struct sk_buff *skb)
skb->len); skb->len);
} }
return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev, if (dst->hh)
ip6_output_finish); return neigh_hh_output(dst->hh, skb);
else if (dst->neighbour)
return dst->neighbour->output(skb);
IP6_INC_STATS_BH(dev_net(dst->dev),
ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
kfree_skb(skb);
return -EINVAL;
} }
static inline int ip6_skb_dst_mtu(struct sk_buff *skb) static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
@ -163,21 +153,29 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
} }
static int ip6_finish_output(struct sk_buff *skb)
{
if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
dst_allfrag(skb_dst(skb)))
return ip6_fragment(skb, ip6_finish_output2);
else
return ip6_finish_output2(skb);
}
int ip6_output(struct sk_buff *skb) int ip6_output(struct sk_buff *skb)
{ {
struct net_device *dev = skb_dst(skb)->dev;
struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
if (unlikely(idev->cnf.disable_ipv6)) { if (unlikely(idev->cnf.disable_ipv6)) {
IP6_INC_STATS(dev_net(skb_dst(skb)->dev), idev, IP6_INC_STATS(dev_net(dev), idev,
IPSTATS_MIB_OUTDISCARDS); IPSTATS_MIB_OUTDISCARDS);
kfree_skb(skb); kfree_skb(skb);
return 0; return 0;
} }
if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, dev,
dst_allfrag(skb_dst(skb))) ip6_finish_output,
return ip6_fragment(skb, ip6_output2); !(IP6CB(skb)->flags & IP6SKB_REROUTED));
else
return ip6_output2(skb);
} }
/* /*
@ -256,8 +254,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)), IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)),
IPSTATS_MIB_OUT, skb->len); IPSTATS_MIB_OUT, skb->len);
return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL,
dst_output); dst->dev, dst_output);
} }
if (net_ratelimit()) if (net_ratelimit())
@ -533,7 +531,7 @@ int ip6_forward(struct sk_buff *skb)
hdr->hop_limit--; hdr->hop_limit--;
IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS); IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dst->dev, return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, skb, skb->dev, dst->dev,
ip6_forward_finish); ip6_forward_finish);
error: error:

View File

@ -1570,7 +1570,7 @@ static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi)
IP6CB(skb)->flags |= IP6SKB_FORWARDED; IP6CB(skb)->flags |= IP6SKB_FORWARDED;
return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dev, return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, skb, skb->dev, dev,
ip6mr_forward2_finish); ip6mr_forward2_finish);
out_free: out_free:

View File

@ -1428,7 +1428,7 @@ static void mld_sendpack(struct sk_buff *skb)
payload_len = skb->len; payload_len = skb->len;
err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
dst_output); dst_output);
out: out:
if (!err) { if (!err) {
@ -1793,7 +1793,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
goto err_out; goto err_out;
skb_dst_set(skb, dst); skb_dst_set(skb, dst);
err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
dst_output); dst_output);
out: out:
if (!err) { if (!err) {

View File

@ -536,7 +536,7 @@ void ndisc_send_skb(struct sk_buff *skb,
idev = in6_dev_get(dst->dev); idev = in6_dev_get(dst->dev);
IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
dst_output); dst_output);
if (!err) { if (!err) {
ICMP6MSGOUT_INC_STATS(net, idev, type); ICMP6MSGOUT_INC_STATS(net, idev, type);
@ -1618,7 +1618,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
skb_dst_set(buff, dst); skb_dst_set(buff, dst);
idev = in6_dev_get(dst->dev); idev = in6_dev_get(dst->dev);
IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev, err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
dst_output); dst_output);
if (!err) { if (!err) {
ICMP6MSGOUT_INC_STATS(net, idev, NDISC_REDIRECT); ICMP6MSGOUT_INC_STATS(net, idev, NDISC_REDIRECT);

View File

@ -25,20 +25,6 @@ int ip6_route_me_harder(struct sk_buff *skb)
}; };
dst = ip6_route_output(net, skb->sk, &fl); dst = ip6_route_output(net, skb->sk, &fl);
#ifdef CONFIG_XFRM
if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
xfrm_decode_session(skb, &fl, AF_INET6) == 0) {
struct dst_entry *dst2 = skb_dst(skb);
if (xfrm_lookup(net, &dst2, &fl, skb->sk, 0)) {
skb_dst_set(skb, NULL);
return -1;
}
skb_dst_set(skb, dst2);
}
#endif
if (dst->error) { if (dst->error) {
IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
@ -50,6 +36,17 @@ int ip6_route_me_harder(struct sk_buff *skb)
skb_dst_drop(skb); skb_dst_drop(skb);
skb_dst_set(skb, dst); skb_dst_set(skb, dst);
#ifdef CONFIG_XFRM
if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
xfrm_decode_session(skb, &fl, AF_INET6) == 0) {
skb_dst_set(skb, NULL);
if (xfrm_lookup(net, &dst, &fl, skb->sk, 0))
return -1;
skb_dst_set(skb, dst);
}
#endif
return 0; return 0;
} }
EXPORT_SYMBOL(ip6_route_me_harder); EXPORT_SYMBOL(ip6_route_me_harder);

View File

@ -162,8 +162,7 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
break; break;
case IPQ_COPY_PACKET: case IPQ_COPY_PACKET:
if ((entry->skb->ip_summed == CHECKSUM_PARTIAL || if (entry->skb->ip_summed == CHECKSUM_PARTIAL &&
entry->skb->ip_summed == CHECKSUM_COMPLETE) &&
(*errp = skb_checksum_help(entry->skb))) { (*errp = skb_checksum_help(entry->skb))) {
read_unlock_bh(&queue_lock); read_unlock_bh(&queue_lock);
return NULL; return NULL;

View File

@ -40,13 +40,13 @@ MODULE_DESCRIPTION("IPv6 packet filter");
/*#define DEBUG_IP_FIREWALL_USER*/ /*#define DEBUG_IP_FIREWALL_USER*/
#ifdef DEBUG_IP_FIREWALL #ifdef DEBUG_IP_FIREWALL
#define dprintf(format, args...) printk(format , ## args) #define dprintf(format, args...) pr_info(format , ## args)
#else #else
#define dprintf(format, args...) #define dprintf(format, args...)
#endif #endif
#ifdef DEBUG_IP_FIREWALL_USER #ifdef DEBUG_IP_FIREWALL_USER
#define duprintf(format, args...) printk(format , ## args) #define duprintf(format, args...) pr_info(format , ## args)
#else #else
#define duprintf(format, args...) #define duprintf(format, args...)
#endif #endif
@ -200,8 +200,7 @@ static unsigned int
ip6t_error(struct sk_buff *skb, const struct xt_target_param *par) ip6t_error(struct sk_buff *skb, const struct xt_target_param *par)
{ {
if (net_ratelimit()) if (net_ratelimit())
printk("ip6_tables: error: `%s'\n", pr_info("error: `%s'\n", (const char *)par->targinfo);
(const char *)par->targinfo);
return NF_DROP; return NF_DROP;
} }
@ -352,15 +351,14 @@ ip6t_do_table(struct sk_buff *skb,
const struct net_device *out, const struct net_device *out,
struct xt_table *table) struct xt_table *table)
{ {
#define tb_comefrom ((struct ip6t_entry *)table_base)->comefrom
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
bool hotdrop = false; bool hotdrop = false;
/* Initializing verdict to NF_DROP keeps gcc happy. */ /* Initializing verdict to NF_DROP keeps gcc happy. */
unsigned int verdict = NF_DROP; unsigned int verdict = NF_DROP;
const char *indev, *outdev; const char *indev, *outdev;
const void *table_base; const void *table_base;
struct ip6t_entry *e, *back; struct ip6t_entry *e, **jumpstack;
unsigned int *stackptr, origptr, cpu;
const struct xt_table_info *private; const struct xt_table_info *private;
struct xt_match_param mtpar; struct xt_match_param mtpar;
struct xt_target_param tgpar; struct xt_target_param tgpar;
@ -384,19 +382,19 @@ ip6t_do_table(struct sk_buff *skb,
xt_info_rdlock_bh(); xt_info_rdlock_bh();
private = table->private; private = table->private;
table_base = private->entries[smp_processor_id()]; cpu = smp_processor_id();
table_base = private->entries[cpu];
jumpstack = (struct ip6t_entry **)private->jumpstack[cpu];
stackptr = &private->stackptr[cpu];
origptr = *stackptr;
e = get_entry(table_base, private->hook_entry[hook]); e = get_entry(table_base, private->hook_entry[hook]);
/* For return from builtin chain */
back = get_entry(table_base, private->underflow[hook]);
do { do {
const struct ip6t_entry_target *t; const struct ip6t_entry_target *t;
const struct xt_entry_match *ematch; const struct xt_entry_match *ematch;
IP_NF_ASSERT(e); IP_NF_ASSERT(e);
IP_NF_ASSERT(back);
if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, if (!ip6_packet_match(skb, indev, outdev, &e->ipv6,
&mtpar.thoff, &mtpar.fragoff, &hotdrop)) { &mtpar.thoff, &mtpar.fragoff, &hotdrop)) {
no_match: no_match:
@ -433,41 +431,30 @@ ip6t_do_table(struct sk_buff *skb,
verdict = (unsigned)(-v) - 1; verdict = (unsigned)(-v) - 1;
break; break;
} }
e = back; if (*stackptr == 0)
back = get_entry(table_base, back->comefrom); e = get_entry(table_base,
private->underflow[hook]);
else
e = ip6t_next_entry(jumpstack[--*stackptr]);
continue; continue;
} }
if (table_base + v != ip6t_next_entry(e) && if (table_base + v != ip6t_next_entry(e) &&
!(e->ipv6.flags & IP6T_F_GOTO)) { !(e->ipv6.flags & IP6T_F_GOTO)) {
/* Save old back ptr in next entry */ if (*stackptr >= private->stacksize) {
struct ip6t_entry *next = ip6t_next_entry(e); verdict = NF_DROP;
next->comefrom = (void *)back - table_base; break;
/* set back pointer to next entry */ }
back = next; jumpstack[(*stackptr)++] = e;
} }
e = get_entry(table_base, v); e = get_entry(table_base, v);
continue; continue;
} }
/* Targets which reenter must return
abs. verdicts */
tgpar.target = t->u.kernel.target; tgpar.target = t->u.kernel.target;
tgpar.targinfo = t->data; tgpar.targinfo = t->data;
#ifdef CONFIG_NETFILTER_DEBUG
tb_comefrom = 0xeeeeeeec;
#endif
verdict = t->u.kernel.target->target(skb, &tgpar); verdict = t->u.kernel.target->target(skb, &tgpar);
#ifdef CONFIG_NETFILTER_DEBUG
if (tb_comefrom != 0xeeeeeeec && verdict == IP6T_CONTINUE) {
printk("Target %s reentered!\n",
t->u.kernel.target->name);
verdict = NF_DROP;
}
tb_comefrom = 0x57acc001;
#endif
if (verdict == IP6T_CONTINUE) if (verdict == IP6T_CONTINUE)
e = ip6t_next_entry(e); e = ip6t_next_entry(e);
else else
@ -475,10 +462,8 @@ ip6t_do_table(struct sk_buff *skb,
break; break;
} while (!hotdrop); } while (!hotdrop);
#ifdef CONFIG_NETFILTER_DEBUG
tb_comefrom = NETFILTER_LINK_POISON;
#endif
xt_info_rdunlock_bh(); xt_info_rdunlock_bh();
*stackptr = origptr;
#ifdef DEBUG_ALLOW_ALL #ifdef DEBUG_ALLOW_ALL
return NF_ACCEPT; return NF_ACCEPT;
@ -487,8 +472,6 @@ ip6t_do_table(struct sk_buff *skb,
return NF_DROP; return NF_DROP;
else return verdict; else return verdict;
#endif #endif
#undef tb_comefrom
} }
/* Figures out from what hook each rule can be called: returns 0 if /* Figures out from what hook each rule can be called: returns 0 if
@ -661,12 +644,11 @@ find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par)
struct xt_match *match; struct xt_match *match;
int ret; int ret;
match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name, match = xt_request_find_match(NFPROTO_IPV6, m->u.user.name,
m->u.user.revision), m->u.user.revision);
"ip6t_%s", m->u.user.name); if (IS_ERR(match)) {
if (IS_ERR(match) || !match) {
duprintf("find_check_match: `%s' not found\n", m->u.user.name); duprintf("find_check_match: `%s' not found\n", m->u.user.name);
return match ? PTR_ERR(match) : -ENOENT; return PTR_ERR(match);
} }
m->u.kernel.match = match; m->u.kernel.match = match;
@ -734,13 +716,11 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
} }
t = ip6t_get_target(e); t = ip6t_get_target(e);
target = try_then_request_module(xt_find_target(AF_INET6, target = xt_request_find_target(NFPROTO_IPV6, t->u.user.name,
t->u.user.name, t->u.user.revision);
t->u.user.revision), if (IS_ERR(target)) {
"ip6t_%s", t->u.user.name);
if (IS_ERR(target) || !target) {
duprintf("find_check_entry: `%s' not found\n", t->u.user.name); duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
ret = target ? PTR_ERR(target) : -ENOENT; ret = PTR_ERR(target);
goto cleanup_matches; goto cleanup_matches;
} }
t->u.kernel.target = target; t->u.kernel.target = target;
@ -873,6 +853,9 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
if (ret != 0) if (ret != 0)
return ret; return ret;
++i; ++i;
if (strcmp(ip6t_get_target(iter)->u.user.name,
XT_ERROR_TARGET) == 0)
++newinfo->stacksize;
} }
if (i != repl->num_entries) { if (i != repl->num_entries) {
@ -1509,13 +1492,12 @@ compat_find_calc_match(struct ip6t_entry_match *m,
{ {
struct xt_match *match; struct xt_match *match;
match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name, match = xt_request_find_match(NFPROTO_IPV6, m->u.user.name,
m->u.user.revision), m->u.user.revision);
"ip6t_%s", m->u.user.name); if (IS_ERR(match)) {
if (IS_ERR(match) || !match) {
duprintf("compat_check_calc_match: `%s' not found\n", duprintf("compat_check_calc_match: `%s' not found\n",
m->u.user.name); m->u.user.name);
return match ? PTR_ERR(match) : -ENOENT; return PTR_ERR(match);
} }
m->u.kernel.match = match; m->u.kernel.match = match;
*size += xt_compat_match_offset(match); *size += xt_compat_match_offset(match);
@ -1582,14 +1564,12 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
} }
t = compat_ip6t_get_target(e); t = compat_ip6t_get_target(e);
target = try_then_request_module(xt_find_target(AF_INET6, target = xt_request_find_target(NFPROTO_IPV6, t->u.user.name,
t->u.user.name, t->u.user.revision);
t->u.user.revision), if (IS_ERR(target)) {
"ip6t_%s", t->u.user.name);
if (IS_ERR(target) || !target) {
duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
t->u.user.name); t->u.user.name);
ret = target ? PTR_ERR(target) : -ENOENT; ret = PTR_ERR(target);
goto release_matches; goto release_matches;
} }
t->u.kernel.target = target; t->u.kernel.target = target;
@ -2127,8 +2107,7 @@ struct xt_table *ip6t_register_table(struct net *net,
{ {
int ret; int ret;
struct xt_table_info *newinfo; struct xt_table_info *newinfo;
struct xt_table_info bootstrap struct xt_table_info bootstrap = {0};
= { 0, 0, 0, { 0 }, { 0 }, { } };
void *loc_cpu_entry; void *loc_cpu_entry;
struct xt_table *new_table; struct xt_table *new_table;
@ -2216,12 +2195,12 @@ icmp6_match(const struct sk_buff *skb, const struct xt_match_param *par)
} }
/* Called when user tries to insert an entry of this type. */ /* Called when user tries to insert an entry of this type. */
static bool icmp6_checkentry(const struct xt_mtchk_param *par) static int icmp6_checkentry(const struct xt_mtchk_param *par)
{ {
const struct ip6t_icmp *icmpinfo = par->matchinfo; const struct ip6t_icmp *icmpinfo = par->matchinfo;
/* Must specify no unknown invflags */ /* Must specify no unknown invflags */
return !(icmpinfo->invflags & ~IP6T_ICMP_INV); return (icmpinfo->invflags & ~IP6T_ICMP_INV) ? -EINVAL : 0;
} }
/* The built-in targets: standard (NULL) and error. */ /* The built-in targets: standard (NULL) and error. */
@ -2308,7 +2287,7 @@ static int __init ip6_tables_init(void)
if (ret < 0) if (ret < 0)
goto err5; goto err5;
printk(KERN_INFO "ip6_tables: (C) 2000-2006 Netfilter Core Team\n"); pr_info("(C) 2000-2006 Netfilter Core Team\n");
return 0; return 0;
err5: err5:

View File

@ -9,9 +9,8 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/ip.h> #include <linux/ip.h>
@ -378,7 +377,7 @@ static struct nf_loginfo default_loginfo = {
.type = NF_LOG_TYPE_LOG, .type = NF_LOG_TYPE_LOG,
.u = { .u = {
.log = { .log = {
.level = 0, .level = 5,
.logflags = NF_LOG_MASK, .logflags = NF_LOG_MASK,
}, },
}, },
@ -452,20 +451,19 @@ log_tg6(struct sk_buff *skb, const struct xt_target_param *par)
} }
static bool log_tg6_check(const struct xt_tgchk_param *par) static int log_tg6_check(const struct xt_tgchk_param *par)
{ {
const struct ip6t_log_info *loginfo = par->targinfo; const struct ip6t_log_info *loginfo = par->targinfo;
if (loginfo->level >= 8) { if (loginfo->level >= 8) {
pr_debug("LOG: level %u >= 8\n", loginfo->level); pr_debug("level %u >= 8\n", loginfo->level);
return false; return -EINVAL;
} }
if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') { if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
pr_debug("LOG: prefix term %i\n", pr_debug("prefix not null-terminated\n");
loginfo->prefix[sizeof(loginfo->prefix)-1]); return -EINVAL;
return false;
} }
return true; return 0;
} }
static struct xt_target log_tg6_reg __read_mostly = { static struct xt_target log_tg6_reg __read_mostly = {

View File

@ -14,6 +14,7 @@
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/module.h> #include <linux/module.h>
@ -50,7 +51,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) || if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
(!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) { (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
pr_debug("ip6t_REJECT: addr is not unicast.\n"); pr_debug("addr is not unicast.\n");
return; return;
} }
@ -58,7 +59,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data), &proto); tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data), &proto);
if ((tcphoff < 0) || (tcphoff > oldskb->len)) { if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
pr_debug("ip6t_REJECT: Can't get TCP header.\n"); pr_debug("Cannot get TCP header.\n");
return; return;
} }
@ -66,7 +67,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
/* IP header checks: fragment, too short. */ /* IP header checks: fragment, too short. */
if (proto != IPPROTO_TCP || otcplen < sizeof(struct tcphdr)) { if (proto != IPPROTO_TCP || otcplen < sizeof(struct tcphdr)) {
pr_debug("ip6t_REJECT: proto(%d) != IPPROTO_TCP, " pr_debug("proto(%d) != IPPROTO_TCP, "
"or too short. otcplen = %d\n", "or too short. otcplen = %d\n",
proto, otcplen); proto, otcplen);
return; return;
@ -77,14 +78,14 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
/* No RST for RST. */ /* No RST for RST. */
if (otcph.rst) { if (otcph.rst) {
pr_debug("ip6t_REJECT: RST is set\n"); pr_debug("RST is set\n");
return; return;
} }
/* Check checksum. */ /* Check checksum. */
if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP, if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP,
skb_checksum(oldskb, tcphoff, otcplen, 0))) { skb_checksum(oldskb, tcphoff, otcplen, 0))) {
pr_debug("ip6t_REJECT: TCP checksum is invalid\n"); pr_debug("TCP checksum is invalid\n");
return; return;
} }
@ -108,7 +109,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
if (!nskb) { if (!nskb) {
if (net_ratelimit()) if (net_ratelimit())
printk("ip6t_REJECT: Can't alloc skb\n"); pr_debug("cannot alloc skb\n");
dst_release(dst); dst_release(dst);
return; return;
} }
@ -180,9 +181,6 @@ reject_tg6(struct sk_buff *skb, const struct xt_target_param *par)
struct net *net = dev_net((par->in != NULL) ? par->in : par->out); struct net *net = dev_net((par->in != NULL) ? par->in : par->out);
pr_debug("%s: medium point\n", __func__); pr_debug("%s: medium point\n", __func__);
/* WARNING: This code causes reentry within ip6tables.
This means that the ip6tables jump stack is now crap. We
must return an absolute verdict. --RR */
switch (reject->with) { switch (reject->with) {
case IP6T_ICMP6_NO_ROUTE: case IP6T_ICMP6_NO_ROUTE:
send_unreach(net, skb, ICMPV6_NOROUTE, par->hooknum); send_unreach(net, skb, ICMPV6_NOROUTE, par->hooknum);
@ -207,30 +205,30 @@ reject_tg6(struct sk_buff *skb, const struct xt_target_param *par)
break; break;
default: default:
if (net_ratelimit()) if (net_ratelimit())
printk(KERN_WARNING "ip6t_REJECT: case %u not handled yet\n", reject->with); pr_info("case %u not handled yet\n", reject->with);
break; break;
} }
return NF_DROP; return NF_DROP;
} }
static bool reject_tg6_check(const struct xt_tgchk_param *par) static int reject_tg6_check(const struct xt_tgchk_param *par)
{ {
const struct ip6t_reject_info *rejinfo = par->targinfo; const struct ip6t_reject_info *rejinfo = par->targinfo;
const struct ip6t_entry *e = par->entryinfo; const struct ip6t_entry *e = par->entryinfo;
if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) { if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
printk("ip6t_REJECT: ECHOREPLY is not supported.\n"); pr_info("ECHOREPLY is not supported.\n");
return false; return -EINVAL;
} else if (rejinfo->with == IP6T_TCP_RESET) { } else if (rejinfo->with == IP6T_TCP_RESET) {
/* Must specify that it's a TCP packet */ /* Must specify that it's a TCP packet */
if (e->ipv6.proto != IPPROTO_TCP || if (e->ipv6.proto != IPPROTO_TCP ||
(e->ipv6.invflags & XT_INV_PROTO)) { (e->ipv6.invflags & XT_INV_PROTO)) {
printk("ip6t_REJECT: TCP_RESET illegal for non-tcp\n"); pr_info("TCP_RESET illegal for non-tcp\n");
return false; return -EINVAL;
} }
} }
return true; return 0;
} }
static struct xt_target reject_tg6_reg __read_mostly = { static struct xt_target reject_tg6_reg __read_mostly = {

View File

@ -6,7 +6,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/ip.h> #include <linux/ip.h>
@ -29,7 +29,7 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
{ {
bool r; bool r;
pr_debug("ah spi_match:%c 0x%x <= 0x%x <= 0x%x", pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n",
invert ? '!' : ' ', min, spi, max); invert ? '!' : ' ', min, spi, max);
r = (spi >= min && spi <= max) ^ invert; r = (spi >= min && spi <= max) ^ invert;
pr_debug(" result %s\n", r ? "PASS" : "FAILED"); pr_debug(" result %s\n", r ? "PASS" : "FAILED");
@ -87,15 +87,15 @@ static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
!(ahinfo->hdrres && ah->reserved); !(ahinfo->hdrres && ah->reserved);
} }
static bool ah_mt6_check(const struct xt_mtchk_param *par) static int ah_mt6_check(const struct xt_mtchk_param *par)
{ {
const struct ip6t_ah *ahinfo = par->matchinfo; const struct ip6t_ah *ahinfo = par->matchinfo;
if (ahinfo->invflags & ~IP6T_AH_INV_MASK) { if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags); pr_debug("unknown flags %X\n", ahinfo->invflags);
return false; return -EINVAL;
} }
return true; return 0;
} }
static struct xt_match ah_mt6_reg __read_mostly = { static struct xt_match ah_mt6_reg __read_mostly = {

View File

@ -6,7 +6,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/ipv6.h> #include <linux/ipv6.h>
@ -27,7 +27,7 @@ static inline bool
id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert) id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
{ {
bool r; bool r;
pr_debug("frag id_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ', pr_debug("id_match:%c 0x%x <= 0x%x <= 0x%x\n", invert ? '!' : ' ',
min, id, max); min, id, max);
r = (id >= min && id <= max) ^ invert; r = (id >= min && id <= max) ^ invert;
pr_debug(" result %s\n", r ? "PASS" : "FAILED"); pr_debug(" result %s\n", r ? "PASS" : "FAILED");
@ -102,15 +102,15 @@ frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
(ntohs(fh->frag_off) & IP6_MF)); (ntohs(fh->frag_off) & IP6_MF));
} }
static bool frag_mt6_check(const struct xt_mtchk_param *par) static int frag_mt6_check(const struct xt_mtchk_param *par)
{ {
const struct ip6t_frag *fraginfo = par->matchinfo; const struct ip6t_frag *fraginfo = par->matchinfo;
if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) { if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags); pr_debug("unknown flags %X\n", fraginfo->invflags);
return false; return -EINVAL;
} }
return true; return 0;
} }
static struct xt_match frag_mt6_reg __read_mostly = { static struct xt_match frag_mt6_reg __read_mostly = {

View File

@ -6,7 +6,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/ipv6.h> #include <linux/ipv6.h>
@ -41,6 +41,8 @@ MODULE_ALIAS("ip6t_dst");
* 5 -> RTALERT 2 x x * 5 -> RTALERT 2 x x
*/ */
static struct xt_match hbh_mt6_reg[] __read_mostly;
static bool static bool
hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par) hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
{ {
@ -58,7 +60,9 @@ hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
unsigned int optlen; unsigned int optlen;
int err; int err;
err = ipv6_find_hdr(skb, &ptr, par->match->data, NULL); err = ipv6_find_hdr(skb, &ptr,
(par->match == &hbh_mt6_reg[0]) ?
NEXTHDR_HOP : NEXTHDR_DEST, NULL);
if (err < 0) { if (err < 0) {
if (err != -ENOENT) if (err != -ENOENT)
*par->hotdrop = true; *par->hotdrop = true;
@ -160,32 +164,32 @@ hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
return false; return false;
} }
static bool hbh_mt6_check(const struct xt_mtchk_param *par) static int hbh_mt6_check(const struct xt_mtchk_param *par)
{ {
const struct ip6t_opts *optsinfo = par->matchinfo; const struct ip6t_opts *optsinfo = par->matchinfo;
if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) { if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); pr_debug("unknown flags %X\n", optsinfo->invflags);
return false; return -EINVAL;
} }
if (optsinfo->flags & IP6T_OPTS_NSTRICT) { if (optsinfo->flags & IP6T_OPTS_NSTRICT) {
pr_debug("ip6t_opts: Not strict - not implemented"); pr_debug("Not strict - not implemented");
return false; return -EINVAL;
} }
return true; return 0;
} }
static struct xt_match hbh_mt6_reg[] __read_mostly = { static struct xt_match hbh_mt6_reg[] __read_mostly = {
{ {
/* Note, hbh_mt6 relies on the order of hbh_mt6_reg */
.name = "hbh", .name = "hbh",
.family = NFPROTO_IPV6, .family = NFPROTO_IPV6,
.match = hbh_mt6, .match = hbh_mt6,
.matchsize = sizeof(struct ip6t_opts), .matchsize = sizeof(struct ip6t_opts),
.checkentry = hbh_mt6_check, .checkentry = hbh_mt6_check,
.me = THIS_MODULE, .me = THIS_MODULE,
.data = NEXTHDR_HOP,
}, },
{ {
.name = "dst", .name = "dst",
@ -194,7 +198,6 @@ static struct xt_match hbh_mt6_reg[] __read_mostly = {
.matchsize = sizeof(struct ip6t_opts), .matchsize = sizeof(struct ip6t_opts),
.checkentry = hbh_mt6_check, .checkentry = hbh_mt6_check,
.me = THIS_MODULE, .me = THIS_MODULE,
.data = NEXTHDR_DEST,
}, },
}; };

View File

@ -118,16 +118,16 @@ ipv6header_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
} }
} }
static bool ipv6header_mt6_check(const struct xt_mtchk_param *par) static int ipv6header_mt6_check(const struct xt_mtchk_param *par)
{ {
const struct ip6t_ipv6header_info *info = par->matchinfo; const struct ip6t_ipv6header_info *info = par->matchinfo;
/* invflags is 0 or 0xff in hard mode */ /* invflags is 0 or 0xff in hard mode */
if ((!info->modeflag) && info->invflags != 0x00 && if ((!info->modeflag) && info->invflags != 0x00 &&
info->invflags != 0xFF) info->invflags != 0xFF)
return false; return -EINVAL;
return true; return 0;
} }
static struct xt_match ipv6header_mt6_reg __read_mostly = { static struct xt_match ipv6header_mt6_reg __read_mostly = {

View File

@ -11,6 +11,7 @@
* Based on net/netfilter/xt_tcpudp.c * Based on net/netfilter/xt_tcpudp.c
* *
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/types.h> #include <linux/types.h>
#include <linux/module.h> #include <linux/module.h>
#include <net/ip.h> #include <net/ip.h>
@ -24,12 +25,6 @@
MODULE_DESCRIPTION("Xtables: IPv6 Mobility Header match"); MODULE_DESCRIPTION("Xtables: IPv6 Mobility Header match");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#ifdef DEBUG_IP_FIREWALL_USER
#define duprintf(format, args...) printk(format , ## args)
#else
#define duprintf(format, args...)
#endif
/* Returns 1 if the type is matched by the range, 0 otherwise */ /* Returns 1 if the type is matched by the range, 0 otherwise */
static inline bool static inline bool
type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert) type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
@ -51,13 +46,13 @@ static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
if (mh == NULL) { if (mh == NULL) {
/* We've been asked to examine this packet, and we /* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */ can't. Hence, no choice but to drop. */
duprintf("Dropping evil MH tinygram.\n"); pr_debug("Dropping evil MH tinygram.\n");
*par->hotdrop = true; *par->hotdrop = true;
return false; return false;
} }
if (mh->ip6mh_proto != IPPROTO_NONE) { if (mh->ip6mh_proto != IPPROTO_NONE) {
duprintf("Dropping invalid MH Payload Proto: %u\n", pr_debug("Dropping invalid MH Payload Proto: %u\n",
mh->ip6mh_proto); mh->ip6mh_proto);
*par->hotdrop = true; *par->hotdrop = true;
return false; return false;
@ -67,12 +62,12 @@ static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
!!(mhinfo->invflags & IP6T_MH_INV_TYPE)); !!(mhinfo->invflags & IP6T_MH_INV_TYPE));
} }
static bool mh_mt6_check(const struct xt_mtchk_param *par) static int mh_mt6_check(const struct xt_mtchk_param *par)
{ {
const struct ip6t_mh *mhinfo = par->matchinfo; const struct ip6t_mh *mhinfo = par->matchinfo;
/* Must specify no unknown invflags */ /* Must specify no unknown invflags */
return !(mhinfo->invflags & ~IP6T_MH_INV_MASK); return (mhinfo->invflags & ~IP6T_MH_INV_MASK) ? -EINVAL : 0;
} }
static struct xt_match mh_mt6_reg __read_mostly = { static struct xt_match mh_mt6_reg __read_mostly = {

View File

@ -6,7 +6,7 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/ipv6.h> #include <linux/ipv6.h>
@ -29,7 +29,7 @@ static inline bool
segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert) segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
{ {
bool r; bool r;
pr_debug("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x", pr_debug("segsleft_match:%c 0x%x <= 0x%x <= 0x%x\n",
invert ? '!' : ' ', min, id, max); invert ? '!' : ' ', min, id, max);
r = (id >= min && id <= max) ^ invert; r = (id >= min && id <= max) ^ invert;
pr_debug(" result %s\n", r ? "PASS" : "FAILED"); pr_debug(" result %s\n", r ? "PASS" : "FAILED");
@ -183,23 +183,23 @@ static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
return false; return false;
} }
static bool rt_mt6_check(const struct xt_mtchk_param *par) static int rt_mt6_check(const struct xt_mtchk_param *par)
{ {
const struct ip6t_rt *rtinfo = par->matchinfo; const struct ip6t_rt *rtinfo = par->matchinfo;
if (rtinfo->invflags & ~IP6T_RT_INV_MASK) { if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags); pr_debug("unknown flags %X\n", rtinfo->invflags);
return false; return -EINVAL;
} }
if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) && if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) &&
(!(rtinfo->flags & IP6T_RT_TYP) || (!(rtinfo->flags & IP6T_RT_TYP) ||
(rtinfo->rt_type != 0) || (rtinfo->rt_type != 0) ||
(rtinfo->invflags & IP6T_RT_INV_TYP))) { (rtinfo->invflags & IP6T_RT_INV_TYP))) {
pr_debug("`--rt-type 0' required before `--rt-0-*'"); pr_debug("`--rt-type 0' required before `--rt-0-*'");
return false; return -EINVAL;
} }
return true; return 0;
} }
static struct xt_match rt_mt6_reg __read_mostly = { static struct xt_match rt_mt6_reg __read_mostly = {

View File

@ -644,7 +644,7 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
s2 = s->next; s2 = s->next;
s->next = NULL; s->next = NULL;
NF_HOOK_THRESH(PF_INET6, hooknum, s, in, out, okfn, NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, s, in, out, okfn,
NF_IP6_PRI_CONNTRACK_DEFRAG + 1); NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
s = s2; s = s2;
} }

View File

@ -640,8 +640,8 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
goto error_fault; goto error_fault;
IP6_UPD_PO_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len); IP6_UPD_PO_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL,
dst_output); rt->u.dst.dev, dst_output);
if (err > 0) if (err > 0)
err = net_xmit_errno(err); err = net_xmit_errno(err);
if (err) if (err)

View File

@ -42,7 +42,7 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
ipv6_hdr(skb)->payload_len = htons(skb->len); ipv6_hdr(skb)->payload_len = htons(skb->len);
__skb_push(skb, skb->data - skb_network_header(skb)); __skb_push(skb, skb->data - skb_network_header(skb));
NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
ip6_rcv_finish); ip6_rcv_finish);
return -1; return -1;
} }

View File

@ -90,6 +90,6 @@ static int xfrm6_output_finish(struct sk_buff *skb)
int xfrm6_output(struct sk_buff *skb) int xfrm6_output(struct sk_buff *skb)
{ {
return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb_dst(skb)->dev, return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL,
xfrm6_output_finish); skb_dst(skb)->dev, xfrm6_output_finish);
} }

View File

@ -314,8 +314,39 @@ config NETFILTER_XTABLES
if NETFILTER_XTABLES if NETFILTER_XTABLES
comment "Xtables combined modules"
config NETFILTER_XT_MARK
tristate 'nfmark target and match support'
default m if NETFILTER_ADVANCED=n
---help---
This option adds the "MARK" target and "mark" match.
Netfilter mark matching allows you to match packets based on the
"nfmark" value in the packet.
The target allows you to create rules in the "mangle" table which alter
the netfilter mark (nfmark) field associated with the packet.
Prior to routing, the nfmark can influence the routing method (see
"Use netfilter MARK value as routing key") and can also be used by
other subsystems to change their behavior.
config NETFILTER_XT_CONNMARK
tristate 'ctmark target and match support'
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
select NF_CONNTRACK_MARK
---help---
This option adds the "CONNMARK" target and "connmark" match.
Netfilter allows you to store a mark value per connection (a.k.a.
ctmark), similarly to the packet mark (nfmark). Using this
target and match, you can set and match on this mark.
# alphabetically ordered list of targets # alphabetically ordered list of targets
comment "Xtables targets"
config NETFILTER_XT_TARGET_CLASSIFY config NETFILTER_XT_TARGET_CLASSIFY
tristate '"CLASSIFY" target support' tristate '"CLASSIFY" target support'
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
@ -332,15 +363,11 @@ config NETFILTER_XT_TARGET_CONNMARK
tristate '"CONNMARK" target support' tristate '"CONNMARK" target support'
depends on NF_CONNTRACK depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
select NF_CONNTRACK_MARK select NETFILTER_XT_CONNMARK
help ---help---
This option adds a `CONNMARK' target, which allows one to manipulate This is a backwards-compat option for the user's convenience
the connection mark value. Similar to the MARK target, but (e.g. when running oldconfig). It selects
affects the connection mark value rather than the packet mark value. CONFIG_NETFILTER_XT_CONNMARK (combined connmark/CONNMARK module).
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. The module will be called
ipt_CONNMARK. If unsure, say `N'.
config NETFILTER_XT_TARGET_CONNSECMARK config NETFILTER_XT_TARGET_CONNSECMARK
tristate '"CONNSECMARK" target support' tristate '"CONNSECMARK" target support'
@ -423,16 +450,12 @@ config NETFILTER_XT_TARGET_LED
config NETFILTER_XT_TARGET_MARK config NETFILTER_XT_TARGET_MARK
tristate '"MARK" target support' tristate '"MARK" target support'
default m if NETFILTER_ADVANCED=n depends on NETFILTER_ADVANCED
help select NETFILTER_XT_MARK
This option adds a `MARK' target, which allows you to create rules ---help---
in the `mangle' table which alter the netfilter mark (nfmark) field This is a backwards-compat option for the user's convenience
associated with the packet prior to routing. This can change (e.g. when running oldconfig). It selects
the routing method (see `Use netfilter MARK value as routing CONFIG_NETFILTER_XT_MARK (combined mark/MARK module).
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 NETFILTER_XT_TARGET_NFLOG config NETFILTER_XT_TARGET_NFLOG
tristate '"NFLOG" target support' tristate '"NFLOG" target support'
@ -479,6 +502,13 @@ config NETFILTER_XT_TARGET_RATEEST
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_TARGET_TEE
tristate '"TEE" - packet cloning to alternate destiantion'
depends on NETFILTER_ADVANCED
---help---
This option adds a "TEE" target with which a packet can be cloned and
this clone be rerouted to another nexthop.
config NETFILTER_XT_TARGET_TPROXY config NETFILTER_XT_TARGET_TPROXY
tristate '"TPROXY" target support (EXPERIMENTAL)' tristate '"TPROXY" target support (EXPERIMENTAL)'
depends on EXPERIMENTAL depends on EXPERIMENTAL
@ -552,6 +582,10 @@ config NETFILTER_XT_TARGET_TCPOPTSTRIP
This option adds a "TCPOPTSTRIP" target, which allows you to strip This option adds a "TCPOPTSTRIP" target, which allows you to strip
TCP options from TCP packets. TCP options from TCP packets.
# alphabetically ordered list of matches
comment "Xtables matches"
config NETFILTER_XT_MATCH_CLUSTER config NETFILTER_XT_MATCH_CLUSTER
tristate '"cluster" match support' tristate '"cluster" match support'
depends on NF_CONNTRACK depends on NF_CONNTRACK
@ -602,14 +636,11 @@ config NETFILTER_XT_MATCH_CONNMARK
tristate '"connmark" connection mark match support' tristate '"connmark" connection mark match support'
depends on NF_CONNTRACK depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
select NF_CONNTRACK_MARK select NETFILTER_XT_CONNMARK
help ---help---
This option adds a `connmark' match, which allows you to match the This is a backwards-compat option for the user's convenience
connection mark value previously set for the session by `CONNMARK'. (e.g. when running oldconfig). It selects
CONFIG_NETFILTER_XT_CONNMARK (combined connmark/CONNMARK module).
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. The module will be called
ipt_connmark. If unsure, say `N'.
config NETFILTER_XT_MATCH_CONNTRACK config NETFILTER_XT_MATCH_CONNTRACK
tristate '"conntrack" connection tracking match support' tristate '"conntrack" connection tracking match support'
@ -733,13 +764,12 @@ config NETFILTER_XT_MATCH_MAC
config NETFILTER_XT_MATCH_MARK config NETFILTER_XT_MATCH_MARK
tristate '"mark" match support' tristate '"mark" match support'
default m if NETFILTER_ADVANCED=n depends on NETFILTER_ADVANCED
help select NETFILTER_XT_MARK
Netfilter mark matching allows you to match packets based on the ---help---
`nfmark' value in the packet. This can be set by the MARK target This is a backwards-compat option for the user's convenience
(see below). (e.g. when running oldconfig). It selects
CONFIG_NETFILTER_XT_MARK (combined mark/MARK module).
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_MATCH_MULTIPORT config NETFILTER_XT_MATCH_MULTIPORT
tristate '"multiport" Multiple port match support' tristate '"multiport" Multiple port match support'
@ -751,6 +781,19 @@ config NETFILTER_XT_MATCH_MULTIPORT
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_MATCH_OSF
tristate '"osf" Passive OS fingerprint match'
depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
help
This option selects the Passive OS Fingerprinting match module
that allows to passively match the remote operating system by
analyzing incoming TCP SYN packets.
Rules and loading software can be downloaded from
http://www.ioremap.net/projects/osf
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_MATCH_OWNER config NETFILTER_XT_MATCH_OWNER
tristate '"owner" match support' tristate '"owner" match support'
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
@ -836,13 +879,6 @@ config NETFILTER_XT_MATCH_RECENT
Short options are available by using 'iptables -m recent -h' Short options are available by using 'iptables -m recent -h'
Official Website: <http://snowman.net/projects/ipt_recent/> Official Website: <http://snowman.net/projects/ipt_recent/>
config NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
bool 'Enable obsolete /proc/net/ipt_recent'
depends on NETFILTER_XT_MATCH_RECENT && PROC_FS
---help---
This option enables the old /proc/net/ipt_recent interface,
which has been obsoleted by /proc/net/xt_recent.
config NETFILTER_XT_MATCH_SCTP config NETFILTER_XT_MATCH_SCTP
tristate '"sctp" protocol match support (EXPERIMENTAL)' tristate '"sctp" protocol match support (EXPERIMENTAL)'
depends on EXPERIMENTAL depends on EXPERIMENTAL
@ -942,19 +978,6 @@ config NETFILTER_XT_MATCH_U32
Details and examples are in the kernel module source. Details and examples are in the kernel module source.
config NETFILTER_XT_MATCH_OSF
tristate '"osf" Passive OS fingerprint match'
depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
help
This option selects the Passive OS Fingerprinting match module
that allows to passively match the remote operating system by
analyzing incoming TCP SYN packets.
Rules and loading software can be downloaded from
http://www.ioremap.net/projects/osf
To compile it as a module, choose M here. If unsure, say N.
endif # NETFILTER_XTABLES endif # NETFILTER_XTABLES
endmenu endmenu

View File

@ -40,15 +40,17 @@ obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
# generic X tables # generic X tables
obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
# combos
obj-$(CONFIG_NETFILTER_XT_MARK) += xt_mark.o
obj-$(CONFIG_NETFILTER_XT_CONNMARK) += xt_connmark.o
# targets # targets
obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
@ -57,6 +59,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TEE) += xt_TEE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
# matches # matches
@ -64,7 +67,6 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CLUSTER) += xt_cluster.o
obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o
obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o
obj-$(CONFIG_NETFILTER_XT_MATCH_CONNLIMIT) += xt_connlimit.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNLIMIT) += xt_connlimit.o
obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o
obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o
obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o
obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o
@ -76,7 +78,6 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_IPRANGE) += xt_iprange.o
obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o
obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o
obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o
obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o
obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o
obj-$(CONFIG_NETFILTER_XT_MATCH_OSF) += xt_osf.o obj-$(CONFIG_NETFILTER_XT_MATCH_OSF) += xt_osf.o
obj-$(CONFIG_NETFILTER_XT_MATCH_OWNER) += xt_owner.o obj-$(CONFIG_NETFILTER_XT_MATCH_OWNER) += xt_owner.o

View File

@ -209,8 +209,14 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
*/ */
from.ip = n_cp->vaddr.ip; from.ip = n_cp->vaddr.ip;
port = n_cp->vport; port = n_cp->vport;
sprintf(buf, "%u,%u,%u,%u,%u,%u", NIPQUAD(from.ip), snprintf(buf, sizeof(buf), "%u,%u,%u,%u,%u,%u",
(ntohs(port)>>8)&255, ntohs(port)&255); ((unsigned char *)&from.ip)[0],
((unsigned char *)&from.ip)[1],
((unsigned char *)&from.ip)[2],
((unsigned char *)&from.ip)[3],
ntohs(port) >> 8,
ntohs(port) & 0xFF);
buf_len = strlen(buf); buf_len = strlen(buf);
/* /*

View File

@ -167,26 +167,24 @@ ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp,
ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
if (ih == NULL) if (ih == NULL)
sprintf(buf, "%s TRUNCATED", pp->name); sprintf(buf, "TRUNCATED");
else if (ih->frag_off & htons(IP_OFFSET)) else if (ih->frag_off & htons(IP_OFFSET))
sprintf(buf, "%s %pI4->%pI4 frag", sprintf(buf, "%pI4->%pI4 frag", &ih->saddr, &ih->daddr);
pp->name, &ih->saddr, &ih->daddr);
else { else {
__be16 _ports[2], *pptr __be16 _ports[2], *pptr
; ;
pptr = skb_header_pointer(skb, offset + ih->ihl*4, pptr = skb_header_pointer(skb, offset + ih->ihl*4,
sizeof(_ports), _ports); sizeof(_ports), _ports);
if (pptr == NULL) if (pptr == NULL)
sprintf(buf, "%s TRUNCATED %pI4->%pI4", sprintf(buf, "TRUNCATED %pI4->%pI4",
pp->name, &ih->saddr, &ih->daddr); &ih->saddr, &ih->daddr);
else else
sprintf(buf, "%s %pI4:%u->%pI4:%u", sprintf(buf, "%pI4:%u->%pI4:%u",
pp->name,
&ih->saddr, ntohs(pptr[0]), &ih->saddr, ntohs(pptr[0]),
&ih->daddr, ntohs(pptr[1])); &ih->daddr, ntohs(pptr[1]));
} }
pr_debug("%s: %s\n", msg, buf); pr_debug("%s: %s %s\n", msg, pp->name, buf);
} }
#ifdef CONFIG_IP_VS_IPV6 #ifdef CONFIG_IP_VS_IPV6
@ -201,26 +199,24 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp,
ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
if (ih == NULL) if (ih == NULL)
sprintf(buf, "%s TRUNCATED", pp->name); sprintf(buf, "TRUNCATED");
else if (ih->nexthdr == IPPROTO_FRAGMENT) else if (ih->nexthdr == IPPROTO_FRAGMENT)
sprintf(buf, "%s %pI6->%pI6 frag", sprintf(buf, "%pI6->%pI6 frag", &ih->saddr, &ih->daddr);
pp->name, &ih->saddr, &ih->daddr);
else { else {
__be16 _ports[2], *pptr; __be16 _ports[2], *pptr;
pptr = skb_header_pointer(skb, offset + sizeof(struct ipv6hdr), pptr = skb_header_pointer(skb, offset + sizeof(struct ipv6hdr),
sizeof(_ports), _ports); sizeof(_ports), _ports);
if (pptr == NULL) if (pptr == NULL)
sprintf(buf, "%s TRUNCATED %pI6->%pI6", sprintf(buf, "TRUNCATED %pI6->%pI6",
pp->name, &ih->saddr, &ih->daddr); &ih->saddr, &ih->daddr);
else else
sprintf(buf, "%s %pI6:%u->%pI6:%u", sprintf(buf, "%pI6:%u->%pI6:%u",
pp->name,
&ih->saddr, ntohs(pptr[0]), &ih->saddr, ntohs(pptr[0]),
&ih->daddr, ntohs(pptr[1])); &ih->daddr, ntohs(pptr[1]));
} }
pr_debug("%s: %s\n", msg, buf); pr_debug("%s: %s %s\n", msg, pp->name, buf);
} }
#endif #endif

View File

@ -136,12 +136,11 @@ ah_esp_debug_packet_v4(struct ip_vs_protocol *pp, const struct sk_buff *skb,
ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
if (ih == NULL) if (ih == NULL)
sprintf(buf, "%s TRUNCATED", pp->name); sprintf(buf, "TRUNCATED");
else else
sprintf(buf, "%s %pI4->%pI4", sprintf(buf, "%pI4->%pI4", &ih->saddr, &ih->daddr);
pp->name, &ih->saddr, &ih->daddr);
pr_debug("%s: %s\n", msg, buf); pr_debug("%s: %s %s\n", msg, pp->name, buf);
} }
#ifdef CONFIG_IP_VS_IPV6 #ifdef CONFIG_IP_VS_IPV6
@ -154,12 +153,11 @@ ah_esp_debug_packet_v6(struct ip_vs_protocol *pp, const struct sk_buff *skb,
ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
if (ih == NULL) if (ih == NULL)
sprintf(buf, "%s TRUNCATED", pp->name); sprintf(buf, "TRUNCATED");
else else
sprintf(buf, "%s %pI6->%pI6", sprintf(buf, "%pI6->%pI6", &ih->saddr, &ih->daddr);
pp->name, &ih->saddr, &ih->daddr);
pr_debug("%s: %s\n", msg, buf); pr_debug("%s: %s %s\n", msg, pp->name, buf);
} }
#endif #endif

View File

@ -270,7 +270,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */ /* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1; skb->local_df = 1;
IP_VS_XMIT(PF_INET, skb, rt); IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
LeaveFunction(10); LeaveFunction(10);
return NF_STOLEN; return NF_STOLEN;
@ -334,7 +334,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */ /* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1; skb->local_df = 1;
IP_VS_XMIT(PF_INET6, skb, rt); IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
LeaveFunction(10); LeaveFunction(10);
return NF_STOLEN; return NF_STOLEN;
@ -410,7 +410,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */ /* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1; skb->local_df = 1;
IP_VS_XMIT(PF_INET, skb, rt); IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
LeaveFunction(10); LeaveFunction(10);
return NF_STOLEN; return NF_STOLEN;
@ -486,7 +486,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */ /* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1; skb->local_df = 1;
IP_VS_XMIT(PF_INET6, skb, rt); IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
LeaveFunction(10); LeaveFunction(10);
return NF_STOLEN; return NF_STOLEN;
@ -785,7 +785,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */ /* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1; skb->local_df = 1;
IP_VS_XMIT(PF_INET, skb, rt); IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
LeaveFunction(10); LeaveFunction(10);
return NF_STOLEN; return NF_STOLEN;
@ -838,7 +838,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */ /* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1; skb->local_df = 1;
IP_VS_XMIT(PF_INET6, skb, rt); IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
LeaveFunction(10); LeaveFunction(10);
return NF_STOLEN; return NF_STOLEN;
@ -912,7 +912,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */ /* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1; skb->local_df = 1;
IP_VS_XMIT(PF_INET, skb, rt); IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
rc = NF_STOLEN; rc = NF_STOLEN;
goto out; goto out;
@ -987,7 +987,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */ /* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1; skb->local_df = 1;
IP_VS_XMIT(PF_INET6, skb, rt); IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
rc = NF_STOLEN; rc = NF_STOLEN;
goto out; goto out;

View File

@ -319,8 +319,10 @@ begin:
* not the expected one, we must restart lookup. * not the expected one, we must restart lookup.
* We probably met an item that was moved to another chain. * We probably met an item that was moved to another chain.
*/ */
if (get_nulls_value(n) != hash) if (get_nulls_value(n) != hash) {
NF_CT_STAT_INC(net, search_restart);
goto begin; goto begin;
}
local_bh_enable(); local_bh_enable();
return NULL; return NULL;

View File

@ -85,7 +85,8 @@ int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new)
struct nf_ct_event_notifier *notify; struct nf_ct_event_notifier *notify;
mutex_lock(&nf_ct_ecache_mutex); mutex_lock(&nf_ct_ecache_mutex);
notify = rcu_dereference(nf_conntrack_event_cb); notify = rcu_dereference_protected(nf_conntrack_event_cb,
lockdep_is_held(&nf_ct_ecache_mutex));
if (notify != NULL) { if (notify != NULL) {
ret = -EBUSY; ret = -EBUSY;
goto out_unlock; goto out_unlock;
@ -105,7 +106,8 @@ void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new)
struct nf_ct_event_notifier *notify; struct nf_ct_event_notifier *notify;
mutex_lock(&nf_ct_ecache_mutex); mutex_lock(&nf_ct_ecache_mutex);
notify = rcu_dereference(nf_conntrack_event_cb); notify = rcu_dereference_protected(nf_conntrack_event_cb,
lockdep_is_held(&nf_ct_ecache_mutex));
BUG_ON(notify != new); BUG_ON(notify != new);
rcu_assign_pointer(nf_conntrack_event_cb, NULL); rcu_assign_pointer(nf_conntrack_event_cb, NULL);
mutex_unlock(&nf_ct_ecache_mutex); mutex_unlock(&nf_ct_ecache_mutex);
@ -118,7 +120,8 @@ int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new)
struct nf_exp_event_notifier *notify; struct nf_exp_event_notifier *notify;
mutex_lock(&nf_ct_ecache_mutex); mutex_lock(&nf_ct_ecache_mutex);
notify = rcu_dereference(nf_expect_event_cb); notify = rcu_dereference_protected(nf_expect_event_cb,
lockdep_is_held(&nf_ct_ecache_mutex));
if (notify != NULL) { if (notify != NULL) {
ret = -EBUSY; ret = -EBUSY;
goto out_unlock; goto out_unlock;
@ -138,7 +141,8 @@ void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new)
struct nf_exp_event_notifier *notify; struct nf_exp_event_notifier *notify;
mutex_lock(&nf_ct_ecache_mutex); mutex_lock(&nf_ct_ecache_mutex);
notify = rcu_dereference(nf_expect_event_cb); notify = rcu_dereference_protected(nf_expect_event_cb,
lockdep_is_held(&nf_ct_ecache_mutex));
BUG_ON(notify != new); BUG_ON(notify != new);
rcu_assign_pointer(nf_expect_event_cb, NULL); rcu_assign_pointer(nf_expect_event_cb, NULL);
mutex_unlock(&nf_ct_ecache_mutex); mutex_unlock(&nf_ct_ecache_mutex);

Some files were not shown because too many files have changed in this diff Show More