2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-16 01:04:08 +08:00

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 2008-10-08 09:50:38 -07:00
commit 364ae953a4
174 changed files with 4310 additions and 3930 deletions

View File

@ -250,6 +250,9 @@ What (Why):
- xt_mark match revision 0
(superseded by xt_mark match revision 1)
- 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>

View File

@ -0,0 +1,85 @@
Transparent proxy support
=========================
This feature adds Linux 2.2-like transparent proxy support to current kernels.
To use it, enable NETFILTER_TPROXY, the socket match and the TPROXY target in
your kernel config. You will need policy routing too, so be sure to enable that
as well.
1. Making non-local sockets work
================================
The idea is that you identify packets with destination address matching a local
socket on your box, set the packet mark to a certain value, and then match on that
value using policy routing to have those packets delivered locally:
# iptables -t mangle -N DIVERT
# iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
# iptables -t mangle -A DIVERT -j MARK --set-mark 1
# iptables -t mangle -A DIVERT -j ACCEPT
# ip rule add fwmark 1 lookup 100
# ip route add local 0.0.0.0/0 dev lo table 100
Because of certain restrictions in the IPv4 routing output code you'll have to
modify your application to allow it to send datagrams _from_ non-local IP
addresses. All you have to do is enable the (SOL_IP, IP_TRANSPARENT) socket
option before calling bind:
fd = socket(AF_INET, SOCK_STREAM, 0);
/* - 8< -*/
int value = 1;
setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value));
/* - 8< -*/
name.sin_family = AF_INET;
name.sin_port = htons(0xCAFE);
name.sin_addr.s_addr = htonl(0xDEADBEEF);
bind(fd, &name, sizeof(name));
A trivial patch for netcat is available here:
http://people.netfilter.org/hidden/tproxy/netcat-ip_transparent-support.patch
2. Redirecting traffic
======================
Transparent proxying often involves "intercepting" traffic on a router. This is
usually done with the iptables REDIRECT target; however, there are serious
limitations of that method. One of the major issues is that it actually
modifies the packets to change the destination address -- which might not be
acceptable in certain situations. (Think of proxying UDP for example: you won't
be able to find out the original destination address. Even in case of TCP
getting the original destination address is racy.)
The 'TPROXY' target provides similar functionality without relying on NAT. Simply
add rules like this to the iptables ruleset above:
# iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
--tproxy-mark 0x1/0x1 --on-port 50080
Note that for this to work you'll have to modify the proxy to enable (SOL_IP,
IP_TRANSPARENT) for the listening socket.
3. Iptables extensions
======================
To use tproxy you'll need to have the 'socket' and 'TPROXY' modules
compiled for iptables. A patched version of iptables is available
here: http://git.balabit.hu/?p=bazsi/iptables-tproxy.git
4. Application support
======================
4.1. Squid
----------
Squid 3.HEAD has support built-in. To use it, pass
'--enable-linux-netfilter' to configure and set the 'tproxy' option on
the HTTP listener you redirect traffic to with the TPROXY iptables
target.
For more information please consult the following page on the Squid
wiki: http://wiki.squid-cache.org/Features/Tproxy4

View File

@ -5,13 +5,11 @@
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/if.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/wait.h>
#include <linux/list.h>
#include <net/net_namespace.h>
#endif
#include <linux/types.h>
#include <linux/compiler.h>
@ -52,6 +50,16 @@ enum nf_inet_hooks {
NF_INET_NUMHOOKS
};
enum {
NFPROTO_UNSPEC = 0,
NFPROTO_IPV4 = 2,
NFPROTO_ARP = 3,
NFPROTO_BRIDGE = 7,
NFPROTO_IPV6 = 10,
NFPROTO_DECNET = 12,
NFPROTO_NUMPROTO,
};
union nf_inet_addr {
__u32 all[4];
__be32 ip;
@ -92,8 +100,8 @@ struct nf_hook_ops
/* User fills in from here down. */
nf_hookfn *hook;
struct module *owner;
int pf;
int hooknum;
u_int8_t pf;
unsigned int hooknum;
/* Hooks are ordered in ascending priority. */
int priority;
};
@ -102,7 +110,7 @@ struct nf_sockopt_ops
{
struct list_head list;
int pf;
u_int8_t pf;
/* Non-inclusive ranges: use 0/0/NULL to never get called. */
int set_optmin;
@ -138,9 +146,9 @@ extern struct ctl_path nf_net_netfilter_sysctl_path[];
extern struct ctl_path nf_net_ipv4_netfilter_sysctl_path[];
#endif /* CONFIG_SYSCTL */
extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
extern struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sk_buff *), int thresh);
@ -151,7 +159,7 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
* okfn must be invoked by the caller in this case. Any other return
* value indicates the packet has been consumed by the hook.
*/
static inline int nf_hook_thresh(int pf, unsigned int hook,
static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
struct sk_buff *skb,
struct net_device *indev,
struct net_device *outdev,
@ -167,7 +175,7 @@ static inline int nf_hook_thresh(int pf, unsigned int hook,
return nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh);
}
static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sk_buff *))
{
@ -212,14 +220,14 @@ __ret;})
NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN)
/* Call setsockopt() */
int nf_setsockopt(struct sock *sk, int pf, int optval, char __user *opt,
int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
int len);
int nf_getsockopt(struct sock *sk, int pf, int optval, char __user *opt,
int nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
int *len);
int compat_nf_setsockopt(struct sock *sk, int pf, int optval,
int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, int optval,
char __user *opt, int len);
int compat_nf_getsockopt(struct sock *sk, int pf, int optval,
int compat_nf_getsockopt(struct sock *sk, u_int8_t pf, int optval,
char __user *opt, int *len);
/* Call this before modifying an existing packet: ensures it is
@ -247,7 +255,7 @@ struct nf_afinfo {
int route_key_size;
};
extern const struct nf_afinfo *nf_afinfo[NPROTO];
extern const struct nf_afinfo *nf_afinfo[NFPROTO_NUMPROTO];
static inline const struct nf_afinfo *nf_get_afinfo(unsigned short family)
{
return rcu_dereference(nf_afinfo[family]);
@ -292,7 +300,7 @@ extern void nf_unregister_afinfo(const struct nf_afinfo *afinfo);
extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
static inline void
nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family)
nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
{
#ifdef CONFIG_NF_NAT_NEEDED
void (*decodefn)(struct sk_buff *, struct flowi *);
@ -315,7 +323,7 @@ extern struct proc_dir_entry *proc_net_netfilter;
#else /* !CONFIG_NETFILTER */
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
static inline int nf_hook_thresh(int pf, unsigned int hook,
static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
struct sk_buff *skb,
struct net_device *indev,
struct net_device *outdev,
@ -324,7 +332,7 @@ static inline int nf_hook_thresh(int pf, unsigned int hook,
{
return okfn(skb);
}
static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sk_buff *))
{
@ -332,7 +340,9 @@ static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
}
struct flowi;
static inline void
nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family) {}
nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
{
}
#endif /*CONFIG_NETFILTER*/
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
@ -343,56 +353,5 @@ extern void (*nf_ct_destroy)(struct nf_conntrack *);
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
#endif
static inline struct net *nf_pre_routing_net(const struct net_device *in,
const struct net_device *out)
{
#ifdef CONFIG_NET_NS
return in->nd_net;
#else
return &init_net;
#endif
}
static inline struct net *nf_local_in_net(const struct net_device *in,
const struct net_device *out)
{
#ifdef CONFIG_NET_NS
return in->nd_net;
#else
return &init_net;
#endif
}
static inline struct net *nf_forward_net(const struct net_device *in,
const struct net_device *out)
{
#ifdef CONFIG_NET_NS
BUG_ON(in->nd_net != out->nd_net);
return in->nd_net;
#else
return &init_net;
#endif
}
static inline struct net *nf_local_out_net(const struct net_device *in,
const struct net_device *out)
{
#ifdef CONFIG_NET_NS
return out->nd_net;
#else
return &init_net;
#endif
}
static inline struct net *nf_post_routing_net(const struct net_device *in,
const struct net_device *out)
{
#ifdef CONFIG_NET_NS
return out->nd_net;
#else
return &init_net;
#endif
}
#endif /*__KERNEL__*/
#endif /*__LINUX_NETFILTER_H*/

View File

@ -32,6 +32,7 @@ header-y += xt_owner.h
header-y += xt_pkttype.h
header-y += xt_rateest.h
header-y += xt_realm.h
header-y += xt_recent.h
header-y += xt_sctp.h
header-y += xt_state.h
header-y += xt_statistic.h

View File

@ -87,7 +87,7 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
/* delete keymap entries */
void nf_ct_gre_keymap_destroy(struct nf_conn *ct);
extern void nf_ct_gre_keymap_flush(void);
extern void nf_ct_gre_keymap_flush(struct net *net);
extern void nf_nat_need_gre(void);
#endif /* __KERNEL__ */

View File

@ -173,6 +173,98 @@ struct xt_counters_info
#include <linux/netdevice.h>
/**
* struct xt_match_param - parameters for match extensions' match functions
*
* @in: input netdevice
* @out: output netdevice
* @match: struct xt_match through which this function was invoked
* @matchinfo: per-match data
* @fragoff: packet is a fragment, this is the data offset
* @thoff: position of transport header relative to skb->data
* @hotdrop: drop packet if we had inspection problems
* @family: Actual NFPROTO_* through which the function is invoked
* (helpful when match->family == NFPROTO_UNSPEC)
*/
struct xt_match_param {
const struct net_device *in, *out;
const struct xt_match *match;
const void *matchinfo;
int fragoff;
unsigned int thoff;
bool *hotdrop;
u_int8_t family;
};
/**
* struct xt_mtchk_param - parameters for match extensions'
* checkentry functions
*
* @table: table the rule is tried to be inserted into
* @entryinfo: the family-specific rule data
* (struct ipt_ip, ip6t_ip, ebt_entry)
* @match: struct xt_match through which this function was invoked
* @matchinfo: per-match data
* @hook_mask: via which hooks the new rule is reachable
*/
struct xt_mtchk_param {
const char *table;
const void *entryinfo;
const struct xt_match *match;
void *matchinfo;
unsigned int hook_mask;
u_int8_t family;
};
/* Match destructor parameters */
struct xt_mtdtor_param {
const struct xt_match *match;
void *matchinfo;
u_int8_t family;
};
/**
* struct xt_target_param - parameters for target extensions' target functions
*
* @hooknum: hook through which this target was invoked
* @target: struct xt_target through which this function was invoked
* @targinfo: per-target data
*
* Other fields see above.
*/
struct xt_target_param {
const struct net_device *in, *out;
unsigned int hooknum;
const struct xt_target *target;
const void *targinfo;
u_int8_t family;
};
/**
* struct xt_tgchk_param - parameters for target extensions'
* checkentry functions
*
* @entryinfo: the family-specific rule data
* (struct ipt_entry, ip6t_entry, arpt_entry, ebt_entry)
*
* Other fields see above.
*/
struct xt_tgchk_param {
const char *table;
void *entryinfo;
const struct xt_target *target;
void *targinfo;
unsigned int hook_mask;
u_int8_t family;
};
/* Target destructor parameters */
struct xt_tgdtor_param {
const struct xt_target *target;
void *targinfo;
u_int8_t family;
};
struct xt_match
{
struct list_head list;
@ -185,24 +277,13 @@ struct xt_match
non-linear skb, using skb_header_pointer and
skb_ip_make_writable. */
bool (*match)(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const struct xt_match *match,
const void *matchinfo,
int offset,
unsigned int protoff,
bool *hotdrop);
const struct xt_match_param *);
/* Called when user tries to insert an entry of this type. */
/* Should return true or false. */
bool (*checkentry)(const char *tablename,
const void *ip,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask);
bool (*checkentry)(const struct xt_mtchk_param *);
/* Called when entry of this type deleted. */
void (*destroy)(const struct xt_match *match, void *matchinfo);
void (*destroy)(const struct xt_mtdtor_param *);
/* Called when userspace align differs from kernel space one */
void (*compat_from_user)(void *dst, void *src);
@ -235,24 +316,16 @@ struct xt_target
must now handle non-linear skbs, using skb_copy_bits and
skb_ip_make_writable. */
unsigned int (*target)(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo);
const struct xt_target_param *);
/* Called when user tries to insert an entry of this type:
hook_mask is a bitmask of hooks from which it can be
called. */
/* Should return true or false. */
bool (*checkentry)(const char *tablename,
const void *entry,
const struct xt_target *target,
void *targinfo,
unsigned int hook_mask);
bool (*checkentry)(const struct xt_tgchk_param *);
/* Called when entry of this type deleted. */
void (*destroy)(const struct xt_target *target, void *targinfo);
void (*destroy)(const struct xt_tgdtor_param *);
/* Called when userspace align differs from kernel space one */
void (*compat_from_user)(void *dst, void *src);
@ -292,7 +365,7 @@ struct xt_table
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;
int af; /* address/protocol family */
u_int8_t af; /* address/protocol family */
};
#include <linux/netfilter_ipv4.h>
@ -328,12 +401,10 @@ extern void xt_unregister_match(struct xt_match *target);
extern int xt_register_matches(struct xt_match *match, unsigned int n);
extern void xt_unregister_matches(struct xt_match *match, unsigned int n);
extern int xt_check_match(const struct xt_match *match, unsigned short family,
unsigned int size, const char *table, unsigned int hook,
unsigned short proto, int inv_proto);
extern int xt_check_target(const struct xt_target *target, unsigned short family,
unsigned int size, const char *table, unsigned int hook,
unsigned short proto, int inv_proto);
extern int xt_check_match(struct xt_mtchk_param *,
unsigned int size, u_int8_t proto, bool inv_proto);
extern int xt_check_target(struct xt_tgchk_param *,
unsigned int size, u_int8_t proto, bool inv_proto);
extern struct xt_table *xt_register_table(struct net *net,
struct xt_table *table,
@ -346,19 +417,19 @@ extern struct xt_table_info *xt_replace_table(struct xt_table *table,
struct xt_table_info *newinfo,
int *error);
extern struct xt_match *xt_find_match(int af, const char *name, u8 revision);
extern struct xt_target *xt_find_target(int af, const char *name, u8 revision);
extern struct xt_target *xt_request_find_target(int af, const char *name,
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_request_find_target(u8 af, const char *name,
u8 revision);
extern int xt_find_revision(int af, const char *name, u8 revision, int target,
int *err);
extern int xt_find_revision(u8 af, const char *name, u8 revision,
int target, int *err);
extern struct xt_table *xt_find_table_lock(struct net *net, int af,
extern struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af,
const char *name);
extern void xt_table_unlock(struct xt_table *t);
extern int xt_proto_init(struct net *net, int af);
extern void xt_proto_fini(struct net *net, int af);
extern int xt_proto_init(struct net *net, u_int8_t af);
extern void xt_proto_fini(struct net *net, u_int8_t af);
extern struct xt_table_info *xt_alloc_table_info(unsigned int size);
extern void xt_free_table_info(struct xt_table_info *info);
@ -423,12 +494,12 @@ struct compat_xt_counters_info
#define COMPAT_XT_ALIGN(s) (((s) + (__alignof__(struct compat_xt_counters)-1)) \
& ~(__alignof__(struct compat_xt_counters)-1))
extern void xt_compat_lock(int af);
extern void xt_compat_unlock(int af);
extern void xt_compat_lock(u_int8_t af);
extern void xt_compat_unlock(u_int8_t af);
extern int xt_compat_add_offset(int af, unsigned int offset, short delta);
extern void xt_compat_flush_offsets(int af);
extern short xt_compat_calc_jump(int af, unsigned int offset);
extern int xt_compat_add_offset(u_int8_t af, unsigned int offset, short delta);
extern void xt_compat_flush_offsets(u_int8_t af);
extern short xt_compat_calc_jump(u_int8_t af, unsigned int offset);
extern int xt_compat_match_offset(const struct xt_match *match);
extern int xt_compat_match_from_user(struct xt_entry_match *m,

View File

@ -0,0 +1,14 @@
#ifndef _XT_TPROXY_H_target
#define _XT_TPROXY_H_target
/* TPROXY target is capable of marking the packet to perform
* redirection. We can get rid of that whenever we get support for
* mutliple targets in the same rule. */
struct xt_tproxy_target_info {
u_int32_t mark_mask;
u_int32_t mark_value;
__be32 laddr;
__be16 lport;
};
#endif /* _XT_TPROXY_H_target */

View File

@ -0,0 +1,26 @@
#ifndef _LINUX_NETFILTER_XT_RECENT_H
#define _LINUX_NETFILTER_XT_RECENT_H 1
enum {
XT_RECENT_CHECK = 1 << 0,
XT_RECENT_SET = 1 << 1,
XT_RECENT_UPDATE = 1 << 2,
XT_RECENT_REMOVE = 1 << 3,
XT_RECENT_TTL = 1 << 4,
XT_RECENT_SOURCE = 0,
XT_RECENT_DEST = 1,
XT_RECENT_NAME_LEN = 200,
};
struct xt_recent_mtinfo {
u_int32_t seconds;
u_int32_t hit_count;
u_int8_t check_set;
u_int8_t invert;
char name[XT_RECENT_NAME_LEN];
u_int8_t side;
};
#endif /* _LINUX_NETFILTER_XT_RECENT_H */

View File

@ -31,6 +31,9 @@
* The 4 lsb are more than enough to store the verdict. */
#define EBT_VERDICT_BITS 0x0000000F
struct xt_match;
struct xt_target;
struct ebt_counter
{
uint64_t pcnt;
@ -121,7 +124,7 @@ struct ebt_entry_match
{
union {
char name[EBT_FUNCTION_MAXNAMELEN];
struct ebt_match *match;
struct xt_match *match;
} u;
/* size of data */
unsigned int match_size;
@ -132,7 +135,7 @@ struct ebt_entry_watcher
{
union {
char name[EBT_FUNCTION_MAXNAMELEN];
struct ebt_watcher *watcher;
struct xt_target *watcher;
} u;
/* size of data */
unsigned int watcher_size;
@ -143,7 +146,7 @@ struct ebt_entry_target
{
union {
char name[EBT_FUNCTION_MAXNAMELEN];
struct ebt_target *target;
struct xt_target *target;
} u;
/* size of data */
unsigned int target_size;
@ -207,14 +210,17 @@ struct ebt_match
{
struct list_head list;
const char name[EBT_FUNCTION_MAXNAMELEN];
/* 0 == it matches */
int (*match)(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *matchdata,
unsigned int datalen);
/* 0 == let it in */
int (*check)(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *matchdata, unsigned int datalen);
void (*destroy)(void *matchdata, unsigned int datalen);
bool (*match)(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff,
bool *hotdrop);
bool (*checkentry)(const char *table, const void *entry,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask);
void (*destroy)(const struct xt_match *match, void *matchinfo);
unsigned int matchsize;
u_int8_t revision;
u_int8_t family;
struct module *me;
};
@ -222,13 +228,17 @@ struct ebt_watcher
{
struct list_head list;
const char name[EBT_FUNCTION_MAXNAMELEN];
void (*watcher)(const struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *watcherdata, unsigned int datalen);
/* 0 == let it in */
int (*check)(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *watcherdata, unsigned int datalen);
void (*destroy)(void *watcherdata, unsigned int datalen);
unsigned int (*target)(struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
unsigned int hook_num, const struct xt_target *target,
const void *targinfo);
bool (*checkentry)(const char *table, const void *entry,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask);
void (*destroy)(const struct xt_target *target, void *targinfo);
unsigned int targetsize;
u_int8_t revision;
u_int8_t family;
struct module *me;
};
@ -236,14 +246,18 @@ struct ebt_target
{
struct list_head list;
const char name[EBT_FUNCTION_MAXNAMELEN];
/* returns one of the standard verdicts */
int (*target)(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *targetdata, unsigned int datalen);
/* 0 == let it in */
int (*check)(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *targetdata, unsigned int datalen);
void (*destroy)(void *targetdata, unsigned int datalen);
/* returns one of the standard EBT_* verdicts */
unsigned int (*target)(struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
unsigned int hook_num, const struct xt_target *target,
const void *targinfo);
bool (*checkentry)(const char *table, const void *entry,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask);
void (*destroy)(const struct xt_target *target, void *targinfo);
unsigned int targetsize;
u_int8_t revision;
u_int8_t family;
struct module *me;
};
@ -288,12 +302,6 @@ struct ebt_table
~(__alignof__(struct ebt_replace)-1))
extern int ebt_register_table(struct ebt_table *table);
extern void ebt_unregister_table(struct ebt_table *table);
extern int ebt_register_match(struct ebt_match *match);
extern void ebt_unregister_match(struct ebt_match *match);
extern int ebt_register_watcher(struct ebt_watcher *watcher);
extern void ebt_unregister_watcher(struct ebt_watcher *watcher);
extern int ebt_register_target(struct ebt_target *target);
extern void ebt_unregister_target(struct ebt_target *target);
extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
struct ebt_table *table);
@ -302,9 +310,9 @@ extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
#define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg))
/* True if the hook mask denotes that the rule is in a base chain,
* used in the check() functions */
#define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS))
#define BASE_CHAIN (par->hook_mask & (1 << NF_BR_NUMHOOKS))
/* Clear the bit in the hook mask that tells if the rule is on a base chain */
#define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS))
#define CLEAR_BASE_CHAIN_BIT (par->hook_mask &= ~(1 << NF_BR_NUMHOOKS))
/* True if the target is not a standard target */
#define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0)

View File

@ -1,27 +1,21 @@
#ifndef _IPT_RECENT_H
#define _IPT_RECENT_H
#define RECENT_NAME "ipt_recent"
#define RECENT_VER "v0.3.1"
#include <linux/netfilter/xt_recent.h>
#define IPT_RECENT_CHECK 1
#define IPT_RECENT_SET 2
#define IPT_RECENT_UPDATE 4
#define IPT_RECENT_REMOVE 8
#define IPT_RECENT_TTL 16
#define ipt_recent_info xt_recent_mtinfo
#define IPT_RECENT_SOURCE 0
#define IPT_RECENT_DEST 1
enum {
IPT_RECENT_CHECK = XT_RECENT_CHECK,
IPT_RECENT_SET = XT_RECENT_SET,
IPT_RECENT_UPDATE = XT_RECENT_UPDATE,
IPT_RECENT_REMOVE = XT_RECENT_REMOVE,
IPT_RECENT_TTL = XT_RECENT_TTL,
#define IPT_RECENT_NAME_LEN 200
IPT_RECENT_SOURCE = XT_RECENT_SOURCE,
IPT_RECENT_DEST = XT_RECENT_DEST,
struct ipt_recent_info {
u_int32_t seconds;
u_int32_t hit_count;
u_int8_t check_set;
u_int8_t invert;
char name[IPT_RECENT_NAME_LEN];
u_int8_t side;
IPT_RECENT_NAME_LEN = XT_RECENT_NAME_LEN,
};
#endif /*_IPT_RECENT_H*/

View File

@ -16,6 +16,9 @@
#include <net/netns/ipv6.h>
#include <net/netns/dccp.h>
#include <net/netns/x_tables.h>
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
#include <net/netns/conntrack.h>
#endif
struct proc_dir_entry;
struct net_device;
@ -67,6 +70,9 @@ struct net {
#endif
#ifdef CONFIG_NETFILTER
struct netns_xt xt;
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct netns_ct ct;
#endif
#endif
struct net_generic *gen;
};

View File

@ -0,0 +1,6 @@
#ifndef _NF_DEFRAG_IPV4_H
#define _NF_DEFRAG_IPV4_H
extern void nf_defrag_ipv4_enable(void);
#endif /* _NF_DEFRAG_IPV4_H */

View File

@ -123,7 +123,9 @@ struct nf_conn
/* Extensions */
struct nf_ct_ext *ext;
#ifdef CONFIG_NET_NS
struct net *ct_net;
#endif
struct rcu_head rcu;
};
@ -147,6 +149,17 @@ static inline u_int8_t nf_ct_protonum(const struct nf_conn *ct)
/* get master conntrack via master expectation */
#define master_ct(conntr) (conntr->master)
extern struct net init_net;
static inline struct net *nf_ct_net(const struct nf_conn *ct)
{
#ifdef CONFIG_NET_NS
return ct->ct_net;
#else
return &init_net;
#endif
}
/* Alter reply tuple (maybe alter helper). */
extern void
nf_conntrack_alter_reply(struct nf_conn *ct,
@ -182,11 +195,11 @@ extern void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced,
unsigned int size);
extern struct nf_conntrack_tuple_hash *
__nf_conntrack_find(const struct nf_conntrack_tuple *tuple);
__nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple);
extern void nf_conntrack_hash_insert(struct nf_conn *ct);
extern void nf_conntrack_flush(void);
extern void nf_conntrack_flush(struct net *net);
extern bool nf_ct_get_tuplepr(const struct sk_buff *skb,
unsigned int nhoff, u_int16_t l3num,
@ -248,10 +261,11 @@ extern struct nf_conn nf_conntrack_untracked;
/* Iterate over all conntracks: if iter returns true, it's deleted. */
extern void
nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data);
nf_ct_iterate_cleanup(struct net *net, int (*iter)(struct nf_conn *i, void *data), void *data);
extern void nf_conntrack_free(struct nf_conn *ct);
extern struct nf_conn *
nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
nf_conntrack_alloc(struct net *net,
const struct nf_conntrack_tuple *orig,
const struct nf_conntrack_tuple *repl,
gfp_t gfp);
@ -273,16 +287,14 @@ static inline int nf_ct_is_untracked(const struct sk_buff *skb)
extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
extern unsigned int nf_conntrack_htable_size;
extern int nf_conntrack_checksum;
extern atomic_t nf_conntrack_count;
extern int nf_conntrack_max;
DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
#define NF_CT_STAT_INC(count) (__get_cpu_var(nf_conntrack_stat).count++)
#define NF_CT_STAT_INC_ATOMIC(count) \
#define NF_CT_STAT_INC(net, count) \
(per_cpu_ptr((net)->ct.stat, raw_smp_processor_id())->count++)
#define NF_CT_STAT_INC_ATOMIC(net, count) \
do { \
local_bh_disable(); \
__get_cpu_var(nf_conntrack_stat).count++; \
per_cpu_ptr((net)->ct.stat, raw_smp_processor_id())->count++; \
local_bh_enable(); \
} while (0)

View File

@ -8,6 +8,7 @@
#ifndef _NF_CONNTRACK_ACCT_H
#define _NF_CONNTRACK_ACCT_H
#include <net/net_namespace.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/netfilter/nf_conntrack_tuple_common.h>
#include <net/netfilter/nf_conntrack.h>
@ -18,8 +19,6 @@ struct nf_conn_counter {
u_int64_t bytes;
};
extern int nf_ct_acct;
static inline
struct nf_conn_counter *nf_conn_acct_find(const struct nf_conn *ct)
{
@ -29,9 +28,10 @@ struct nf_conn_counter *nf_conn_acct_find(const struct nf_conn *ct)
static inline
struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp)
{
struct net *net = nf_ct_net(ct);
struct nf_conn_counter *acct;
if (!nf_ct_acct)
if (!net->ct.sysctl_acct)
return NULL;
acct = nf_ct_ext_add(ct, NF_CT_EXT_ACCT, gfp);
@ -45,7 +45,7 @@ struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp)
extern unsigned int
seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir);
extern int nf_conntrack_acct_init(void);
extern void nf_conntrack_acct_fini(void);
extern int nf_conntrack_acct_init(struct net *net);
extern void nf_conntrack_acct_fini(struct net *net);
#endif /* _NF_CONNTRACK_ACCT_H */

View File

@ -20,12 +20,13 @@
/* This header is used to share core functionality between the
standalone connection tracking module, and the compatibility layer's use
of connection tracking. */
extern unsigned int nf_conntrack_in(int pf,
extern unsigned int nf_conntrack_in(struct net *net,
u_int8_t pf,
unsigned int hooknum,
struct sk_buff *skb);
extern int nf_conntrack_init(void);
extern void nf_conntrack_cleanup(void);
extern int nf_conntrack_init(struct net *net);
extern void nf_conntrack_cleanup(struct net *net);
extern int nf_conntrack_proto_init(void);
extern void nf_conntrack_proto_fini(void);
@ -48,7 +49,7 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
/* Find a connection corresponding to a tuple. */
extern struct nf_conntrack_tuple_hash *
nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple);
nf_conntrack_find_get(struct net *net, const struct nf_conntrack_tuple *tuple);
extern int __nf_conntrack_confirm(struct sk_buff *skb);
@ -71,8 +72,6 @@ print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_l3proto *l3proto,
const struct nf_conntrack_l4proto *proto);
extern struct hlist_head *nf_conntrack_hash;
extern spinlock_t nf_conntrack_lock ;
extern struct hlist_head unconfirmed;
#endif /* _NF_CONNTRACK_CORE_H */

View File

@ -8,6 +8,7 @@
#include <linux/notifier.h>
#include <linux/interrupt.h>
#include <net/net_namespace.h>
#include <net/netfilter/nf_conntrack_expect.h>
#ifdef CONFIG_NF_CONNTRACK_EVENTS
@ -15,9 +16,6 @@ struct nf_conntrack_ecache {
struct nf_conn *ct;
unsigned int events;
};
DECLARE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
#define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x)
extern struct atomic_notifier_head nf_conntrack_chain;
extern int nf_conntrack_register_notifier(struct notifier_block *nb);
@ -25,17 +23,16 @@ extern int nf_conntrack_unregister_notifier(struct notifier_block *nb);
extern void nf_ct_deliver_cached_events(const struct nf_conn *ct);
extern void __nf_ct_event_cache_init(struct nf_conn *ct);
extern void nf_ct_event_cache_flush(void);
extern void nf_ct_event_cache_flush(struct net *net);
static inline void
nf_conntrack_event_cache(enum ip_conntrack_events event,
const struct sk_buff *skb)
nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
{
struct nf_conn *ct = (struct nf_conn *)skb->nfct;
struct net *net = nf_ct_net(ct);
struct nf_conntrack_ecache *ecache;
local_bh_disable();
ecache = &__get_cpu_var(nf_conntrack_ecache);
ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
if (ct != ecache->ct)
__nf_ct_event_cache_init(ct);
ecache->events |= event;
@ -60,6 +57,9 @@ nf_ct_expect_event(enum ip_conntrack_expect_events event,
atomic_notifier_call_chain(&nf_ct_expect_chain, event, exp);
}
extern int nf_conntrack_ecache_init(struct net *net);
extern void nf_conntrack_ecache_fini(struct net *net);
#else /* CONFIG_NF_CONNTRACK_EVENTS */
static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
@ -69,7 +69,15 @@ static inline void nf_conntrack_event(enum ip_conntrack_events event,
static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
struct nf_conntrack_expect *exp) {}
static inline void nf_ct_event_cache_flush(void) {}
static inline void nf_ct_event_cache_flush(struct net *net) {}
static inline int nf_conntrack_ecache_init(struct net *net)
{
return 0;
static inline void nf_conntrack_ecache_fini(struct net *net)
{
}
#endif /* CONFIG_NF_CONNTRACK_EVENTS */
#endif /*_NF_CONNTRACK_ECACHE_H*/

View File

@ -6,7 +6,6 @@
#define _NF_CONNTRACK_EXPECT_H
#include <net/netfilter/nf_conntrack.h>
extern struct hlist_head *nf_ct_expect_hash;
extern unsigned int nf_ct_expect_hsize;
extern unsigned int nf_ct_expect_max;
@ -56,6 +55,15 @@ struct nf_conntrack_expect
struct rcu_head rcu;
};
static inline struct net *nf_ct_exp_net(struct nf_conntrack_expect *exp)
{
#ifdef CONFIG_NET_NS
return exp->master->ct_net; /* by definition */
#else
return &init_net;
#endif
}
struct nf_conntrack_expect_policy
{
unsigned int max_expected;
@ -67,17 +75,17 @@ struct nf_conntrack_expect_policy
#define NF_CT_EXPECT_PERMANENT 0x1
#define NF_CT_EXPECT_INACTIVE 0x2
int nf_conntrack_expect_init(void);
void nf_conntrack_expect_fini(void);
int nf_conntrack_expect_init(struct net *net);
void nf_conntrack_expect_fini(struct net *net);
struct nf_conntrack_expect *
__nf_ct_expect_find(const struct nf_conntrack_tuple *tuple);
__nf_ct_expect_find(struct net *net, const struct nf_conntrack_tuple *tuple);
struct nf_conntrack_expect *
nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple);
nf_ct_expect_find_get(struct net *net, const struct nf_conntrack_tuple *tuple);
struct nf_conntrack_expect *
nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple);
nf_ct_find_expectation(struct net *net, const struct nf_conntrack_tuple *tuple);
void nf_ct_unlink_expect(struct nf_conntrack_expect *exp);
void nf_ct_remove_expectations(struct nf_conn *ct);
@ -86,7 +94,7 @@ void nf_ct_unexpect_related(struct nf_conntrack_expect *exp);
/* Allocate space for an expectation: this is mandatory before calling
nf_ct_expect_related. You will have to call put afterwards. */
struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me);
void nf_ct_expect_init(struct nf_conntrack_expect *, unsigned int, int,
void nf_ct_expect_init(struct nf_conntrack_expect *, unsigned int, u_int8_t,
const union nf_inet_addr *,
const union nf_inet_addr *,
u_int8_t, const __be16 *, const __be16 *);

View File

@ -39,7 +39,7 @@ struct nf_conntrack_l4proto
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
int pf,
u_int8_t pf,
unsigned int hooknum);
/* Called when a new connection for this protocol found;
@ -50,9 +50,9 @@ struct nf_conntrack_l4proto
/* Called when a conntrack entry is destroyed */
void (*destroy)(struct nf_conn *ct);
int (*error)(struct sk_buff *skb, unsigned int dataoff,
int (*error)(struct net *net, struct sk_buff *skb, unsigned int dataoff,
enum ip_conntrack_info *ctinfo,
int pf, unsigned int hooknum);
u_int8_t pf, unsigned int hooknum);
/* Print out the per-protocol part of the tuple. Return like seq_* */
int (*print_tuple)(struct seq_file *s,
@ -117,20 +117,19 @@ extern int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
struct nf_conntrack_tuple *t);
extern const struct nla_policy nf_ct_port_nla_policy[];
/* Log invalid packets */
extern unsigned int nf_ct_log_invalid;
#ifdef CONFIG_SYSCTL
#ifdef DEBUG_INVALID_PACKETS
#define LOG_INVALID(proto) \
(nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW)
#define LOG_INVALID(net, proto) \
((net)->ct.sysctl_log_invalid == (proto) || \
(net)->ct.sysctl_log_invalid == IPPROTO_RAW)
#else
#define LOG_INVALID(proto) \
((nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW) \
#define LOG_INVALID(net, proto) \
(((net)->ct.sysctl_log_invalid == (proto) || \
(net)->ct.sysctl_log_invalid == IPPROTO_RAW) \
&& net_ratelimit())
#endif
#else
#define LOG_INVALID(proto) 0
#define LOG_INVALID(net, proto) 0
#endif /* CONFIG_SYSCTL */
#endif /*_NF_CONNTRACK_PROTOCOL_H*/

View File

@ -28,7 +28,7 @@ struct nf_loginfo {
} u;
};
typedef void nf_logfn(unsigned int pf,
typedef void nf_logfn(u_int8_t pf,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,
@ -43,12 +43,12 @@ struct nf_logger {
};
/* Function to register/unregister log function. */
int nf_log_register(int pf, const struct nf_logger *logger);
int nf_log_register(u_int8_t pf, const struct nf_logger *logger);
void nf_log_unregister(const struct nf_logger *logger);
void nf_log_unregister_pf(int pf);
void nf_log_unregister_pf(u_int8_t pf);
/* Calls the registered backend logging function */
void nf_log_packet(int pf,
void nf_log_packet(u_int8_t pf,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,

View File

@ -8,7 +8,7 @@ struct nf_queue_entry {
unsigned int id;
struct nf_hook_ops *elem;
int pf;
u_int8_t pf;
unsigned int hook;
struct net_device *indev;
struct net_device *outdev;
@ -24,9 +24,9 @@ struct nf_queue_handler {
char *name;
};
extern int nf_register_queue_handler(int pf,
extern int nf_register_queue_handler(u_int8_t pf,
const struct nf_queue_handler *qh);
extern int nf_unregister_queue_handler(int pf,
extern int nf_unregister_queue_handler(u_int8_t pf,
const struct nf_queue_handler *qh);
extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);

View File

@ -0,0 +1,32 @@
#ifndef _NF_TPROXY_CORE_H
#define _NF_TPROXY_CORE_H
#include <linux/types.h>
#include <linux/in.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/inet_sock.h>
#include <net/tcp.h>
/* look up and get a reference to a matching socket */
extern struct sock *
nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
const __be32 saddr, const __be32 daddr,
const __be16 sport, const __be16 dport,
const struct net_device *in, bool listening);
static inline void
nf_tproxy_put_sock(struct sock *sk)
{
/* TIME_WAIT inet sockets have to be handled differently */
if ((sk->sk_protocol == IPPROTO_TCP) && (sk->sk_state == TCP_TIME_WAIT))
inet_twsk_put(inet_twsk(sk));
else
sock_put(sk);
}
/* assign a socket to the skb -- consumes sk */
int
nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk);
#endif

View File

@ -0,0 +1,30 @@
#ifndef __NETNS_CONNTRACK_H
#define __NETNS_CONNTRACK_H
#include <linux/list.h>
#include <asm/atomic.h>
struct ctl_table_header;
struct nf_conntrack_ecache;
struct netns_ct {
atomic_t count;
unsigned int expect_count;
struct hlist_head *hash;
struct hlist_head *expect_hash;
struct hlist_head unconfirmed;
struct ip_conntrack_stat *stat;
#ifdef CONFIG_NF_CONNTRACK_EVENTS
struct nf_conntrack_ecache *ecache;
#endif
int sysctl_acct;
int sysctl_checksum;
unsigned int sysctl_log_invalid; /* Log invalid packets */
#ifdef CONFIG_SYSCTL
struct ctl_table_header *sysctl_header;
struct ctl_table_header *acct_sysctl_header;
#endif
int hash_vmalloc;
int expect_vmalloc;
};
#endif

View File

@ -38,6 +38,9 @@ struct netns_ipv4 {
struct xt_table *iptable_raw;
struct xt_table *arptable_filter;
struct xt_table *iptable_security;
struct xt_table *nat_table;
struct hlist_head *nat_bysource;
int nat_vmalloced;
#endif
int sysctl_icmp_echo_ignore_all;

View File

@ -657,7 +657,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
{
struct nf_bridge_info *nf_bridge;
struct net_device *parent;
int pf;
u_int8_t pf;
if (!skb->nf_bridge)
return NF_ACCEPT;
@ -791,7 +791,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
{
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
struct net_device *realoutdev = bridge_parent(skb->dev);
int pf;
u_int8_t pf;
#ifdef CONFIG_NETFILTER_DEBUG
/* Be very paranoid. This probably won't happen anymore, but let's

View File

@ -2,21 +2,21 @@
# Bridge netfilter configuration
#
menu "Bridge: Netfilter Configuration"
depends on BRIDGE && BRIDGE_NETFILTER
config BRIDGE_NF_EBTABLES
menuconfig BRIDGE_NF_EBTABLES
tristate "Ethernet Bridge tables (ebtables) support"
select NETFILTER_XTABLES
help
ebtables is a general, extensible frame/packet identification
framework. Say 'Y' or 'M' here if you want to do Ethernet
filtering/NAT/brouting on the Ethernet bridge.
if BRIDGE_NF_EBTABLES
#
# tables
#
config BRIDGE_EBT_BROUTE
tristate "ebt: broute table support"
depends on BRIDGE_NF_EBTABLES
help
The ebtables broute table is used to define rules that decide between
bridging and routing frames, giving Linux the functionality of a
@ -27,7 +27,6 @@ config BRIDGE_EBT_BROUTE
config BRIDGE_EBT_T_FILTER
tristate "ebt: filter table support"
depends on BRIDGE_NF_EBTABLES
help
The ebtables filter table is used to define frame filtering rules at
local input, forwarding and local output. See the man page for
@ -37,7 +36,6 @@ config BRIDGE_EBT_T_FILTER
config BRIDGE_EBT_T_NAT
tristate "ebt: nat table support"
depends on BRIDGE_NF_EBTABLES
help
The ebtables nat table is used to define rules that alter the MAC
source address (MAC SNAT) or the MAC destination address (MAC DNAT).
@ -49,7 +47,6 @@ config BRIDGE_EBT_T_NAT
#
config BRIDGE_EBT_802_3
tristate "ebt: 802.3 filter support"
depends on BRIDGE_NF_EBTABLES
help
This option adds matching support for 802.3 Ethernet frames.
@ -57,7 +54,6 @@ config BRIDGE_EBT_802_3
config BRIDGE_EBT_AMONG
tristate "ebt: among filter support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the among match, which allows matching the MAC source
and/or destination address on a list of addresses. Optionally,
@ -67,7 +63,6 @@ config BRIDGE_EBT_AMONG
config BRIDGE_EBT_ARP
tristate "ebt: ARP filter support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the ARP match, which allows ARP and RARP header field
filtering.
@ -76,7 +71,6 @@ config BRIDGE_EBT_ARP
config BRIDGE_EBT_IP
tristate "ebt: IP filter support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the IP match, which allows basic IP header field
filtering.
@ -94,7 +88,6 @@ config BRIDGE_EBT_IP6
config BRIDGE_EBT_LIMIT
tristate "ebt: limit match support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the limit match, which allows you to control
the rate at which a rule can be matched. This match is the
@ -105,7 +98,6 @@ config BRIDGE_EBT_LIMIT
config BRIDGE_EBT_MARK
tristate "ebt: mark filter support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the mark match, which allows matching frames based on
the 'nfmark' value in the frame. This can be set by the mark target.
@ -116,7 +108,6 @@ config BRIDGE_EBT_MARK
config BRIDGE_EBT_PKTTYPE
tristate "ebt: packet type filter support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the packet type match, which allows matching on the
type of packet based on its Ethernet "class" (as determined by
@ -127,7 +118,6 @@ config BRIDGE_EBT_PKTTYPE
config BRIDGE_EBT_STP
tristate "ebt: STP filter support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the Spanning Tree Protocol match, which
allows STP header field filtering.
@ -136,7 +126,6 @@ config BRIDGE_EBT_STP
config BRIDGE_EBT_VLAN
tristate "ebt: 802.1Q VLAN filter support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the 802.1Q vlan match, which allows the filtering of
802.1Q vlan fields.
@ -156,7 +145,6 @@ config BRIDGE_EBT_ARPREPLY
config BRIDGE_EBT_DNAT
tristate "ebt: dnat target support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the MAC DNAT target, which allows altering the MAC
destination address of frames.
@ -165,7 +153,6 @@ config BRIDGE_EBT_DNAT
config BRIDGE_EBT_MARK_T
tristate "ebt: mark target support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the mark target, which allows marking frames by
setting the 'nfmark' value in the frame.
@ -176,7 +163,6 @@ config BRIDGE_EBT_MARK_T
config BRIDGE_EBT_REDIRECT
tristate "ebt: redirect target support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the MAC redirect target, which allows altering the MAC
destination address of a frame to that of the device it arrived on.
@ -185,7 +171,6 @@ config BRIDGE_EBT_REDIRECT
config BRIDGE_EBT_SNAT
tristate "ebt: snat target support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the MAC SNAT target, which allows altering the MAC
source address of frames.
@ -196,7 +181,6 @@ config BRIDGE_EBT_SNAT
#
config BRIDGE_EBT_LOG
tristate "ebt: log support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the log watcher, that you can use in any rule
in any ebtables table. It records info about the frame header
@ -206,7 +190,6 @@ config BRIDGE_EBT_LOG
config BRIDGE_EBT_ULOG
tristate "ebt: ulog support (OBSOLETE)"
depends on BRIDGE_NF_EBTABLES
help
This option enables the old bridge-specific "ebt_ulog" implementation
which has been obsoleted by the new "nfnetlink_log" code (see
@ -223,7 +206,6 @@ config BRIDGE_EBT_ULOG
config BRIDGE_EBT_NFLOG
tristate "ebt: nflog support"
depends on BRIDGE_NF_EBTABLES
help
This option enables the nflog watcher, which allows to LOG
messages through the netfilter logging API, which can use
@ -235,4 +217,4 @@ config BRIDGE_EBT_NFLOG
To compile it as a module, choose M here. If unsure, say N.
endmenu
endif # BRIDGE_NF_EBTABLES

View File

@ -7,64 +7,63 @@
* May 2003
*
*/
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_802_3.h>
#include <linux/module.h>
static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *data, unsigned int datalen)
static bool
ebt_802_3_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ebt_802_3_info *info = data;
const struct ebt_802_3_info *info = par->matchinfo;
const struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb);
__be16 type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type;
if (info->bitmask & EBT_802_3_SAP) {
if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP))
return EBT_NOMATCH;
return false;
if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_802_3_TYPE) {
if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE))
return EBT_NOMATCH;
return false;
if (FWINV(info->type != type, EBT_802_3_TYPE))
return EBT_NOMATCH;
return false;
}
return EBT_MATCH;
return true;
}
static struct ebt_match filter_802_3;
static int ebt_802_3_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_802_3_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_802_3_info *info = data;
const struct ebt_802_3_info *info = par->matchinfo;
if (datalen < sizeof(struct ebt_802_3_info))
return -EINVAL;
if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK)
return -EINVAL;
return false;
return 0;
return true;
}
static struct ebt_match filter_802_3 __read_mostly = {
.name = EBT_802_3_MATCH,
.match = ebt_filter_802_3,
.check = ebt_802_3_check,
static struct xt_match ebt_802_3_mt_reg __read_mostly = {
.name = "802_3",
.revision = 0,
.family = NFPROTO_BRIDGE,
.match = ebt_802_3_mt,
.checkentry = ebt_802_3_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_802_3_info)),
.me = THIS_MODULE,
};
static int __init ebt_802_3_init(void)
{
return ebt_register_match(&filter_802_3);
return xt_register_match(&ebt_802_3_mt_reg);
}
static void __exit ebt_802_3_fini(void)
{
ebt_unregister_match(&filter_802_3);
xt_unregister_match(&ebt_802_3_mt_reg);
}
module_init(ebt_802_3_init);

View File

@ -7,15 +7,15 @@
* August, 2003
*
*/
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_among.h>
#include <linux/ip.h>
#include <linux/if_arp.h>
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_among.h>
static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
const char *mac, __be32 ip)
static bool ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
const char *mac, __be32 ip)
{
/* You may be puzzled as to how this code works.
* Some tricks were used, refer to
@ -33,23 +33,19 @@ static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
if (ip) {
for (i = start; i < limit; i++) {
p = &wh->pool[i];
if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) {
if (p->ip == 0 || p->ip == ip) {
return 1;
}
}
if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0])
if (p->ip == 0 || p->ip == ip)
return true;
}
} else {
for (i = start; i < limit; i++) {
p = &wh->pool[i];
if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) {
if (p->ip == 0) {
return 1;
}
}
if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0])
if (p->ip == 0)
return true;
}
}
return 0;
return false;
}
static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash
@ -131,12 +127,10 @@ static int get_ip_src(const struct sk_buff *skb, __be32 *addr)
return 0;
}
static int ebt_filter_among(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out, const void *data,
unsigned int datalen)
static bool
ebt_among_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ebt_among_info *info = data;
const struct ebt_among_info *info = par->matchinfo;
const char *dmac, *smac;
const struct ebt_mac_wormhash *wh_dst, *wh_src;
__be32 dip = 0, sip = 0;
@ -147,41 +141,41 @@ static int ebt_filter_among(const struct sk_buff *skb,
if (wh_src) {
smac = eth_hdr(skb)->h_source;
if (get_ip_src(skb, &sip))
return EBT_NOMATCH;
return false;
if (!(info->bitmask & EBT_AMONG_SRC_NEG)) {
/* we match only if it contains */
if (!ebt_mac_wormhash_contains(wh_src, smac, sip))
return EBT_NOMATCH;
return false;
} else {
/* we match only if it DOES NOT contain */
if (ebt_mac_wormhash_contains(wh_src, smac, sip))
return EBT_NOMATCH;
return false;
}
}
if (wh_dst) {
dmac = eth_hdr(skb)->h_dest;
if (get_ip_dst(skb, &dip))
return EBT_NOMATCH;
return false;
if (!(info->bitmask & EBT_AMONG_DST_NEG)) {
/* we match only if it contains */
if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip))
return EBT_NOMATCH;
return false;
} else {
/* we match only if it DOES NOT contain */
if (ebt_mac_wormhash_contains(wh_dst, dmac, dip))
return EBT_NOMATCH;
return false;
}
}
return EBT_MATCH;
return true;
}
static int ebt_among_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data,
unsigned int datalen)
static bool ebt_among_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_among_info *info = data;
const struct ebt_among_info *info = par->matchinfo;
const struct ebt_entry_match *em =
container_of(par->matchinfo, const struct ebt_entry_match, data);
int expected_length = sizeof(struct ebt_among_info);
const struct ebt_mac_wormhash *wh_dst, *wh_src;
int err;
@ -191,42 +185,45 @@ static int ebt_among_check(const char *tablename, unsigned int hookmask,
expected_length += ebt_mac_wormhash_size(wh_dst);
expected_length += ebt_mac_wormhash_size(wh_src);
if (datalen != EBT_ALIGN(expected_length)) {
if (em->match_size != EBT_ALIGN(expected_length)) {
printk(KERN_WARNING
"ebtables: among: wrong size: %d "
"against expected %d, rounded to %Zd\n",
datalen, expected_length,
em->match_size, expected_length,
EBT_ALIGN(expected_length));
return -EINVAL;
return false;
}
if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) {
printk(KERN_WARNING
"ebtables: among: dst integrity fail: %x\n", -err);
return -EINVAL;
return false;
}
if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) {
printk(KERN_WARNING
"ebtables: among: src integrity fail: %x\n", -err);
return -EINVAL;
return false;
}
return 0;
return true;
}
static struct ebt_match filter_among __read_mostly = {
.name = EBT_AMONG_MATCH,
.match = ebt_filter_among,
.check = ebt_among_check,
static struct xt_match ebt_among_mt_reg __read_mostly = {
.name = "among",
.revision = 0,
.family = NFPROTO_BRIDGE,
.match = ebt_among_mt,
.checkentry = ebt_among_mt_check,
.matchsize = -1, /* special case */
.me = THIS_MODULE,
};
static int __init ebt_among_init(void)
{
return ebt_register_match(&filter_among);
return xt_register_match(&ebt_among_mt_reg);
}
static void __exit ebt_among_fini(void)
{
ebt_unregister_match(&filter_among);
xt_unregister_match(&ebt_among_mt_reg);
}
module_init(ebt_among_init);

View File

@ -8,58 +8,58 @@
* April, 2002
*
*/
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_arp.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_arp.h>
static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *data, unsigned int datalen)
static bool
ebt_arp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ebt_arp_info *info = data;
const struct ebt_arp_info *info = par->matchinfo;
const struct arphdr *ah;
struct arphdr _arph;
ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
if (ah == NULL)
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode !=
ah->ar_op, EBT_ARP_OPCODE))
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype !=
ah->ar_hrd, EBT_ARP_HTYPE))
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype !=
ah->ar_pro, EBT_ARP_PTYPE))
return EBT_NOMATCH;
return false;
if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) {
const __be32 *sap, *dap;
__be32 saddr, daddr;
if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP))
return EBT_NOMATCH;
return false;
sap = skb_header_pointer(skb, sizeof(struct arphdr) +
ah->ar_hln, sizeof(saddr),
&saddr);
if (sap == NULL)
return EBT_NOMATCH;
return false;
dap = skb_header_pointer(skb, sizeof(struct arphdr) +
2*ah->ar_hln+sizeof(saddr),
sizeof(daddr), &daddr);
if (dap == NULL)
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_ARP_SRC_IP &&
FWINV(info->saddr != (*sap & info->smsk), EBT_ARP_SRC_IP))
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_ARP_DST_IP &&
FWINV(info->daddr != (*dap & info->dmsk), EBT_ARP_DST_IP))
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_ARP_GRAT &&
FWINV(*dap != *sap, EBT_ARP_GRAT))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) {
@ -68,18 +68,18 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
uint8_t verdict, i;
if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER))
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_ARP_SRC_MAC) {
mp = skb_header_pointer(skb, sizeof(struct arphdr),
sizeof(_mac), &_mac);
if (mp == NULL)
return EBT_NOMATCH;
return false;
verdict = 0;
for (i = 0; i < 6; i++)
verdict |= (mp[i] ^ info->smaddr[i]) &
info->smmsk[i];
if (FWINV(verdict != 0, EBT_ARP_SRC_MAC))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_ARP_DST_MAC) {
@ -87,50 +87,51 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
ah->ar_hln + ah->ar_pln,
sizeof(_mac), &_mac);
if (mp == NULL)
return EBT_NOMATCH;
return false;
verdict = 0;
for (i = 0; i < 6; i++)
verdict |= (mp[i] ^ info->dmaddr[i]) &
info->dmmsk[i];
if (FWINV(verdict != 0, EBT_ARP_DST_MAC))
return EBT_NOMATCH;
return false;
}
}
return EBT_MATCH;
return true;
}
static int ebt_arp_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_arp_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_arp_info *info = data;
const struct ebt_arp_info *info = par->matchinfo;
const struct ebt_entry *e = par->entryinfo;
if (datalen != EBT_ALIGN(sizeof(struct ebt_arp_info)))
return -EINVAL;
if ((e->ethproto != htons(ETH_P_ARP) &&
e->ethproto != htons(ETH_P_RARP)) ||
e->invflags & EBT_IPROTO)
return -EINVAL;
return false;
if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK)
return -EINVAL;
return 0;
return false;
return true;
}
static struct ebt_match filter_arp __read_mostly = {
.name = EBT_ARP_MATCH,
.match = ebt_filter_arp,
.check = ebt_arp_check,
static struct xt_match ebt_arp_mt_reg __read_mostly = {
.name = "arp",
.revision = 0,
.family = NFPROTO_BRIDGE,
.match = ebt_arp_mt,
.checkentry = ebt_arp_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_arp_info)),
.me = THIS_MODULE,
};
static int __init ebt_arp_init(void)
{
return ebt_register_match(&filter_arp);
return xt_register_match(&ebt_arp_mt_reg);
}
static void __exit ebt_arp_fini(void)
{
ebt_unregister_match(&filter_arp);
xt_unregister_match(&ebt_arp_mt_reg);
}
module_init(ebt_arp_init);

View File

@ -8,18 +8,17 @@
* August, 2003
*
*/
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_arpreply.h>
#include <linux/if_arp.h>
#include <net/arp.h>
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_arpreply.h>
static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
static unsigned int
ebt_arpreply_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
struct ebt_arpreply_info *info = (void *)data;
const struct ebt_arpreply_info *info = par->targinfo;
const __be32 *siptr, *diptr;
__be32 _sip, _dip;
const struct arphdr *ap;
@ -52,45 +51,45 @@ static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
if (diptr == NULL)
return EBT_DROP;
arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr, (struct net_device *)in,
arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr, (struct net_device *)par->in,
*diptr, shp, info->mac, shp);
return info->target;
}
static int ebt_target_reply_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
{
const struct ebt_arpreply_info *info = data;
const struct ebt_arpreply_info *info = par->targinfo;
const struct ebt_entry *e = par->entryinfo;
if (datalen != EBT_ALIGN(sizeof(struct ebt_arpreply_info)))
return -EINVAL;
if (BASE_CHAIN && info->target == EBT_RETURN)
return -EINVAL;
return false;
if (e->ethproto != htons(ETH_P_ARP) ||
e->invflags & EBT_IPROTO)
return -EINVAL;
CLEAR_BASE_CHAIN_BIT;
if (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING))
return -EINVAL;
return 0;
return false;
return true;
}
static struct ebt_target reply_target __read_mostly = {
.name = EBT_ARPREPLY_TARGET,
.target = ebt_target_reply,
.check = ebt_target_reply_check,
static struct xt_target ebt_arpreply_tg_reg __read_mostly = {
.name = "arpreply",
.revision = 0,
.family = NFPROTO_BRIDGE,
.table = "nat",
.hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING),
.target = ebt_arpreply_tg,
.checkentry = ebt_arpreply_tg_check,
.targetsize = XT_ALIGN(sizeof(struct ebt_arpreply_info)),
.me = THIS_MODULE,
};
static int __init ebt_arpreply_init(void)
{
return ebt_register_target(&reply_target);
return xt_register_target(&ebt_arpreply_tg_reg);
}
static void __exit ebt_arpreply_fini(void)
{
ebt_unregister_target(&reply_target);
xt_unregister_target(&ebt_arpreply_tg_reg);
}
module_init(ebt_arpreply_init);

View File

@ -7,18 +7,17 @@
* June, 2002
*
*/
#include <linux/netfilter.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nat.h>
#include <linux/module.h>
#include <net/sock.h>
#include <linux/netfilter.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nat.h>
static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
static unsigned int
ebt_dnat_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct ebt_nat_info *info = data;
const struct ebt_nat_info *info = par->targinfo;
if (!skb_make_writable(skb, 0))
return EBT_DROP;
@ -27,40 +26,46 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
return info->target;
}
static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par)
{
const struct ebt_nat_info *info = data;
const struct ebt_nat_info *info = par->targinfo;
unsigned int hook_mask;
if (BASE_CHAIN && info->target == EBT_RETURN)
return -EINVAL;
CLEAR_BASE_CHAIN_BIT;
if ( (strcmp(tablename, "nat") ||
(hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) &&
(strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) )
return -EINVAL;
if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info)))
return -EINVAL;
return false;
hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
if ((strcmp(par->table, "nat") != 0 ||
(hook_mask & ~((1 << NF_BR_PRE_ROUTING) |
(1 << NF_BR_LOCAL_OUT)))) &&
(strcmp(par->table, "broute") != 0 ||
hook_mask & ~(1 << NF_BR_BROUTING)))
return false;
if (INVALID_TARGET)
return -EINVAL;
return 0;
return false;
return true;
}
static struct ebt_target dnat __read_mostly = {
.name = EBT_DNAT_TARGET,
.target = ebt_target_dnat,
.check = ebt_target_dnat_check,
static struct xt_target ebt_dnat_tg_reg __read_mostly = {
.name = "dnat",
.revision = 0,
.family = NFPROTO_BRIDGE,
.hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) |
(1 << NF_BR_LOCAL_OUT) | (1 << NF_BR_BROUTING),
.target = ebt_dnat_tg,
.checkentry = ebt_dnat_tg_check,
.targetsize = XT_ALIGN(sizeof(struct ebt_nat_info)),
.me = THIS_MODULE,
};
static int __init ebt_dnat_init(void)
{
return ebt_register_target(&dnat);
return xt_register_target(&ebt_dnat_tg_reg);
}
static void __exit ebt_dnat_fini(void)
{
ebt_unregister_target(&dnat);
xt_unregister_target(&ebt_dnat_tg_reg);
}
module_init(ebt_dnat_init);

View File

@ -11,24 +11,23 @@
* Innominate Security Technologies AG <mhopf@innominate.com>
* September, 2002
*/
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_ip.h>
#include <linux/ip.h>
#include <net/ip.h>
#include <linux/in.h>
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_ip.h>
struct tcpudphdr {
__be16 src;
__be16 dst;
};
static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *data,
unsigned int datalen)
static bool
ebt_ip_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ebt_ip_info *info = data;
const struct ebt_ip_info *info = par->matchinfo;
const struct iphdr *ih;
struct iphdr _iph;
const struct tcpudphdr *pptr;
@ -36,92 +35,93 @@ static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
if (ih == NULL)
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_IP_TOS &&
FWINV(info->tos != ih->tos, EBT_IP_TOS))
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_IP_SOURCE &&
FWINV((ih->saddr & info->smsk) !=
info->saddr, EBT_IP_SOURCE))
return EBT_NOMATCH;
return false;
if ((info->bitmask & EBT_IP_DEST) &&
FWINV((ih->daddr & info->dmsk) !=
info->daddr, EBT_IP_DEST))
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_IP_PROTO) {
if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO))
return EBT_NOMATCH;
return false;
if (!(info->bitmask & EBT_IP_DPORT) &&
!(info->bitmask & EBT_IP_SPORT))
return EBT_MATCH;
return true;
if (ntohs(ih->frag_off) & IP_OFFSET)
return EBT_NOMATCH;
return false;
pptr = skb_header_pointer(skb, ih->ihl*4,
sizeof(_ports), &_ports);
if (pptr == NULL)
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_IP_DPORT) {
u32 dst = ntohs(pptr->dst);
if (FWINV(dst < info->dport[0] ||
dst > info->dport[1],
EBT_IP_DPORT))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_IP_SPORT) {
u32 src = ntohs(pptr->src);
if (FWINV(src < info->sport[0] ||
src > info->sport[1],
EBT_IP_SPORT))
return EBT_NOMATCH;
return false;
}
}
return EBT_MATCH;
return true;
}
static int ebt_ip_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_ip_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_ip_info *info = data;
const struct ebt_ip_info *info = par->matchinfo;
const struct ebt_entry *e = par->entryinfo;
if (datalen != EBT_ALIGN(sizeof(struct ebt_ip_info)))
return -EINVAL;
if (e->ethproto != htons(ETH_P_IP) ||
e->invflags & EBT_IPROTO)
return -EINVAL;
return false;
if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK)
return -EINVAL;
return false;
if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) {
if (info->invflags & EBT_IP_PROTO)
return -EINVAL;
return false;
if (info->protocol != IPPROTO_TCP &&
info->protocol != IPPROTO_UDP &&
info->protocol != IPPROTO_UDPLITE &&
info->protocol != IPPROTO_SCTP &&
info->protocol != IPPROTO_DCCP)
return -EINVAL;
return false;
}
if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
return -EINVAL;
return false;
if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
return -EINVAL;
return 0;
return false;
return true;
}
static struct ebt_match filter_ip __read_mostly = {
.name = EBT_IP_MATCH,
.match = ebt_filter_ip,
.check = ebt_ip_check,
static struct xt_match ebt_ip_mt_reg __read_mostly = {
.name = "ip",
.revision = 0,
.family = NFPROTO_BRIDGE,
.match = ebt_ip_mt,
.checkentry = ebt_ip_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_ip_info)),
.me = THIS_MODULE,
};
static int __init ebt_ip_init(void)
{
return ebt_register_match(&filter_ip);
return xt_register_match(&ebt_ip_mt_reg);
}
static void __exit ebt_ip_fini(void)
{
ebt_unregister_match(&filter_ip);
xt_unregister_match(&ebt_ip_mt_reg);
}
module_init(ebt_ip_init);

View File

@ -13,26 +13,24 @@
*
* Jan, 2008
*/
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_ip6.h>
#include <linux/ipv6.h>
#include <net/ipv6.h>
#include <linux/in.h>
#include <linux/module.h>
#include <net/dsfield.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_ip6.h>
struct tcpudphdr {
__be16 src;
__be16 dst;
};
static int ebt_filter_ip6(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out, const void *data,
unsigned int datalen)
static bool
ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ebt_ip6_info *info = (struct ebt_ip6_info *)data;
const struct ebt_ip6_info *info = par->matchinfo;
const struct ipv6hdr *ih6;
struct ipv6hdr _ip6h;
const struct tcpudphdr *pptr;
@ -42,100 +40,100 @@ static int ebt_filter_ip6(const struct sk_buff *skb,
ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h);
if (ih6 == NULL)
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_IP6_TCLASS &&
FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS))
return EBT_NOMATCH;
return false;
for (i = 0; i < 4; i++)
tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] &
info->smsk.in6_u.u6_addr32[i];
if (info->bitmask & EBT_IP6_SOURCE &&
FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0),
EBT_IP6_SOURCE))
return EBT_NOMATCH;
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 EBT_NOMATCH;
return false;
if (info->bitmask & EBT_IP6_PROTO) {
uint8_t nexthdr = ih6->nexthdr;
int offset_ph;
offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr);
if (offset_ph == -1)
return EBT_NOMATCH;
return false;
if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO))
return EBT_NOMATCH;
return false;
if (!(info->bitmask & EBT_IP6_DPORT) &&
!(info->bitmask & EBT_IP6_SPORT))
return EBT_MATCH;
return true;
pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports),
&_ports);
if (pptr == NULL)
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_IP6_DPORT) {
u32 dst = ntohs(pptr->dst);
if (FWINV(dst < info->dport[0] ||
dst > info->dport[1], EBT_IP6_DPORT))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_IP6_SPORT) {
u32 src = ntohs(pptr->src);
if (FWINV(src < info->sport[0] ||
src > info->sport[1], EBT_IP6_SPORT))
return EBT_NOMATCH;
return false;
}
return EBT_MATCH;
return true;
}
return EBT_MATCH;
return true;
}
static int ebt_ip6_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_ip6_mt_check(const struct xt_mtchk_param *par)
{
struct ebt_ip6_info *info = (struct ebt_ip6_info *)data;
const struct ebt_entry *e = par->entryinfo;
struct ebt_ip6_info *info = par->matchinfo;
if (datalen != EBT_ALIGN(sizeof(struct ebt_ip6_info)))
return -EINVAL;
if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO)
return -EINVAL;
return false;
if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK)
return -EINVAL;
return false;
if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) {
if (info->invflags & EBT_IP6_PROTO)
return -EINVAL;
return false;
if (info->protocol != IPPROTO_TCP &&
info->protocol != IPPROTO_UDP &&
info->protocol != IPPROTO_UDPLITE &&
info->protocol != IPPROTO_SCTP &&
info->protocol != IPPROTO_DCCP)
return -EINVAL;
return false;
}
if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1])
return -EINVAL;
return false;
if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1])
return -EINVAL;
return 0;
return false;
return true;
}
static struct ebt_match filter_ip6 =
{
.name = EBT_IP6_MATCH,
.match = ebt_filter_ip6,
.check = ebt_ip6_check,
static struct xt_match ebt_ip6_mt_reg __read_mostly = {
.name = "ip6",
.revision = 0,
.family = NFPROTO_BRIDGE,
.match = ebt_ip6_mt,
.checkentry = ebt_ip6_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_ip6_info)),
.me = THIS_MODULE,
};
static int __init ebt_ip6_init(void)
{
return ebt_register_match(&filter_ip6);
return xt_register_match(&ebt_ip6_mt_reg);
}
static void __exit ebt_ip6_fini(void)
{
ebt_unregister_match(&filter_ip6);
xt_unregister_match(&ebt_ip6_mt_reg);
}
module_init(ebt_ip6_init);

View File

@ -10,13 +10,12 @@
* September, 2003
*
*/
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_limit.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_limit.h>
static DEFINE_SPINLOCK(limit_lock);
@ -31,11 +30,10 @@ static DEFINE_SPINLOCK(limit_lock);
#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
static int ebt_limit_match(const struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
static bool
ebt_limit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
struct ebt_limit_info *info = (struct ebt_limit_info *)data;
struct ebt_limit_info *info = (void *)par->matchinfo;
unsigned long now = jiffies;
spin_lock_bh(&limit_lock);
@ -47,11 +45,11 @@ static int ebt_limit_match(const struct sk_buff *skb,
/* We're not limited. */
info->credit -= info->cost;
spin_unlock_bh(&limit_lock);
return EBT_MATCH;
return true;
}
spin_unlock_bh(&limit_lock);
return EBT_NOMATCH;
return false;
}
/* Precision saver. */
@ -66,20 +64,16 @@ user2credits(u_int32_t user)
return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE;
}
static int ebt_limit_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_limit_mt_check(const struct xt_mtchk_param *par)
{
struct ebt_limit_info *info = data;
if (datalen != EBT_ALIGN(sizeof(struct ebt_limit_info)))
return -EINVAL;
struct ebt_limit_info *info = par->matchinfo;
/* Check for overflow. */
if (info->burst == 0 ||
user2credits(info->avg * info->burst) < user2credits(info->avg)) {
printk("Overflow in ebt_limit, try lower: %u/%u\n",
info->avg, info->burst);
return -EINVAL;
return false;
}
/* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */
@ -87,24 +81,27 @@ static int ebt_limit_check(const char *tablename, unsigned int hookmask,
info->credit = user2credits(info->avg * info->burst);
info->credit_cap = user2credits(info->avg * info->burst);
info->cost = user2credits(info->avg);
return 0;
return true;
}
static struct ebt_match ebt_limit_reg __read_mostly = {
.name = EBT_LIMIT_MATCH,
.match = ebt_limit_match,
.check = ebt_limit_check,
static struct xt_match ebt_limit_mt_reg __read_mostly = {
.name = "limit",
.revision = 0,
.family = NFPROTO_BRIDGE,
.match = ebt_limit_mt,
.checkentry = ebt_limit_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_limit_info)),
.me = THIS_MODULE,
};
static int __init ebt_limit_init(void)
{
return ebt_register_match(&ebt_limit_reg);
return xt_register_match(&ebt_limit_mt_reg);
}
static void __exit ebt_limit_fini(void)
{
ebt_unregister_match(&ebt_limit_reg);
xt_unregister_match(&ebt_limit_mt_reg);
}
module_init(ebt_limit_init);

View File

@ -8,10 +8,6 @@
* April, 2002
*
*/
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_log.h>
#include <linux/netfilter.h>
#include <linux/module.h>
#include <linux/ip.h>
#include <linux/in.h>
@ -21,22 +17,23 @@
#include <linux/ipv6.h>
#include <net/ipv6.h>
#include <linux/in6.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_log.h>
#include <linux/netfilter.h>
static DEFINE_SPINLOCK(ebt_log_lock);
static int ebt_log_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_log_tg_check(const struct xt_tgchk_param *par)
{
struct ebt_log_info *info = data;
struct ebt_log_info *info = par->targinfo;
if (datalen != EBT_ALIGN(sizeof(struct ebt_log_info)))
return -EINVAL;
if (info->bitmask & ~EBT_LOG_MASK)
return -EINVAL;
return false;
if (info->loglevel >= 8)
return -EINVAL;
return false;
info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0';
return 0;
return true;
}
struct tcpudphdr
@ -84,7 +81,7 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
#define myNIPQUAD(a) a[0], a[1], a[2], a[3]
static void
ebt_log_packet(unsigned int pf, unsigned int hooknum,
ebt_log_packet(u_int8_t pf, unsigned int hooknum,
const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct nf_loginfo *loginfo,
const char *prefix)
@ -194,11 +191,10 @@ out:
}
static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
static unsigned int
ebt_log_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct ebt_log_info *info = data;
const struct ebt_log_info *info = par->targinfo;
struct nf_loginfo li;
li.type = NF_LOG_TYPE_LOG;
@ -206,18 +202,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
li.u.log.logflags = info->bitmask;
if (info->bitmask & EBT_LOG_NFLOG)
nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li,
"%s", info->prefix);
nf_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
par->out, &li, "%s", info->prefix);
else
ebt_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li,
info->prefix);
ebt_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
par->out, &li, info->prefix);
return EBT_CONTINUE;
}
static struct ebt_watcher log =
{
.name = EBT_LOG_WATCHER,
.watcher = ebt_log,
.check = ebt_log_check,
static struct xt_target ebt_log_tg_reg __read_mostly = {
.name = "log",
.revision = 0,
.family = NFPROTO_BRIDGE,
.target = ebt_log_tg,
.checkentry = ebt_log_tg_check,
.targetsize = XT_ALIGN(sizeof(struct ebt_log_info)),
.me = THIS_MODULE,
};
@ -231,17 +230,17 @@ static int __init ebt_log_init(void)
{
int ret;
ret = ebt_register_watcher(&log);
ret = xt_register_target(&ebt_log_tg_reg);
if (ret < 0)
return ret;
nf_log_register(PF_BRIDGE, &ebt_log_logger);
nf_log_register(NFPROTO_BRIDGE, &ebt_log_logger);
return 0;
}
static void __exit ebt_log_fini(void)
{
nf_log_unregister(&ebt_log_logger);
ebt_unregister_watcher(&log);
xt_unregister_target(&ebt_log_tg_reg);
}
module_init(ebt_log_init);

View File

@ -13,15 +13,15 @@
* Marking a frame doesn't really change anything in the frame anyway.
*/
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_mark_t.h>
#include <linux/module.h>
static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
static unsigned int
ebt_mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct ebt_mark_t_info *info = data;
const struct ebt_mark_t_info *info = par->targinfo;
int action = info->target & -16;
if (action == MARK_SET_VALUE)
@ -36,42 +36,41 @@ static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr,
return info->target | ~EBT_VERDICT_BITS;
}
static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_mark_tg_check(const struct xt_tgchk_param *par)
{
const struct ebt_mark_t_info *info = data;
const struct ebt_mark_t_info *info = par->targinfo;
int tmp;
if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
return -EINVAL;
tmp = info->target | ~EBT_VERDICT_BITS;
if (BASE_CHAIN && tmp == EBT_RETURN)
return -EINVAL;
CLEAR_BASE_CHAIN_BIT;
return false;
if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
return -EINVAL;
return false;
tmp = info->target & ~EBT_VERDICT_BITS;
if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
return -EINVAL;
return 0;
return false;
return true;
}
static struct ebt_target mark_target __read_mostly = {
.name = EBT_MARK_TARGET,
.target = ebt_target_mark,
.check = ebt_target_mark_check,
static struct xt_target ebt_mark_tg_reg __read_mostly = {
.name = "mark",
.revision = 0,
.family = NFPROTO_BRIDGE,
.target = ebt_mark_tg,
.checkentry = ebt_mark_tg_check,
.targetsize = XT_ALIGN(sizeof(struct ebt_mark_t_info)),
.me = THIS_MODULE,
};
static int __init ebt_mark_init(void)
{
return ebt_register_target(&mark_target);
return xt_register_target(&ebt_mark_tg_reg);
}
static void __exit ebt_mark_fini(void)
{
ebt_unregister_target(&mark_target);
xt_unregister_target(&ebt_mark_tg_reg);
}
module_init(ebt_mark_init);

View File

@ -7,53 +7,52 @@
* July, 2002
*
*/
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_mark_m.h>
#include <linux/module.h>
static int ebt_filter_mark(const struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const void *data,
unsigned int datalen)
static bool
ebt_mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ebt_mark_m_info *info = data;
const struct ebt_mark_m_info *info = par->matchinfo;
if (info->bitmask & EBT_MARK_OR)
return !(!!(skb->mark & info->mask) ^ info->invert);
return !(((skb->mark & info->mask) == info->mark) ^ info->invert);
return !!(skb->mark & info->mask) ^ info->invert;
return ((skb->mark & info->mask) == info->mark) ^ info->invert;
}
static int ebt_mark_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_mark_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_mark_m_info *info = data;
const struct ebt_mark_m_info *info = par->matchinfo;
if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_m_info)))
return -EINVAL;
if (info->bitmask & ~EBT_MARK_MASK)
return -EINVAL;
return false;
if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND))
return -EINVAL;
return false;
if (!info->bitmask)
return -EINVAL;
return 0;
return false;
return true;
}
static struct ebt_match filter_mark __read_mostly = {
.name = EBT_MARK_MATCH,
.match = ebt_filter_mark,
.check = ebt_mark_check,
static struct xt_match ebt_mark_mt_reg __read_mostly = {
.name = "mark_m",
.revision = 0,
.family = NFPROTO_BRIDGE,
.match = ebt_mark_mt,
.checkentry = ebt_mark_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_mark_m_info)),
.me = THIS_MODULE,
};
static int __init ebt_mark_m_init(void)
{
return ebt_register_match(&filter_mark);
return xt_register_match(&ebt_mark_mt_reg);
}
static void __exit ebt_mark_m_fini(void)
{
ebt_unregister_match(&filter_mark);
xt_unregister_match(&ebt_mark_mt_reg);
}
module_init(ebt_mark_m_init);

View File

@ -14,17 +14,15 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nflog.h>
#include <net/netfilter/nf_log.h>
static void ebt_nflog(const struct sk_buff *skb,
unsigned int hooknr,
const struct net_device *in,
const struct net_device *out,
const void *data, unsigned int datalen)
static unsigned int
ebt_nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
struct ebt_nflog_info *info = (struct ebt_nflog_info *)data;
const struct ebt_nflog_info *info = par->targinfo;
struct nf_loginfo li;
li.type = NF_LOG_TYPE_ULOG;
@ -32,39 +30,39 @@ static void ebt_nflog(const struct sk_buff *skb,
li.u.ulog.group = info->group;
li.u.ulog.qthreshold = info->threshold;
nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, "%s", info->prefix);
nf_log_packet(PF_BRIDGE, par->hooknum, skb, par->in, par->out,
&li, "%s", info->prefix);
return EBT_CONTINUE;
}
static int ebt_nflog_check(const char *tablename,
unsigned int hookmask,
const struct ebt_entry *e,
void *data, unsigned int datalen)
static bool ebt_nflog_tg_check(const struct xt_tgchk_param *par)
{
struct ebt_nflog_info *info = (struct ebt_nflog_info *)data;
struct ebt_nflog_info *info = par->targinfo;
if (datalen != EBT_ALIGN(sizeof(struct ebt_nflog_info)))
return -EINVAL;
if (info->flags & ~EBT_NFLOG_MASK)
return -EINVAL;
return false;
info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0';
return 0;
return true;
}
static struct ebt_watcher nflog __read_mostly = {
.name = EBT_NFLOG_WATCHER,
.watcher = ebt_nflog,
.check = ebt_nflog_check,
.me = THIS_MODULE,
static struct xt_target ebt_nflog_tg_reg __read_mostly = {
.name = "nflog",
.revision = 0,
.family = NFPROTO_BRIDGE,
.target = ebt_nflog_tg,
.checkentry = ebt_nflog_tg_check,
.targetsize = XT_ALIGN(sizeof(struct ebt_nflog_info)),
.me = THIS_MODULE,
};
static int __init ebt_nflog_init(void)
{
return ebt_register_watcher(&nflog);
return xt_register_target(&ebt_nflog_tg_reg);
}
static void __exit ebt_nflog_fini(void)
{
ebt_unregister_watcher(&nflog);
xt_unregister_target(&ebt_nflog_tg_reg);
}
module_init(ebt_nflog_init);

View File

@ -7,50 +7,47 @@
* April, 2003
*
*/
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_pkttype.h>
#include <linux/module.h>
static int ebt_filter_pkttype(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *data,
unsigned int datalen)
static bool
ebt_pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ebt_pkttype_info *info = data;
const struct ebt_pkttype_info *info = par->matchinfo;
return (skb->pkt_type != info->pkt_type) ^ info->invert;
return (skb->pkt_type == info->pkt_type) ^ info->invert;
}
static int ebt_pkttype_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_pkttype_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_pkttype_info *info = data;
const struct ebt_pkttype_info *info = par->matchinfo;
if (datalen != EBT_ALIGN(sizeof(struct ebt_pkttype_info)))
return -EINVAL;
if (info->invert != 0 && info->invert != 1)
return -EINVAL;
return false;
/* Allow any pkt_type value */
return 0;
return true;
}
static struct ebt_match filter_pkttype __read_mostly = {
.name = EBT_PKTTYPE_MATCH,
.match = ebt_filter_pkttype,
.check = ebt_pkttype_check,
static struct xt_match ebt_pkttype_mt_reg __read_mostly = {
.name = "pkttype",
.revision = 0,
.family = NFPROTO_BRIDGE,
.match = ebt_pkttype_mt,
.checkentry = ebt_pkttype_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_pkttype_info)),
.me = THIS_MODULE,
};
static int __init ebt_pkttype_init(void)
{
return ebt_register_match(&filter_pkttype);
return xt_register_match(&ebt_pkttype_mt_reg);
}
static void __exit ebt_pkttype_fini(void)
{
ebt_unregister_match(&filter_pkttype);
xt_unregister_match(&ebt_pkttype_mt_reg);
}
module_init(ebt_pkttype_init);

View File

@ -7,65 +7,70 @@
* April, 2002
*
*/
#include <linux/netfilter.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_redirect.h>
#include <linux/module.h>
#include <net/sock.h>
#include "../br_private.h"
#include <linux/netfilter.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_redirect.h>
static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
static unsigned int
ebt_redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct ebt_redirect_info *info = data;
const struct ebt_redirect_info *info = par->targinfo;
if (!skb_make_writable(skb, 0))
return EBT_DROP;
if (hooknr != NF_BR_BROUTING)
if (par->hooknum != NF_BR_BROUTING)
memcpy(eth_hdr(skb)->h_dest,
in->br_port->br->dev->dev_addr, ETH_ALEN);
par->in->br_port->br->dev->dev_addr, ETH_ALEN);
else
memcpy(eth_hdr(skb)->h_dest, in->dev_addr, ETH_ALEN);
memcpy(eth_hdr(skb)->h_dest, par->in->dev_addr, ETH_ALEN);
skb->pkt_type = PACKET_HOST;
return info->target;
}
static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_redirect_tg_check(const struct xt_tgchk_param *par)
{
const struct ebt_redirect_info *info = data;
const struct ebt_redirect_info *info = par->targinfo;
unsigned int hook_mask;
if (datalen != EBT_ALIGN(sizeof(struct ebt_redirect_info)))
return -EINVAL;
if (BASE_CHAIN && info->target == EBT_RETURN)
return -EINVAL;
CLEAR_BASE_CHAIN_BIT;
if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) &&
(strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) )
return -EINVAL;
return false;
hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
if ((strcmp(par->table, "nat") != 0 ||
hook_mask & ~(1 << NF_BR_PRE_ROUTING)) &&
(strcmp(par->table, "broute") != 0 ||
hook_mask & ~(1 << NF_BR_BROUTING)))
return false;
if (INVALID_TARGET)
return -EINVAL;
return 0;
return false;
return true;
}
static struct ebt_target redirect_target __read_mostly = {
.name = EBT_REDIRECT_TARGET,
.target = ebt_target_redirect,
.check = ebt_target_redirect_check,
static struct xt_target ebt_redirect_tg_reg __read_mostly = {
.name = "redirect",
.revision = 0,
.family = NFPROTO_BRIDGE,
.hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) |
(1 << NF_BR_BROUTING),
.target = ebt_redirect_tg,
.checkentry = ebt_redirect_tg_check,
.targetsize = XT_ALIGN(sizeof(struct ebt_redirect_info)),
.me = THIS_MODULE,
};
static int __init ebt_redirect_init(void)
{
return ebt_register_target(&redirect_target);
return xt_register_target(&ebt_redirect_tg_reg);
}
static void __exit ebt_redirect_fini(void)
{
ebt_unregister_target(&redirect_target);
xt_unregister_target(&ebt_redirect_tg_reg);
}
module_init(ebt_redirect_init);

View File

@ -7,20 +7,19 @@
* June, 2002
*
*/
#include <linux/netfilter.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nat.h>
#include <linux/module.h>
#include <net/sock.h>
#include <linux/if_arp.h>
#include <net/arp.h>
#include <linux/netfilter.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nat.h>
static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
static unsigned int
ebt_snat_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct ebt_nat_info *info = data;
const struct ebt_nat_info *info = par->targinfo;
if (!skb_make_writable(skb, 0))
return EBT_DROP;
@ -43,46 +42,43 @@ out:
return info->target | ~EBT_VERDICT_BITS;
}
static int ebt_target_snat_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_snat_tg_check(const struct xt_tgchk_param *par)
{
const struct ebt_nat_info *info = data;
const struct ebt_nat_info *info = par->targinfo;
int tmp;
if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info)))
return -EINVAL;
tmp = info->target | ~EBT_VERDICT_BITS;
if (BASE_CHAIN && tmp == EBT_RETURN)
return -EINVAL;
CLEAR_BASE_CHAIN_BIT;
if (strcmp(tablename, "nat"))
return -EINVAL;
if (hookmask & ~(1 << NF_BR_POST_ROUTING))
return -EINVAL;
return false;
if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
return -EINVAL;
return false;
tmp = info->target | EBT_VERDICT_BITS;
if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT)
return -EINVAL;
return 0;
return false;
return true;
}
static struct ebt_target snat __read_mostly = {
.name = EBT_SNAT_TARGET,
.target = ebt_target_snat,
.check = ebt_target_snat_check,
static struct xt_target ebt_snat_tg_reg __read_mostly = {
.name = "snat",
.revision = 0,
.family = NFPROTO_BRIDGE,
.table = "nat",
.hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_POST_ROUTING),
.target = ebt_snat_tg,
.checkentry = ebt_snat_tg_check,
.targetsize = XT_ALIGN(sizeof(struct ebt_nat_info)),
.me = THIS_MODULE,
};
static int __init ebt_snat_init(void)
{
return ebt_register_target(&snat);
return xt_register_target(&ebt_snat_tg_reg);
}
static void __exit ebt_snat_fini(void)
{
ebt_unregister_target(&snat);
xt_unregister_target(&ebt_snat_tg_reg);
}
module_init(ebt_snat_init);

View File

@ -7,11 +7,11 @@
*
* July, 2003
*/
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_stp.h>
#include <linux/etherdevice.h>
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_stp.h>
#define BPDU_TYPE_CONFIG 0
#define BPDU_TYPE_TCN 0x80
@ -40,7 +40,7 @@ struct stp_config_pdu {
#define NR16(p) (p[0] << 8 | p[1])
#define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3])
static int ebt_filter_config(const struct ebt_stp_info *info,
static bool ebt_filter_config(const struct ebt_stp_info *info,
const struct stp_config_pdu *stpc)
{
const struct ebt_stp_config_info *c;
@ -51,12 +51,12 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
c = &info->config;
if ((info->bitmask & EBT_STP_FLAGS) &&
FWINV(c->flags != stpc->flags, EBT_STP_FLAGS))
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_STP_ROOTPRIO) {
v16 = NR16(stpc->root);
if (FWINV(v16 < c->root_priol ||
v16 > c->root_priou, EBT_STP_ROOTPRIO))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_STP_ROOTADDR) {
verdict = 0;
@ -64,19 +64,19 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
verdict |= (stpc->root[2+i] ^ c->root_addr[i]) &
c->root_addrmsk[i];
if (FWINV(verdict != 0, EBT_STP_ROOTADDR))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_STP_ROOTCOST) {
v32 = NR32(stpc->root_cost);
if (FWINV(v32 < c->root_costl ||
v32 > c->root_costu, EBT_STP_ROOTCOST))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_STP_SENDERPRIO) {
v16 = NR16(stpc->sender);
if (FWINV(v16 < c->sender_priol ||
v16 > c->sender_priou, EBT_STP_SENDERPRIO))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_STP_SENDERADDR) {
verdict = 0;
@ -84,60 +84,60 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) &
c->sender_addrmsk[i];
if (FWINV(verdict != 0, EBT_STP_SENDERADDR))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_STP_PORT) {
v16 = NR16(stpc->port);
if (FWINV(v16 < c->portl ||
v16 > c->portu, EBT_STP_PORT))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_STP_MSGAGE) {
v16 = NR16(stpc->msg_age);
if (FWINV(v16 < c->msg_agel ||
v16 > c->msg_ageu, EBT_STP_MSGAGE))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_STP_MAXAGE) {
v16 = NR16(stpc->max_age);
if (FWINV(v16 < c->max_agel ||
v16 > c->max_ageu, EBT_STP_MAXAGE))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_STP_HELLOTIME) {
v16 = NR16(stpc->hello_time);
if (FWINV(v16 < c->hello_timel ||
v16 > c->hello_timeu, EBT_STP_HELLOTIME))
return EBT_NOMATCH;
return false;
}
if (info->bitmask & EBT_STP_FWDD) {
v16 = NR16(stpc->forward_delay);
if (FWINV(v16 < c->forward_delayl ||
v16 > c->forward_delayu, EBT_STP_FWDD))
return EBT_NOMATCH;
return false;
}
return EBT_MATCH;
return true;
}
static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *data, unsigned int datalen)
static bool
ebt_stp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ebt_stp_info *info = data;
const struct ebt_stp_info *info = par->matchinfo;
const struct stp_header *sp;
struct stp_header _stph;
const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph);
if (sp == NULL)
return EBT_NOMATCH;
return false;
/* The stp code only considers these */
if (memcmp(sp, header, sizeof(header)))
return EBT_NOMATCH;
return false;
if (info->bitmask & EBT_STP_TYPE
&& FWINV(info->type != sp->type, EBT_STP_TYPE))
return EBT_NOMATCH;
return false;
if (sp->type == BPDU_TYPE_CONFIG &&
info->bitmask & EBT_STP_CONFIG_MASK) {
@ -147,48 +147,48 @@ static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in
st = skb_header_pointer(skb, sizeof(_stph),
sizeof(_stpc), &_stpc);
if (st == NULL)
return EBT_NOMATCH;
return false;
return ebt_filter_config(info, st);
}
return EBT_MATCH;
return true;
}
static int ebt_stp_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_stp_mt_check(const struct xt_mtchk_param *par)
{
const struct ebt_stp_info *info = data;
const unsigned int len = EBT_ALIGN(sizeof(struct ebt_stp_info));
const struct ebt_stp_info *info = par->matchinfo;
const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00};
const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const struct ebt_entry *e = par->entryinfo;
if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK ||
!(info->bitmask & EBT_STP_MASK))
return -EINVAL;
if (datalen != len)
return -EINVAL;
return false;
/* Make sure the match only receives stp frames */
if (compare_ether_addr(e->destmac, bridge_ula) ||
compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC))
return -EINVAL;
return false;
return 0;
return true;
}
static struct ebt_match filter_stp __read_mostly = {
.name = EBT_STP_MATCH,
.match = ebt_filter_stp,
.check = ebt_stp_check,
static struct xt_match ebt_stp_mt_reg __read_mostly = {
.name = "stp",
.revision = 0,
.family = NFPROTO_BRIDGE,
.match = ebt_stp_mt,
.checkentry = ebt_stp_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_stp_info)),
.me = THIS_MODULE,
};
static int __init ebt_stp_init(void)
{
return ebt_register_match(&filter_stp);
return xt_register_match(&ebt_stp_mt_reg);
}
static void __exit ebt_stp_fini(void)
{
ebt_unregister_match(&filter_stp);
xt_unregister_match(&ebt_stp_mt_reg);
}
module_init(ebt_stp_init);

View File

@ -36,6 +36,7 @@
#include <linux/timer.h>
#include <linux/netlink.h>
#include <linux/netdevice.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_ulog.h>
#include <net/netfilter/nf_log.h>
@ -223,7 +224,7 @@ alloc_failure:
}
/* this function is registered with the netfilter core */
static void ebt_log_packet(unsigned int pf, unsigned int hooknum,
static void ebt_log_packet(u_int8_t pf, unsigned int hooknum,
const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct nf_loginfo *li,
const char *prefix)
@ -245,24 +246,20 @@ static void ebt_log_packet(unsigned int pf, unsigned int hooknum,
ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
}
static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
static unsigned int
ebt_ulog_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct ebt_ulog_info *uloginfo = data;
ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL);
ebt_ulog_packet(par->hooknum, skb, par->in, par->out,
par->targinfo, NULL);
return EBT_CONTINUE;
}
static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par)
{
struct ebt_ulog_info *uloginfo = data;
struct ebt_ulog_info *uloginfo = par->targinfo;
if (datalen != EBT_ALIGN(sizeof(struct ebt_ulog_info)) ||
uloginfo->nlgroup > 31)
return -EINVAL;
if (uloginfo->nlgroup > 31)
return false;
uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0';
@ -272,27 +269,31 @@ static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
return 0;
}
static struct ebt_watcher ulog __read_mostly = {
.name = EBT_ULOG_WATCHER,
.watcher = ebt_ulog,
.check = ebt_ulog_check,
static struct xt_target ebt_ulog_tg_reg __read_mostly = {
.name = "ulog",
.revision = 0,
.family = NFPROTO_BRIDGE,
.target = ebt_ulog_tg,
.checkentry = ebt_ulog_tg_check,
.targetsize = XT_ALIGN(sizeof(struct ebt_ulog_info)),
.me = THIS_MODULE,
};
static const struct nf_logger ebt_ulog_logger = {
.name = EBT_ULOG_WATCHER,
.name = "ulog",
.logfn = &ebt_log_packet,
.me = THIS_MODULE,
};
static int __init ebt_ulog_init(void)
{
int i, ret = 0;
bool ret = true;
int i;
if (nlbufsiz >= 128*1024) {
printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB,"
" please try a smaller nlbufsiz parameter.\n");
return -EINVAL;
return false;
}
/* initialize ulog_buffers */
@ -304,13 +305,16 @@ static int __init ebt_ulog_init(void)
ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
EBT_ULOG_MAXNLGROUPS, NULL, NULL,
THIS_MODULE);
if (!ebtulognl)
ret = -ENOMEM;
else if ((ret = ebt_register_watcher(&ulog)))
if (!ebtulognl) {
printk(KERN_WARNING KBUILD_MODNAME ": out of memory trying to "
"call netlink_kernel_create\n");
ret = false;
} else if (xt_register_target(&ebt_ulog_tg_reg) != 0) {
netlink_kernel_release(ebtulognl);
}
if (ret == 0)
nf_log_register(PF_BRIDGE, &ebt_ulog_logger);
if (ret)
nf_log_register(NFPROTO_BRIDGE, &ebt_ulog_logger);
return ret;
}
@ -321,7 +325,7 @@ static void __exit ebt_ulog_fini(void)
int i;
nf_log_unregister(&ebt_ulog_logger);
ebt_unregister_watcher(&ulog);
xt_unregister_target(&ebt_ulog_tg_reg);
for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
ub = &ulog_buffers[i];
if (timer_pending(&ub->timer))

View File

@ -22,6 +22,7 @@
#include <linux/if_vlan.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_vlan.h>
@ -37,15 +38,12 @@ 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 EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return EBT_NOMATCH;}
#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return false; }
static int
ebt_filter_vlan(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *data, unsigned int datalen)
static bool
ebt_vlan_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ebt_vlan_info *info = data;
const struct ebt_vlan_info *info = par->matchinfo;
const struct vlan_hdr *fp;
struct vlan_hdr _frame;
@ -57,7 +55,7 @@ ebt_filter_vlan(const struct sk_buff *skb,
fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame);
if (fp == NULL)
return EBT_NOMATCH;
return false;
/* Tag Control Information (TCI) consists of the following elements:
* - User_priority. The user_priority field is three bits in length,
@ -83,30 +81,20 @@ ebt_filter_vlan(const struct sk_buff *skb,
if (GET_BITMASK(EBT_VLAN_ENCAP))
EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP);
return EBT_MATCH;
return true;
}
static int
ebt_check_vlan(const char *tablename,
unsigned int hooknr,
const struct ebt_entry *e, void *data, unsigned int datalen)
static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
{
struct ebt_vlan_info *info = data;
/* Parameters buffer overflow check */
if (datalen != EBT_ALIGN(sizeof(struct ebt_vlan_info))) {
DEBUG_MSG
("passed size %d is not eq to ebt_vlan_info (%Zd)\n",
datalen, sizeof(struct ebt_vlan_info));
return -EINVAL;
}
struct ebt_vlan_info *info = par->matchinfo;
const struct ebt_entry *e = par->entryinfo;
/* Is it 802.1Q frame checked? */
if (e->ethproto != htons(ETH_P_8021Q)) {
DEBUG_MSG
("passed entry proto %2.4X is not 802.1Q (8100)\n",
(unsigned short) ntohs(e->ethproto));
return -EINVAL;
return false;
}
/* Check for bitmask range
@ -114,14 +102,14 @@ ebt_check_vlan(const char *tablename,
if (info->bitmask & ~EBT_VLAN_MASK) {
DEBUG_MSG("bitmask %2X is out of mask (%2X)\n",
info->bitmask, EBT_VLAN_MASK);
return -EINVAL;
return false;
}
/* Check for inversion flags range */
if (info->invflags & ~EBT_VLAN_MASK) {
DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n",
info->invflags, EBT_VLAN_MASK);
return -EINVAL;
return false;
}
/* Reserved VLAN ID (VID) values
@ -136,7 +124,7 @@ ebt_check_vlan(const char *tablename,
DEBUG_MSG
("id %d is out of range (1-4096)\n",
info->id);
return -EINVAL;
return false;
}
/* Note: This is valid VLAN-tagged frame point.
* Any value of user_priority are acceptable,
@ -151,7 +139,7 @@ ebt_check_vlan(const char *tablename,
if ((unsigned char) info->prio > 7) {
DEBUG_MSG("prio %d is out of range (0-7)\n",
info->prio);
return -EINVAL;
return false;
}
}
/* Check for encapsulated proto range - it is possible to be
@ -162,17 +150,20 @@ ebt_check_vlan(const char *tablename,
DEBUG_MSG
("encap frame length %d is less than minimal\n",
ntohs(info->encap));
return -EINVAL;
return false;
}
}
return 0;
return true;
}
static struct ebt_match filter_vlan __read_mostly = {
.name = EBT_VLAN_MATCH,
.match = ebt_filter_vlan,
.check = ebt_check_vlan,
static struct xt_match ebt_vlan_mt_reg __read_mostly = {
.name = "vlan",
.revision = 0,
.family = NFPROTO_BRIDGE,
.match = ebt_vlan_mt,
.checkentry = ebt_vlan_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_vlan_info)),
.me = THIS_MODULE,
};
@ -181,12 +172,12 @@ static int __init ebt_vlan_init(void)
DEBUG_MSG("ebtables 802.1Q extension module v"
MODULE_VERS "\n");
DEBUG_MSG("module debug=%d\n", !!debug);
return ebt_register_match(&filter_vlan);
return xt_register_match(&ebt_vlan_mt_reg);
}
static void __exit ebt_vlan_fini(void)
{
ebt_unregister_match(&filter_vlan);
xt_unregister_match(&ebt_vlan_mt_reg);
}
module_init(ebt_vlan_init);

View File

@ -19,6 +19,7 @@
#include <linux/kmod.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
@ -55,29 +56,31 @@
static DEFINE_MUTEX(ebt_mutex);
static LIST_HEAD(ebt_tables);
static LIST_HEAD(ebt_targets);
static LIST_HEAD(ebt_matches);
static LIST_HEAD(ebt_watchers);
static struct ebt_target ebt_standard_target =
{ {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL};
static struct xt_target ebt_standard_target = {
.name = "standard",
.revision = 0,
.family = NFPROTO_BRIDGE,
.targetsize = sizeof(int),
};
static inline int ebt_do_watcher (struct ebt_entry_watcher *w,
const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in,
const struct net_device *out)
static inline int
ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb,
struct xt_target_param *par)
{
w->u.watcher->watcher(skb, hooknr, in, out, w->data,
w->watcher_size);
par->target = w->u.watcher;
par->targinfo = w->data;
w->u.watcher->target(skb, par);
/* watchers don't give a verdict */
return 0;
}
static inline int ebt_do_match (struct ebt_entry_match *m,
const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out)
const struct sk_buff *skb, struct xt_match_param *par)
{
return m->u.match->match(skb, in, out, m->data,
m->match_size);
par->match = m->u.match;
par->matchinfo = m->data;
return m->u.match->match(skb, par);
}
static inline int ebt_dev_check(char *entry, const struct net_device *device)
@ -153,6 +156,15 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
struct ebt_entries *chaininfo;
char *base;
struct ebt_table_info *private;
bool hotdrop = false;
struct xt_match_param mtpar;
struct xt_target_param tgpar;
mtpar.family = tgpar.family = NFPROTO_BRIDGE;
mtpar.in = tgpar.in = in;
mtpar.out = tgpar.out = out;
mtpar.hotdrop = &hotdrop;
tgpar.hooknum = hook;
read_lock_bh(&table->lock);
private = table->private;
@ -173,8 +185,12 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
if (ebt_basic_match(point, eth_hdr(skb), in, out))
goto letscontinue;
if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, in, out) != 0)
if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &mtpar) != 0)
goto letscontinue;
if (hotdrop) {
read_unlock_bh(&table->lock);
return NF_DROP;
}
/* increase counter */
(*(counter_base + i)).pcnt++;
@ -182,17 +198,18 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
/* these should only watch: not modify, nor tell us
what to do with the packet */
EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, hook, in,
out);
EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, &tgpar);
t = (struct ebt_entry_target *)
(((char *)point) + point->target_offset);
/* standard target */
if (!t->u.target->target)
verdict = ((struct ebt_standard_target *)t)->verdict;
else
verdict = t->u.target->target(skb, hook,
in, out, t->data, t->target_size);
else {
tgpar.target = t->u.target;
tgpar.targinfo = t->data;
verdict = t->u.target->target(skb, &tgpar);
}
if (verdict == EBT_ACCEPT) {
read_unlock_bh(&table->lock);
return NF_ACCEPT;
@ -312,80 +329,71 @@ find_table_lock(const char *name, int *error, struct mutex *mutex)
return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
}
static inline struct ebt_match *
find_match_lock(const char *name, int *error, struct mutex *mutex)
{
return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex);
}
static inline struct ebt_watcher *
find_watcher_lock(const char *name, int *error, struct mutex *mutex)
{
return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex);
}
static inline struct ebt_target *
find_target_lock(const char *name, int *error, struct mutex *mutex)
{
return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex);
}
static inline int
ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
const char *name, unsigned int hookmask, unsigned int *cnt)
ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par,
unsigned int *cnt)
{
struct ebt_match *match;
const struct ebt_entry *e = par->entryinfo;
struct xt_match *match;
size_t left = ((char *)e + e->watchers_offset) - (char *)m;
int ret;
if (left < sizeof(struct ebt_entry_match) ||
left - sizeof(struct ebt_entry_match) < m->match_size)
return -EINVAL;
match = find_match_lock(m->u.name, &ret, &ebt_mutex);
if (!match)
return ret;
m->u.match = match;
if (!try_module_get(match->me)) {
mutex_unlock(&ebt_mutex);
match = try_then_request_module(xt_find_match(NFPROTO_BRIDGE,
m->u.name, 0), "ebt_%s", m->u.name);
if (IS_ERR(match))
return PTR_ERR(match);
if (match == NULL)
return -ENOENT;
}
mutex_unlock(&ebt_mutex);
if (match->check &&
match->check(name, hookmask, e, m->data, m->match_size) != 0) {
BUGPRINT("match->check failed\n");
m->u.match = match;
par->match = match;
par->matchinfo = m->data;
ret = xt_check_match(par, m->match_size,
e->ethproto, e->invflags & EBT_IPROTO);
if (ret < 0) {
module_put(match->me);
return -EINVAL;
return ret;
}
(*cnt)++;
return 0;
}
static inline int
ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
const char *name, unsigned int hookmask, unsigned int *cnt)
ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par,
unsigned int *cnt)
{
struct ebt_watcher *watcher;
const struct ebt_entry *e = par->entryinfo;
struct xt_target *watcher;
size_t left = ((char *)e + e->target_offset) - (char *)w;
int ret;
if (left < sizeof(struct ebt_entry_watcher) ||
left - sizeof(struct ebt_entry_watcher) < w->watcher_size)
return -EINVAL;
watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex);
if (!watcher)
return ret;
w->u.watcher = watcher;
if (!try_module_get(watcher->me)) {
mutex_unlock(&ebt_mutex);
watcher = try_then_request_module(
xt_find_target(NFPROTO_BRIDGE, w->u.name, 0),
"ebt_%s", w->u.name);
if (IS_ERR(watcher))
return PTR_ERR(watcher);
if (watcher == NULL)
return -ENOENT;
}
mutex_unlock(&ebt_mutex);
if (watcher->check &&
watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) {
BUGPRINT("watcher->check failed\n");
w->u.watcher = watcher;
par->target = watcher;
par->targinfo = w->data;
ret = xt_check_target(par, w->watcher_size,
e->ethproto, e->invflags & EBT_IPROTO);
if (ret < 0) {
module_put(watcher->me);
return -EINVAL;
return ret;
}
(*cnt)++;
return 0;
}
@ -558,30 +566,41 @@ ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
static inline int
ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
{
struct xt_mtdtor_param par;
if (i && (*i)-- == 0)
return 1;
if (m->u.match->destroy)
m->u.match->destroy(m->data, m->match_size);
module_put(m->u.match->me);
par.match = m->u.match;
par.matchinfo = m->data;
par.family = NFPROTO_BRIDGE;
if (par.match->destroy != NULL)
par.match->destroy(&par);
module_put(par.match->me);
return 0;
}
static inline int
ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
{
struct xt_tgdtor_param par;
if (i && (*i)-- == 0)
return 1;
if (w->u.watcher->destroy)
w->u.watcher->destroy(w->data, w->watcher_size);
module_put(w->u.watcher->me);
par.target = w->u.watcher;
par.targinfo = w->data;
par.family = NFPROTO_BRIDGE;
if (par.target->destroy != NULL)
par.target->destroy(&par);
module_put(par.target->me);
return 0;
}
static inline int
ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
{
struct xt_tgdtor_param par;
struct ebt_entry_target *t;
if (e->bitmask == 0)
@ -592,10 +611,13 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
if (t->u.target->destroy)
t->u.target->destroy(t->data, t->target_size);
module_put(t->u.target->me);
par.target = t->u.target;
par.targinfo = t->data;
par.family = NFPROTO_BRIDGE;
if (par.target->destroy != NULL)
par.target->destroy(&par);
module_put(par.target->me);
return 0;
}
@ -605,10 +627,12 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
{
struct ebt_entry_target *t;
struct ebt_target *target;
struct xt_target *target;
unsigned int i, j, hook = 0, hookmask = 0;
size_t gap;
int ret;
struct xt_mtchk_param mtpar;
struct xt_tgchk_param tgpar;
/* don't mess with the struct ebt_entries */
if (e->bitmask == 0)
@ -649,24 +673,31 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
hookmask = cl_s[i - 1].hookmask;
}
i = 0;
ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i);
mtpar.table = tgpar.table = name;
mtpar.entryinfo = tgpar.entryinfo = e;
mtpar.hook_mask = tgpar.hook_mask = hookmask;
mtpar.family = tgpar.family = NFPROTO_BRIDGE;
ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i);
if (ret != 0)
goto cleanup_matches;
j = 0;
ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j);
ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, &tgpar, &j);
if (ret != 0)
goto cleanup_watchers;
t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
gap = e->next_offset - e->target_offset;
target = find_target_lock(t->u.name, &ret, &ebt_mutex);
if (!target)
target = try_then_request_module(
xt_find_target(NFPROTO_BRIDGE, t->u.name, 0),
"ebt_%s", t->u.name);
if (IS_ERR(target)) {
ret = PTR_ERR(target);
goto cleanup_watchers;
if (!try_module_get(target->me)) {
mutex_unlock(&ebt_mutex);
} else if (target == NULL) {
ret = -ENOENT;
goto cleanup_watchers;
}
mutex_unlock(&ebt_mutex);
t->u.target = target;
if (t->u.target == &ebt_standard_target) {
@ -681,13 +712,20 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
ret = -EFAULT;
goto cleanup_watchers;
}
} else if (t->target_size > gap - sizeof(struct ebt_entry_target) ||
(t->u.target->check &&
t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
} else if (t->target_size > gap - sizeof(struct ebt_entry_target)) {
module_put(t->u.target->me);
ret = -EFAULT;
goto cleanup_watchers;
}
tgpar.target = target;
tgpar.targinfo = t->data;
ret = xt_check_target(&tgpar, t->target_size,
e->ethproto, e->invflags & EBT_IPROTO);
if (ret < 0) {
module_put(target->me);
goto cleanup_watchers;
}
(*cnt)++;
return 0;
cleanup_watchers:
@ -1068,87 +1106,6 @@ free_newinfo:
return ret;
}
int ebt_register_target(struct ebt_target *target)
{
struct ebt_target *t;
int ret;
ret = mutex_lock_interruptible(&ebt_mutex);
if (ret != 0)
return ret;
list_for_each_entry(t, &ebt_targets, list) {
if (strcmp(t->name, target->name) == 0) {
mutex_unlock(&ebt_mutex);
return -EEXIST;
}
}
list_add(&target->list, &ebt_targets);
mutex_unlock(&ebt_mutex);
return 0;
}
void ebt_unregister_target(struct ebt_target *target)
{
mutex_lock(&ebt_mutex);
list_del(&target->list);
mutex_unlock(&ebt_mutex);
}
int ebt_register_match(struct ebt_match *match)
{
struct ebt_match *m;
int ret;
ret = mutex_lock_interruptible(&ebt_mutex);
if (ret != 0)
return ret;
list_for_each_entry(m, &ebt_matches, list) {
if (strcmp(m->name, match->name) == 0) {
mutex_unlock(&ebt_mutex);
return -EEXIST;
}
}
list_add(&match->list, &ebt_matches);
mutex_unlock(&ebt_mutex);
return 0;
}
void ebt_unregister_match(struct ebt_match *match)
{
mutex_lock(&ebt_mutex);
list_del(&match->list);
mutex_unlock(&ebt_mutex);
}
int ebt_register_watcher(struct ebt_watcher *watcher)
{
struct ebt_watcher *w;
int ret;
ret = mutex_lock_interruptible(&ebt_mutex);
if (ret != 0)
return ret;
list_for_each_entry(w, &ebt_watchers, list) {
if (strcmp(w->name, watcher->name) == 0) {
mutex_unlock(&ebt_mutex);
return -EEXIST;
}
}
list_add(&watcher->list, &ebt_watchers);
mutex_unlock(&ebt_mutex);
return 0;
}
void ebt_unregister_watcher(struct ebt_watcher *watcher)
{
mutex_lock(&ebt_mutex);
list_del(&watcher->list);
mutex_unlock(&ebt_mutex);
}
int ebt_register_table(struct ebt_table *table)
{
struct ebt_table_info *newinfo;
@ -1518,11 +1475,14 @@ static int __init ebtables_init(void)
{
int ret;
mutex_lock(&ebt_mutex);
list_add(&ebt_standard_target.list, &ebt_targets);
mutex_unlock(&ebt_mutex);
if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0)
ret = xt_register_target(&ebt_standard_target);
if (ret < 0)
return ret;
ret = nf_register_sockopt(&ebt_sockopts);
if (ret < 0) {
xt_unregister_target(&ebt_standard_target);
return ret;
}
printk(KERN_INFO "Ebtables v2.0 registered\n");
return 0;
@ -1531,17 +1491,12 @@ static int __init ebtables_init(void)
static void __exit ebtables_fini(void)
{
nf_unregister_sockopt(&ebt_sockopts);
xt_unregister_target(&ebt_standard_target);
printk(KERN_INFO "Ebtables v2.0 unregistered\n");
}
EXPORT_SYMBOL(ebt_register_table);
EXPORT_SYMBOL(ebt_unregister_table);
EXPORT_SYMBOL(ebt_register_match);
EXPORT_SYMBOL(ebt_unregister_match);
EXPORT_SYMBOL(ebt_register_watcher);
EXPORT_SYMBOL(ebt_unregister_watcher);
EXPORT_SYMBOL(ebt_register_target);
EXPORT_SYMBOL(ebt_unregister_target);
EXPORT_SYMBOL(ebt_do_table);
module_init(ebtables_init);
module_exit(ebtables_fini);

View File

@ -18,6 +18,7 @@ static struct list_head *first_device = &pernet_list;
static DEFINE_MUTEX(net_mutex);
LIST_HEAD(net_namespace_list);
EXPORT_SYMBOL_GPL(net_namespace_list);
struct net init_net;
EXPORT_SYMBOL(init_net);

View File

@ -12,6 +12,7 @@
/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
{
struct net *net = dev_net(skb->dst->dev);
const struct iphdr *iph = ip_hdr(skb);
struct rtable *rt;
struct flowi fl = {};
@ -19,7 +20,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
unsigned int hh_len;
unsigned int type;
type = inet_addr_type(&init_net, iph->saddr);
type = inet_addr_type(net, iph->saddr);
if (skb->sk && inet_sk(skb->sk)->transparent)
type = RTN_LOCAL;
if (addr_type == RTN_UNSPEC)
@ -36,7 +37,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
fl.mark = skb->mark;
fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
if (ip_route_output_key(&init_net, &rt, &fl) != 0)
if (ip_route_output_key(net, &rt, &fl) != 0)
return -1;
/* Drop old route. */
@ -46,7 +47,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
/* non-local src, find valid iif to satisfy
* rp-filter when calling ip_route_input. */
fl.nl_u.ip4_u.daddr = iph->saddr;
if (ip_route_output_key(&init_net, &rt, &fl) != 0)
if (ip_route_output_key(net, &rt, &fl) != 0)
return -1;
odst = skb->dst;

View File

@ -5,10 +5,15 @@
menu "IP: Netfilter Configuration"
depends on INET && NETFILTER
config NF_DEFRAG_IPV4
tristate
default n
config NF_CONNTRACK_IPV4
tristate "IPv4 connection tracking support (required for NAT)"
depends on NF_CONNTRACK
default m if NETFILTER_ADVANCED=n
select NF_DEFRAG_IPV4
---help---
Connection tracking keeps a record of what packets have passed
through your machine, in order to figure out how they are related
@ -56,53 +61,11 @@ config IP_NF_IPTABLES
To compile it as a module, choose M here. If unsure, say N.
if IP_NF_IPTABLES
# The matches.
config IP_NF_MATCH_RECENT
tristate '"recent" match support'
depends on IP_NF_IPTABLES
depends on NETFILTER_ADVANCED
help
This match is used for creating one or many lists of recently
used addresses and then matching against that/those list(s).
Short options are available by using 'iptables -m recent -h'
Official Website: <http://snowman.net/projects/ipt_recent/>
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_MATCH_ECN
tristate '"ecn" match support'
depends on IP_NF_IPTABLES
depends on NETFILTER_ADVANCED
help
This option adds a `ECN' match, which allows you to match against
the IPv4 and TCP header ECN fields.
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_MATCH_AH
tristate '"ah" match support'
depends on IP_NF_IPTABLES
depends on NETFILTER_ADVANCED
help
This match extension allows you to match a range of SPIs
inside AH header of IPSec packets.
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_MATCH_TTL
tristate '"ttl" match support'
depends on IP_NF_IPTABLES
depends on NETFILTER_ADVANCED
help
This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user
to match packets by their TTL value.
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_MATCH_ADDRTYPE
tristate '"addrtype" address type match support'
depends on IP_NF_IPTABLES
depends on NETFILTER_ADVANCED
help
This option allows you to match what routing thinks of an address,
@ -111,10 +74,36 @@ config IP_NF_MATCH_ADDRTYPE
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
config IP_NF_MATCH_AH
tristate '"ah" match support'
depends on NETFILTER_ADVANCED
help
This match extension allows you to match a range of SPIs
inside AH header of IPSec packets.
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_MATCH_ECN
tristate '"ecn" match support'
depends on NETFILTER_ADVANCED
help
This option adds a `ECN' match, which allows you to match against
the IPv4 and TCP header ECN fields.
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_MATCH_TTL
tristate '"ttl" match support'
depends on NETFILTER_ADVANCED
help
This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user
to match packets by their TTL value.
To compile it as a module, choose M here. If unsure, say N.
# `filter', generic and specific targets
config IP_NF_FILTER
tristate "Packet filtering"
depends on IP_NF_IPTABLES
default m if NETFILTER_ADVANCED=n
help
Packet filtering defines a table `filter', which has a series of
@ -136,7 +125,6 @@ config IP_NF_TARGET_REJECT
config IP_NF_TARGET_LOG
tristate "LOG target support"
depends on IP_NF_IPTABLES
default m if NETFILTER_ADVANCED=n
help
This option adds a `LOG' target, which allows you to create rules in
@ -146,7 +134,6 @@ config IP_NF_TARGET_LOG
config IP_NF_TARGET_ULOG
tristate "ULOG target support"
depends on IP_NF_IPTABLES
default m if NETFILTER_ADVANCED=n
---help---
@ -167,7 +154,7 @@ config IP_NF_TARGET_ULOG
# NAT + specific targets: nf_conntrack
config NF_NAT
tristate "Full NAT"
depends on IP_NF_IPTABLES && NF_CONNTRACK_IPV4
depends on NF_CONNTRACK_IPV4
default m if NETFILTER_ADVANCED=n
help
The Full NAT option allows masquerading, port forwarding and other
@ -194,6 +181,17 @@ config IP_NF_TARGET_MASQUERADE
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TARGET_NETMAP
tristate "NETMAP target support"
depends on NF_NAT
depends on NETFILTER_ADVANCED
help
NETMAP is an implementation of static 1:1 NAT mapping of network
addresses. It maps the network address part, while keeping the host
address part intact.
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TARGET_REDIRECT
tristate "REDIRECT target support"
depends on NF_NAT
@ -206,17 +204,6 @@ config IP_NF_TARGET_REDIRECT
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TARGET_NETMAP
tristate "NETMAP target support"
depends on NF_NAT
depends on NETFILTER_ADVANCED
help
NETMAP is an implementation of static 1:1 NAT mapping of network
addresses. It maps the network address part, while keeping the host
address part intact.
To compile it as a module, choose M here. If unsure, say N.
config NF_NAT_SNMP_BASIC
tristate "Basic SNMP-ALG support"
depends on NF_NAT
@ -262,44 +249,43 @@ config NF_NAT_PROTO_SCTP
config NF_NAT_FTP
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_FTP
config NF_NAT_IRC
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_IRC
config NF_NAT_TFTP
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_TFTP
config NF_NAT_AMANDA
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_AMANDA
config NF_NAT_PPTP
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_PPTP
select NF_NAT_PROTO_GRE
config NF_NAT_H323
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_H323
config NF_NAT_SIP
tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_SIP
# mangle + specific targets
config IP_NF_MANGLE
tristate "Packet mangling"
depends on IP_NF_IPTABLES
default m if NETFILTER_ADVANCED=n
help
This option adds a `mangle' table to iptables: see the man page for
@ -308,6 +294,19 @@ config IP_NF_MANGLE
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TARGET_CLUSTERIP
tristate "CLUSTERIP target support (EXPERIMENTAL)"
depends on IP_NF_MANGLE && EXPERIMENTAL
depends on NF_CONNTRACK_IPV4
depends on NETFILTER_ADVANCED
select NF_CONNTRACK_MARK
help
The CLUSTERIP target allows you to build load-balancing clusters of
network servers without having a dedicated load-balancing
router/server/switch.
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TARGET_ECN
tristate "ECN target support"
depends on IP_NF_MANGLE
@ -338,23 +337,9 @@ config IP_NF_TARGET_TTL
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TARGET_CLUSTERIP
tristate "CLUSTERIP target support (EXPERIMENTAL)"
depends on IP_NF_MANGLE && EXPERIMENTAL
depends on NF_CONNTRACK_IPV4
depends on NETFILTER_ADVANCED
select NF_CONNTRACK_MARK
help
The CLUSTERIP target allows you to build load-balancing clusters of
network servers without having a dedicated load-balancing
router/server/switch.
To compile it as a module, choose M here. If unsure, say N.
# raw + specific targets
config IP_NF_RAW
tristate 'raw table support (required for NOTRACK/TRACE)'
depends on IP_NF_IPTABLES
depends on NETFILTER_ADVANCED
help
This option adds a `raw' table to iptables. This table is the very
@ -367,7 +352,6 @@ config IP_NF_RAW
# security table for MAC policy
config IP_NF_SECURITY
tristate "Security table"
depends on IP_NF_IPTABLES
depends on SECURITY
depends on NETFILTER_ADVANCED
help
@ -376,6 +360,8 @@ config IP_NF_SECURITY
If unsure, say N.
endif # IP_NF_IPTABLES
# ARP tables
config IP_NF_ARPTABLES
tristate "ARP tables support"
@ -388,9 +374,10 @@ config IP_NF_ARPTABLES
To compile it as a module, choose M here. If unsure, say N.
if IP_NF_ARPTABLES
config IP_NF_ARPFILTER
tristate "ARP packet filtering"
depends on IP_NF_ARPTABLES
help
ARP packet filtering defines a table `filter', which has a series of
rules for simple ARP packet filtering at local input and
@ -401,10 +388,11 @@ config IP_NF_ARPFILTER
config IP_NF_ARP_MANGLE
tristate "ARP payload mangling"
depends on IP_NF_ARPTABLES
help
Allows altering the ARP packet payload: source and destination
hardware and network addresses.
endif # IP_NF_ARPTABLES
endmenu

View File

@ -18,6 +18,9 @@ obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
obj-$(CONFIG_NF_NAT) += nf_nat.o
# defrag
obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
# NAT helpers (nf_conntrack)
obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
@ -48,7 +51,6 @@ obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o
obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
# targets

View File

@ -200,15 +200,12 @@ static inline int arp_checkentry(const struct arpt_arp *arp)
return 1;
}
static unsigned int arpt_error(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
static unsigned int
arpt_error(struct sk_buff *skb, const struct xt_target_param *par)
{
if (net_ratelimit())
printk("arp_tables: error: '%s'\n", (char *)targinfo);
printk("arp_tables: error: '%s'\n",
(const char *)par->targinfo);
return NF_DROP;
}
@ -232,6 +229,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
const char *indev, *outdev;
void *table_base;
const struct xt_table_info *private;
struct xt_target_param tgpar;
if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
return NF_DROP;
@ -245,6 +243,11 @@ unsigned int arpt_do_table(struct sk_buff *skb,
e = get_entry(table_base, private->hook_entry[hook]);
back = get_entry(table_base, private->underflow[hook]);
tgpar.in = in;
tgpar.out = out;
tgpar.hooknum = hook;
tgpar.family = NFPROTO_ARP;
arp = arp_hdr(skb);
do {
if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) {
@ -290,11 +293,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
/* Targets which reenter must return
* abs. verdicts
*/
tgpar.target = t->u.kernel.target;
tgpar.targinfo = t->data;
verdict = t->u.kernel.target->target(skb,
in, out,
hook,
t->u.kernel.target,
t->data);
&tgpar);
/* Target might have changed stuff. */
arp = arp_hdr(skb);
@ -456,23 +458,24 @@ static inline int check_entry(struct arpt_entry *e, const char *name)
static inline int check_target(struct arpt_entry *e, const char *name)
{
struct arpt_entry_target *t;
struct xt_target *target;
struct arpt_entry_target *t = arpt_get_target(e);
int ret;
struct xt_tgchk_param par = {
.table = name,
.entryinfo = e,
.target = t->u.kernel.target,
.targinfo = t->data,
.hook_mask = e->comefrom,
.family = NFPROTO_ARP,
};
t = arpt_get_target(e);
target = t->u.kernel.target;
ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t),
name, e->comefrom, 0, 0);
if (!ret && t->u.kernel.target->checkentry
&& !t->u.kernel.target->checkentry(name, e, target, t->data,
e->comefrom)) {
ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
if (ret < 0) {
duprintf("arp_tables: check failed for `%s'.\n",
t->u.kernel.target->name);
ret = -EINVAL;
return ret;
}
return ret;
return 0;
}
static inline int
@ -488,7 +491,8 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
return ret;
t = arpt_get_target(e);
target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name,
target = try_then_request_module(xt_find_target(NFPROTO_ARP,
t->u.user.name,
t->u.user.revision),
"arpt_%s", t->u.user.name);
if (IS_ERR(target) || !target) {
@ -554,15 +558,19 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i)
{
struct xt_tgdtor_param par;
struct arpt_entry_target *t;
if (i && (*i)-- == 0)
return 1;
t = arpt_get_target(e);
if (t->u.kernel.target->destroy)
t->u.kernel.target->destroy(t->u.kernel.target, t->data);
module_put(t->u.kernel.target->me);
par.target = t->u.kernel.target;
par.targinfo = t->data;
par.family = NFPROTO_ARP;
if (par.target->destroy != NULL)
par.target->destroy(&par);
module_put(par.target->me);
return 0;
}
@ -788,7 +796,7 @@ static void compat_standard_from_user(void *dst, void *src)
int v = *(compat_int_t *)src;
if (v > 0)
v += xt_compat_calc_jump(NF_ARP, v);
v += xt_compat_calc_jump(NFPROTO_ARP, v);
memcpy(dst, &v, sizeof(v));
}
@ -797,7 +805,7 @@ static int compat_standard_to_user(void __user *dst, void *src)
compat_int_t cv = *(int *)src;
if (cv > 0)
cv -= xt_compat_calc_jump(NF_ARP, cv);
cv -= xt_compat_calc_jump(NFPROTO_ARP, cv);
return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
}
@ -815,7 +823,7 @@ static int compat_calc_entry(struct arpt_entry *e,
t = arpt_get_target(e);
off += xt_compat_target_offset(t->u.kernel.target);
newinfo->size -= off;
ret = xt_compat_add_offset(NF_ARP, entry_offset, off);
ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off);
if (ret)
return ret;
@ -866,9 +874,9 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
#ifdef CONFIG_COMPAT
if (compat)
xt_compat_lock(NF_ARP);
xt_compat_lock(NFPROTO_ARP);
#endif
t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name),
t = try_then_request_module(xt_find_table_lock(net, NFPROTO_ARP, name),
"arptable_%s", name);
if (t && !IS_ERR(t)) {
struct arpt_getinfo info;
@ -878,7 +886,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
if (compat) {
struct xt_table_info tmp;
ret = compat_table_info(private, &tmp);
xt_compat_flush_offsets(NF_ARP);
xt_compat_flush_offsets(NFPROTO_ARP);
private = &tmp;
}
#endif
@ -901,7 +909,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
ret = t ? PTR_ERR(t) : -ENOENT;
#ifdef CONFIG_COMPAT
if (compat)
xt_compat_unlock(NF_ARP);
xt_compat_unlock(NFPROTO_ARP);
#endif
return ret;
}
@ -925,7 +933,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
return -EINVAL;
}
t = xt_find_table_lock(net, NF_ARP, get.name);
t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
if (t && !IS_ERR(t)) {
const struct xt_table_info *private = t->private;
@ -967,7 +975,7 @@ static int __do_replace(struct net *net, const char *name,
goto out;
}
t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name),
t = try_then_request_module(xt_find_table_lock(net, NFPROTO_ARP, name),
"arptable_%s", name);
if (!t || IS_ERR(t)) {
ret = t ? PTR_ERR(t) : -ENOENT;
@ -1134,7 +1142,7 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len,
goto free;
}
t = xt_find_table_lock(net, NF_ARP, name);
t = xt_find_table_lock(net, NFPROTO_ARP, name);
if (!t || IS_ERR(t)) {
ret = t ? PTR_ERR(t) : -ENOENT;
goto free;
@ -1218,7 +1226,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
entry_offset = (void *)e - (void *)base;
t = compat_arpt_get_target(e);
target = try_then_request_module(xt_find_target(NF_ARP,
target = try_then_request_module(xt_find_target(NFPROTO_ARP,
t->u.user.name,
t->u.user.revision),
"arpt_%s", t->u.user.name);
@ -1232,7 +1240,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
off += xt_compat_target_offset(target);
*size += off;
ret = xt_compat_add_offset(NF_ARP, entry_offset, off);
ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off);
if (ret)
goto release_target;
@ -1333,7 +1341,7 @@ static int translate_compat_table(const char *name,
duprintf("translate_compat_table: size %u\n", info->size);
j = 0;
xt_compat_lock(NF_ARP);
xt_compat_lock(NFPROTO_ARP);
/* Walk through entries, checking offsets. */
ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size,
check_compat_entry_size_and_hooks,
@ -1383,8 +1391,8 @@ static int translate_compat_table(const char *name,
ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size,
compat_copy_entry_from_user,
&pos, &size, name, newinfo, entry1);
xt_compat_flush_offsets(NF_ARP);
xt_compat_unlock(NF_ARP);
xt_compat_flush_offsets(NFPROTO_ARP);
xt_compat_unlock(NFPROTO_ARP);
if (ret)
goto free_newinfo;
@ -1420,8 +1428,8 @@ out:
COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
return ret;
out_unlock:
xt_compat_flush_offsets(NF_ARP);
xt_compat_unlock(NF_ARP);
xt_compat_flush_offsets(NFPROTO_ARP);
xt_compat_unlock(NFPROTO_ARP);
goto out;
}
@ -1607,8 +1615,8 @@ static int compat_get_entries(struct net *net,
return -EINVAL;
}
xt_compat_lock(NF_ARP);
t = xt_find_table_lock(net, NF_ARP, get.name);
xt_compat_lock(NFPROTO_ARP);
t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
if (t && !IS_ERR(t)) {
const struct xt_table_info *private = t->private;
struct xt_table_info info;
@ -1623,13 +1631,13 @@ static int compat_get_entries(struct net *net,
private->size, get.size);
ret = -EAGAIN;
}
xt_compat_flush_offsets(NF_ARP);
xt_compat_flush_offsets(NFPROTO_ARP);
module_put(t->me);
xt_table_unlock(t);
} else
ret = t ? PTR_ERR(t) : -ENOENT;
xt_compat_unlock(NF_ARP);
xt_compat_unlock(NFPROTO_ARP);
return ret;
}
@ -1709,7 +1717,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
break;
}
try_then_request_module(xt_find_revision(NF_ARP, rev.name,
try_then_request_module(xt_find_revision(NFPROTO_ARP, rev.name,
rev.revision, 1, &ret),
"arpt_%s", rev.name);
break;
@ -1787,7 +1795,7 @@ void arpt_unregister_table(struct xt_table *table)
static struct xt_target arpt_standard_target __read_mostly = {
.name = ARPT_STANDARD_TARGET,
.targetsize = sizeof(int),
.family = NF_ARP,
.family = NFPROTO_ARP,
#ifdef CONFIG_COMPAT
.compatsize = sizeof(compat_int_t),
.compat_from_user = compat_standard_from_user,
@ -1799,7 +1807,7 @@ static struct xt_target arpt_error_target __read_mostly = {
.name = ARPT_ERROR_TARGET,
.target = arpt_error,
.targetsize = ARPT_FUNCTION_MAXNAMELEN,
.family = NF_ARP,
.family = NFPROTO_ARP,
};
static struct nf_sockopt_ops arpt_sockopts = {
@ -1821,12 +1829,12 @@ static struct nf_sockopt_ops arpt_sockopts = {
static int __net_init arp_tables_net_init(struct net *net)
{
return xt_proto_init(net, NF_ARP);
return xt_proto_init(net, NFPROTO_ARP);
}
static void __net_exit arp_tables_net_exit(struct net *net)
{
xt_proto_fini(net, NF_ARP);
xt_proto_fini(net, NFPROTO_ARP);
}
static struct pernet_operations arp_tables_net_ops = {

View File

@ -9,12 +9,9 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
MODULE_DESCRIPTION("arptables arp payload mangle target");
static unsigned int
target(struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *target,
const void *targinfo)
target(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct arpt_mangle *mangle = targinfo;
const struct arpt_mangle *mangle = par->targinfo;
const struct arphdr *arp;
unsigned char *arpptr;
int pln, hln;
@ -57,11 +54,9 @@ target(struct sk_buff *skb,
return mangle->target;
}
static bool
checkentry(const char *tablename, const void *e, const struct xt_target *target,
void *targinfo, unsigned int hook_mask)
static bool checkentry(const struct xt_tgchk_param *par)
{
const struct arpt_mangle *mangle = targinfo;
const struct arpt_mangle *mangle = par->targinfo;
if (mangle->flags & ~ARPT_MANGLE_MASK ||
!(mangle->flags & ARPT_MANGLE_MASK))
@ -75,7 +70,7 @@ checkentry(const char *tablename, const void *e, const struct xt_target *target,
static struct xt_target arpt_mangle_reg __read_mostly = {
.name = "mangle",
.family = NF_ARP,
.family = NFPROTO_ARP,
.target = target,
.targetsize = sizeof(struct arpt_mangle),
.checkentry = checkentry,

View File

@ -51,7 +51,7 @@ static struct xt_table packet_filter = {
.lock = __RW_LOCK_UNLOCKED(packet_filter.lock),
.private = NULL,
.me = THIS_MODULE,
.af = NF_ARP,
.af = NFPROTO_ARP,
};
/* The work comes in here from netfilter.c */
@ -89,21 +89,21 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = {
{
.hook = arpt_in_hook,
.owner = THIS_MODULE,
.pf = NF_ARP,
.pf = NFPROTO_ARP,
.hooknum = NF_ARP_IN,
.priority = NF_IP_PRI_FILTER,
},
{
.hook = arpt_out_hook,
.owner = THIS_MODULE,
.pf = NF_ARP,
.pf = NFPROTO_ARP,
.hooknum = NF_ARP_OUT,
.priority = NF_IP_PRI_FILTER,
},
{
.hook = arpt_forward_hook,
.owner = THIS_MODULE,
.pf = NF_ARP,
.pf = NFPROTO_ARP,
.hooknum = NF_ARP_FORWARD,
.priority = NF_IP_PRI_FILTER,
},

View File

@ -171,31 +171,25 @@ ip_checkentry(const struct ipt_ip *ip)
}
static unsigned int
ipt_error(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
ipt_error(struct sk_buff *skb, const struct xt_target_param *par)
{
if (net_ratelimit())
printk("ip_tables: error: `%s'\n", (char *)targinfo);
printk("ip_tables: error: `%s'\n",
(const char *)par->targinfo);
return NF_DROP;
}
/* Performance critical - called for every packet */
static inline bool
do_match(struct ipt_entry_match *m,
const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int offset,
bool *hotdrop)
do_match(struct ipt_entry_match *m, const struct sk_buff *skb,
struct xt_match_param *par)
{
par->match = m->u.kernel.match;
par->matchinfo = m->data;
/* Stop iteration if it doesn't match */
if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data,
offset, ip_hdrlen(skb), hotdrop))
if (!m->u.kernel.match->match(skb, par))
return true;
else
return false;
@ -326,7 +320,6 @@ ipt_do_table(struct sk_buff *skb,
struct xt_table *table)
{
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
u_int16_t offset;
const struct iphdr *ip;
u_int16_t datalen;
bool hotdrop = false;
@ -336,6 +329,8 @@ ipt_do_table(struct sk_buff *skb,
void *table_base;
struct ipt_entry *e, *back;
struct xt_table_info *private;
struct xt_match_param mtpar;
struct xt_target_param tgpar;
/* Initialization */
ip = ip_hdr(skb);
@ -348,7 +343,13 @@ ipt_do_table(struct sk_buff *skb,
* things we don't know, ie. tcp syn flag or ports). If the
* rule is also a fragment-specific rule, non-fragments won't
* match it. */
offset = ntohs(ip->frag_off) & IP_OFFSET;
mtpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
mtpar.thoff = ip_hdrlen(skb);
mtpar.hotdrop = &hotdrop;
mtpar.in = tgpar.in = in;
mtpar.out = tgpar.out = out;
mtpar.family = tgpar.family = NFPROTO_IPV4;
tgpar.hooknum = hook;
read_lock_bh(&table->lock);
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
@ -362,12 +363,11 @@ ipt_do_table(struct sk_buff *skb,
do {
IP_NF_ASSERT(e);
IP_NF_ASSERT(back);
if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) {
if (ip_packet_match(ip, indev, outdev,
&e->ip, mtpar.fragoff)) {
struct ipt_entry_target *t;
if (IPT_MATCH_ITERATE(e, do_match,
skb, in, out,
offset, &hotdrop) != 0)
if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0)
goto no_match;
ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
@ -413,16 +413,14 @@ ipt_do_table(struct sk_buff *skb,
} else {
/* Targets which reenter must return
abs. verdicts */
tgpar.target = t->u.kernel.target;
tgpar.targinfo = t->data;
#ifdef CONFIG_NETFILTER_DEBUG
((struct ipt_entry *)table_base)->comefrom
= 0xeeeeeeec;
#endif
verdict = t->u.kernel.target->target(skb,
in, out,
hook,
t->u.kernel.target,
t->data);
&tgpar);
#ifdef CONFIG_NETFILTER_DEBUG
if (((struct ipt_entry *)table_base)->comefrom
!= 0xeeeeeeec
@ -575,12 +573,17 @@ mark_source_chains(struct xt_table_info *newinfo,
static int
cleanup_match(struct ipt_entry_match *m, unsigned int *i)
{
struct xt_mtdtor_param par;
if (i && (*i)-- == 0)
return 1;
if (m->u.kernel.match->destroy)
m->u.kernel.match->destroy(m->u.kernel.match, m->data);
module_put(m->u.kernel.match->me);
par.match = m->u.kernel.match;
par.matchinfo = m->data;
par.family = NFPROTO_IPV4;
if (par.match->destroy != NULL)
par.match->destroy(&par);
module_put(par.match->me);
return 0;
}
@ -606,34 +609,28 @@ check_entry(struct ipt_entry *e, const char *name)
}
static int
check_match(struct ipt_entry_match *m, const char *name,
const struct ipt_ip *ip,
unsigned int hookmask, unsigned int *i)
check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
unsigned int *i)
{
struct xt_match *match;
const struct ipt_ip *ip = par->entryinfo;
int ret;
match = m->u.kernel.match;
ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m),
name, hookmask, ip->proto,
ip->invflags & IPT_INV_PROTO);
if (!ret && m->u.kernel.match->checkentry
&& !m->u.kernel.match->checkentry(name, ip, match, m->data,
hookmask)) {
par->match = m->u.kernel.match;
par->matchinfo = m->data;
ret = xt_check_match(par, m->u.match_size - sizeof(*m),
ip->proto, ip->invflags & IPT_INV_PROTO);
if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n",
m->u.kernel.match->name);
ret = -EINVAL;
par.match->name);
return ret;
}
if (!ret)
(*i)++;
return ret;
++*i;
return 0;
}
static int
find_check_match(struct ipt_entry_match *m,
const char *name,
const struct ipt_ip *ip,
unsigned int hookmask,
find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
unsigned int *i)
{
struct xt_match *match;
@ -648,7 +645,7 @@ find_check_match(struct ipt_entry_match *m,
}
m->u.kernel.match = match;
ret = check_match(m, name, ip, hookmask, i);
ret = check_match(m, par, i);
if (ret)
goto err;
@ -660,23 +657,25 @@ err:
static int check_target(struct ipt_entry *e, const char *name)
{
struct ipt_entry_target *t;
struct xt_target *target;
struct ipt_entry_target *t = ipt_get_target(e);
struct xt_tgchk_param par = {
.table = name,
.entryinfo = e,
.target = t->u.kernel.target,
.targinfo = t->data,
.hook_mask = e->comefrom,
.family = NFPROTO_IPV4,
};
int ret;
t = ipt_get_target(e);
target = t->u.kernel.target;
ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
name, e->comefrom, e->ip.proto,
e->ip.invflags & IPT_INV_PROTO);
if (!ret && t->u.kernel.target->checkentry
&& !t->u.kernel.target->checkentry(name, e, target, t->data,
e->comefrom)) {
ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n",
t->u.kernel.target->name);
ret = -EINVAL;
return ret;
}
return ret;
return 0;
}
static int
@ -687,14 +686,18 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
struct xt_target *target;
int ret;
unsigned int j;
struct xt_mtchk_param mtpar;
ret = check_entry(e, name);
if (ret)
return ret;
j = 0;
ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip,
e->comefrom, &j);
mtpar.table = name;
mtpar.entryinfo = &e->ip;
mtpar.hook_mask = e->comefrom;
mtpar.family = NFPROTO_IPV4;
ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
if (ret != 0)
goto cleanup_matches;
@ -769,6 +772,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
static int
cleanup_entry(struct ipt_entry *e, unsigned int *i)
{
struct xt_tgdtor_param par;
struct ipt_entry_target *t;
if (i && (*i)-- == 0)
@ -777,9 +781,13 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i)
/* Cleanup all matches */
IPT_MATCH_ITERATE(e, cleanup_match, NULL);
t = ipt_get_target(e);
if (t->u.kernel.target->destroy)
t->u.kernel.target->destroy(t->u.kernel.target, t->data);
module_put(t->u.kernel.target->me);
par.target = t->u.kernel.target;
par.targinfo = t->data;
par.family = NFPROTO_IPV4;
if (par.target->destroy != NULL)
par.target->destroy(&par);
module_put(par.target->me);
return 0;
}
@ -1648,12 +1656,16 @@ static int
compat_check_entry(struct ipt_entry *e, const char *name,
unsigned int *i)
{
struct xt_mtchk_param mtpar;
unsigned int j;
int ret;
j = 0;
ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip,
e->comefrom, &j);
mtpar.table = name;
mtpar.entryinfo = &e->ip;
mtpar.hook_mask = e->comefrom;
mtpar.family = NFPROTO_IPV4;
ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j);
if (ret)
goto cleanup_matches;
@ -2121,30 +2133,23 @@ icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
}
static bool
icmp_match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const struct xt_match *match,
const void *matchinfo,
int offset,
unsigned int protoff,
bool *hotdrop)
icmp_match(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct icmphdr *ic;
struct icmphdr _icmph;
const struct ipt_icmp *icmpinfo = matchinfo;
const struct ipt_icmp *icmpinfo = par->matchinfo;
/* Must not be a fragment. */
if (offset)
if (par->fragoff != 0)
return false;
ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph);
ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
if (ic == NULL) {
/* We've been asked to examine this packet, and we
* can't. Hence, no choice but to drop.
*/
duprintf("Dropping evil ICMP tinygram.\n");
*hotdrop = true;
*par->hotdrop = true;
return false;
}
@ -2155,15 +2160,9 @@ icmp_match(const struct sk_buff *skb,
!!(icmpinfo->invflags&IPT_ICMP_INV));
}
/* Called when user tries to insert an entry of this type. */
static bool
icmp_checkentry(const char *tablename,
const void *entry,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask)
static bool icmp_checkentry(const struct xt_mtchk_param *par)
{
const struct ipt_icmp *icmpinfo = matchinfo;
const struct ipt_icmp *icmpinfo = par->matchinfo;
/* Must specify no unknown invflags */
return !(icmpinfo->invflags & ~IPT_ICMP_INV);

View File

@ -281,11 +281,9 @@ clusterip_responsible(const struct clusterip_config *config, u_int32_t hash)
***********************************************************************/
static unsigned int
clusterip_tg(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct ipt_clusterip_tgt_info *cipinfo = targinfo;
const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
u_int32_t hash;
@ -349,13 +347,10 @@ clusterip_tg(struct sk_buff *skb, const struct net_device *in,
return XT_CONTINUE;
}
static bool
clusterip_tg_check(const char *tablename, const void *e_void,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
static bool clusterip_tg_check(const struct xt_tgchk_param *par)
{
struct ipt_clusterip_tgt_info *cipinfo = targinfo;
const struct ipt_entry *e = e_void;
struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
const struct ipt_entry *e = par->entryinfo;
struct clusterip_config *config;
@ -406,9 +401,9 @@ clusterip_tg_check(const char *tablename, const void *e_void,
}
cipinfo->config = config;
if (nf_ct_l3proto_try_module_get(target->family) < 0) {
if (nf_ct_l3proto_try_module_get(par->target->family) < 0) {
printk(KERN_WARNING "can't load conntrack support for "
"proto=%u\n", target->family);
"proto=%u\n", par->target->family);
return false;
}
@ -416,9 +411,9 @@ clusterip_tg_check(const char *tablename, const void *e_void,
}
/* drop reference count of cluster config when rule is deleted */
static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo)
static void clusterip_tg_destroy(const struct xt_tgdtor_param *par)
{
const struct ipt_clusterip_tgt_info *cipinfo = targinfo;
const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
/* if no more entries are referencing the config, remove it
* from the list and destroy the proc entry */
@ -426,7 +421,7 @@ static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo)
clusterip_config_put(cipinfo->config);
nf_ct_l3proto_module_put(target->family);
nf_ct_l3proto_module_put(par->target->family);
}
#ifdef CONFIG_COMPAT
@ -445,7 +440,7 @@ struct compat_ipt_clusterip_tgt_info
static struct xt_target clusterip_tg_reg __read_mostly = {
.name = "CLUSTERIP",
.family = AF_INET,
.family = NFPROTO_IPV4,
.target = clusterip_tg,
.checkentry = clusterip_tg_check,
.destroy = clusterip_tg_destroy,
@ -546,7 +541,7 @@ arp_mangle(unsigned int hook,
static struct nf_hook_ops cip_arp_ops __read_mostly = {
.hook = arp_mangle,
.pf = NF_ARP,
.pf = NFPROTO_ARP,
.hooknum = NF_ARP_OUT,
.priority = -1
};

View File

@ -77,11 +77,9 @@ set_ect_tcp(struct sk_buff *skb, const struct ipt_ECN_info *einfo)
}
static unsigned int
ecn_tg(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
ecn_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct ipt_ECN_info *einfo = targinfo;
const struct ipt_ECN_info *einfo = par->targinfo;
if (einfo->operation & IPT_ECN_OP_SET_IP)
if (!set_ect_ip(skb, einfo))
@ -95,13 +93,10 @@ ecn_tg(struct sk_buff *skb, const struct net_device *in,
return XT_CONTINUE;
}
static bool
ecn_tg_check(const char *tablename, const void *e_void,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
static bool ecn_tg_check(const struct xt_tgchk_param *par)
{
const struct ipt_ECN_info *einfo = targinfo;
const struct ipt_entry *e = e_void;
const struct ipt_ECN_info *einfo = par->targinfo;
const struct ipt_entry *e = par->entryinfo;
if (einfo->operation & IPT_ECN_OP_MASK) {
printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
@ -124,7 +119,7 @@ ecn_tg_check(const char *tablename, const void *e_void,
static struct xt_target ecn_tg_reg __read_mostly = {
.name = "ECN",
.family = AF_INET,
.family = NFPROTO_IPV4,
.target = ecn_tg,
.targetsize = sizeof(struct ipt_ECN_info),
.table = "mangle",

View File

@ -375,7 +375,7 @@ static struct nf_loginfo default_loginfo = {
};
static void
ipt_log_packet(unsigned int pf,
ipt_log_packet(u_int8_t pf,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,
@ -426,28 +426,23 @@ ipt_log_packet(unsigned int pf,
}
static unsigned int
log_tg(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
log_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct ipt_log_info *loginfo = targinfo;
const struct ipt_log_info *loginfo = par->targinfo;
struct nf_loginfo li;
li.type = NF_LOG_TYPE_LOG;
li.u.log.level = loginfo->level;
li.u.log.logflags = loginfo->logflags;
ipt_log_packet(PF_INET, hooknum, skb, in, out, &li,
ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, par->out, &li,
loginfo->prefix);
return XT_CONTINUE;
}
static bool
log_tg_check(const char *tablename, const void *e,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
static bool log_tg_check(const struct xt_tgchk_param *par)
{
const struct ipt_log_info *loginfo = targinfo;
const struct ipt_log_info *loginfo = par->targinfo;
if (loginfo->level >= 8) {
pr_debug("LOG: level %u >= 8\n", loginfo->level);
@ -463,7 +458,7 @@ log_tg_check(const char *tablename, const void *e,
static struct xt_target log_tg_reg __read_mostly = {
.name = "LOG",
.family = AF_INET,
.family = NFPROTO_IPV4,
.target = log_tg,
.targetsize = sizeof(struct ipt_log_info),
.checkentry = log_tg_check,
@ -483,7 +478,7 @@ static int __init log_tg_init(void)
ret = xt_register_target(&log_tg_reg);
if (ret < 0)
return ret;
nf_log_register(PF_INET, &ipt_log_logger);
nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
return 0;
}

View File

@ -31,12 +31,9 @@ MODULE_DESCRIPTION("Xtables: automatic-address SNAT");
static DEFINE_RWLOCK(masq_lock);
/* FIXME: Multiple targets. --RR */
static bool
masquerade_tg_check(const char *tablename, const void *e,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
static bool masquerade_tg_check(const struct xt_tgchk_param *par)
{
const struct nf_nat_multi_range_compat *mr = targinfo;
const struct nf_nat_multi_range_compat *mr = par->targinfo;
if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
pr_debug("masquerade_check: bad MAP_IPS.\n");
@ -50,9 +47,7 @@ masquerade_tg_check(const char *tablename, const void *e,
}
static unsigned int
masquerade_tg(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
struct nf_conn *ct;
struct nf_conn_nat *nat;
@ -62,7 +57,7 @@ masquerade_tg(struct sk_buff *skb, const struct net_device *in,
const struct rtable *rt;
__be32 newsrc;
NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING);
NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING);
ct = nf_ct_get(skb, &ctinfo);
nat = nfct_nat(ct);
@ -76,16 +71,16 @@ masquerade_tg(struct sk_buff *skb, const struct net_device *in,
if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0)
return NF_ACCEPT;
mr = targinfo;
mr = par->targinfo;
rt = skb->rtable;
newsrc = inet_select_addr(out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
if (!newsrc) {
printk("MASQUERADE: %s ate my IP address\n", out->name);
printk("MASQUERADE: %s ate my IP address\n", par->out->name);
return NF_DROP;
}
write_lock_bh(&masq_lock);
nat->masq_index = out->ifindex;
nat->masq_index = par->out->ifindex;
write_unlock_bh(&masq_lock);
/* Transfer from original range. */
@ -119,9 +114,7 @@ static int masq_device_event(struct notifier_block *this,
void *ptr)
{
const struct net_device *dev = ptr;
if (!net_eq(dev_net(dev), &init_net))
return NOTIFY_DONE;
struct net *net = dev_net(dev);
if (event == NETDEV_DOWN) {
/* Device was downed. Search entire table for
@ -129,7 +122,8 @@ static int masq_device_event(struct notifier_block *this,
and forget them. */
NF_CT_ASSERT(dev->ifindex != 0);
nf_ct_iterate_cleanup(device_cmp, (void *)(long)dev->ifindex);
nf_ct_iterate_cleanup(net, device_cmp,
(void *)(long)dev->ifindex);
}
return NOTIFY_DONE;
@ -153,7 +147,7 @@ static struct notifier_block masq_inet_notifier = {
static struct xt_target masquerade_tg_reg __read_mostly = {
.name = "MASQUERADE",
.family = AF_INET,
.family = NFPROTO_IPV4,
.target = masquerade_tg,
.targetsize = sizeof(struct nf_nat_multi_range_compat),
.table = "nat",

View File

@ -22,12 +22,9 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets");
static bool
netmap_tg_check(const char *tablename, const void *e,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
static bool netmap_tg_check(const struct xt_tgchk_param *par)
{
const struct nf_nat_multi_range_compat *mr = targinfo;
const struct nf_nat_multi_range_compat *mr = par->targinfo;
if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
pr_debug("NETMAP:check: bad MAP_IPS.\n");
@ -41,24 +38,23 @@ netmap_tg_check(const char *tablename, const void *e,
}
static unsigned int
netmap_tg(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
netmap_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
__be32 new_ip, netmask;
const struct nf_nat_multi_range_compat *mr = targinfo;
const struct nf_nat_multi_range_compat *mr = par->targinfo;
struct nf_nat_range newrange;
NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING
|| hooknum == NF_INET_POST_ROUTING
|| hooknum == NF_INET_LOCAL_OUT);
NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
par->hooknum == NF_INET_POST_ROUTING ||
par->hooknum == NF_INET_LOCAL_OUT);
ct = nf_ct_get(skb, &ctinfo);
netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip);
if (hooknum == NF_INET_PRE_ROUTING || hooknum == NF_INET_LOCAL_OUT)
if (par->hooknum == NF_INET_PRE_ROUTING ||
par->hooknum == NF_INET_LOCAL_OUT)
new_ip = ip_hdr(skb)->daddr & ~netmask;
else
new_ip = ip_hdr(skb)->saddr & ~netmask;
@ -70,12 +66,12 @@ netmap_tg(struct sk_buff *skb, const struct net_device *in,
mr->range[0].min, mr->range[0].max });
/* Hand modified range to generic setup. */
return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(hooknum));
return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(par->hooknum));
}
static struct xt_target netmap_tg_reg __read_mostly = {
.name = "NETMAP",
.family = AF_INET,
.family = NFPROTO_IPV4,
.target = netmap_tg,
.targetsize = sizeof(struct nf_nat_multi_range_compat),
.table = "nat",

View File

@ -26,12 +26,9 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
/* FIXME: Take multiple ranges --RR */
static bool
redirect_tg_check(const char *tablename, const void *e,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
static bool redirect_tg_check(const struct xt_tgchk_param *par)
{
const struct nf_nat_multi_range_compat *mr = targinfo;
const struct nf_nat_multi_range_compat *mr = par->targinfo;
if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
pr_debug("redirect_check: bad MAP_IPS.\n");
@ -45,24 +42,22 @@ redirect_tg_check(const char *tablename, const void *e,
}
static unsigned int
redirect_tg(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
__be32 newdst;
const struct nf_nat_multi_range_compat *mr = targinfo;
const struct nf_nat_multi_range_compat *mr = par->targinfo;
struct nf_nat_range newrange;
NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING
|| hooknum == NF_INET_LOCAL_OUT);
NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
par->hooknum == NF_INET_LOCAL_OUT);
ct = nf_ct_get(skb, &ctinfo);
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
/* Local packets: make them go to loopback */
if (hooknum == NF_INET_LOCAL_OUT)
if (par->hooknum == NF_INET_LOCAL_OUT)
newdst = htonl(0x7F000001);
else {
struct in_device *indev;
@ -92,7 +87,7 @@ redirect_tg(struct sk_buff *skb, const struct net_device *in,
static struct xt_target redirect_tg_reg __read_mostly = {
.name = "REDIRECT",
.family = AF_INET,
.family = NFPROTO_IPV4,
.target = redirect_tg,
.targetsize = sizeof(struct nf_nat_multi_range_compat),
.table = "nat",

View File

@ -136,11 +136,9 @@ static inline void send_unreach(struct sk_buff *skb_in, int code)
}
static unsigned int
reject_tg(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
reject_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct ipt_reject_info *reject = 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
@ -168,7 +166,7 @@ reject_tg(struct sk_buff *skb, const struct net_device *in,
send_unreach(skb, ICMP_PKT_FILTERED);
break;
case IPT_TCP_RESET:
send_reset(skb, hooknum);
send_reset(skb, par->hooknum);
case IPT_ICMP_ECHOREPLY:
/* Doesn't happen. */
break;
@ -177,13 +175,10 @@ reject_tg(struct sk_buff *skb, const struct net_device *in,
return NF_DROP;
}
static bool
reject_tg_check(const char *tablename, const void *e_void,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
static bool reject_tg_check(const struct xt_tgchk_param *par)
{
const struct ipt_reject_info *rejinfo = targinfo;
const struct ipt_entry *e = e_void;
const struct ipt_reject_info *rejinfo = par->targinfo;
const struct ipt_entry *e = par->entryinfo;
if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
printk("ipt_REJECT: ECHOREPLY no longer supported.\n");
@ -201,7 +196,7 @@ reject_tg_check(const char *tablename, const void *e_void,
static struct xt_target reject_tg_reg __read_mostly = {
.name = "REJECT",
.family = AF_INET,
.family = NFPROTO_IPV4,
.target = reject_tg,
.targetsize = sizeof(struct ipt_reject_info),
.table = "filter",

View File

@ -20,12 +20,10 @@ MODULE_DESCRIPTION("Xtables: IPv4 TTL field modification target");
MODULE_LICENSE("GPL");
static unsigned int
ttl_tg(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
ttl_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
struct iphdr *iph;
const struct ipt_TTL_info *info = targinfo;
const struct ipt_TTL_info *info = par->targinfo;
int new_ttl;
if (!skb_make_writable(skb, skb->len))
@ -61,12 +59,9 @@ ttl_tg(struct sk_buff *skb, const struct net_device *in,
return XT_CONTINUE;
}
static bool
ttl_tg_check(const char *tablename, const void *e,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
static bool ttl_tg_check(const struct xt_tgchk_param *par)
{
const struct ipt_TTL_info *info = targinfo;
const struct ipt_TTL_info *info = par->targinfo;
if (info->mode > IPT_TTL_MAXMODE) {
printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n",
@ -80,7 +75,7 @@ ttl_tg_check(const char *tablename, const void *e,
static struct xt_target ttl_tg_reg __read_mostly = {
.name = "TTL",
.family = AF_INET,
.family = NFPROTO_IPV4,
.target = ttl_tg,
.targetsize = sizeof(struct ipt_TTL_info),
.table = "mangle",

View File

@ -281,18 +281,14 @@ alloc_failure:
}
static unsigned int
ulog_tg(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
ulog_tg(struct sk_buff *skb, const struct xt_target_param *par)
{
struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
ipt_ulog_packet(hooknum, skb, in, out, loginfo, NULL);
ipt_ulog_packet(par->hooknum, skb, par->in, par->out,
par->targinfo, NULL);
return XT_CONTINUE;
}
static void ipt_logfn(unsigned int pf,
static void ipt_logfn(u_int8_t pf,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,
@ -317,12 +313,9 @@ static void ipt_logfn(unsigned int pf,
ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
}
static bool
ulog_tg_check(const char *tablename, const void *e,
const struct xt_target *target, void *targinfo,
unsigned int hookmask)
static bool ulog_tg_check(const struct xt_tgchk_param *par)
{
const struct ipt_ulog_info *loginfo = targinfo;
const struct ipt_ulog_info *loginfo = par->targinfo;
if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
pr_debug("ipt_ULOG: prefix term %i\n",
@ -374,7 +367,7 @@ static int ulog_tg_compat_to_user(void __user *dst, void *src)
static struct xt_target ulog_tg_reg __read_mostly = {
.name = "ULOG",
.family = AF_INET,
.family = NFPROTO_IPV4,
.target = ulog_tg,
.targetsize = sizeof(struct ipt_ulog_info),
.checkentry = ulog_tg_check,
@ -419,7 +412,7 @@ static int __init ulog_tg_init(void)
return ret;
}
if (nflog)
nf_log_register(PF_INET, &ipt_ulog_logger);
nf_log_register(NFPROTO_IPV4, &ipt_ulog_logger);
return 0;
}

View File

@ -30,12 +30,9 @@ static inline bool match_type(const struct net_device *dev, __be32 addr,
}
static bool
addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff,
bool *hotdrop)
addrtype_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ipt_addrtype_info *info = matchinfo;
const struct ipt_addrtype_info *info = par->matchinfo;
const struct iphdr *iph = ip_hdr(skb);
bool ret = true;
@ -50,20 +47,17 @@ addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in,
}
static bool
addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff,
bool *hotdrop)
addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ipt_addrtype_info_v1 *info = matchinfo;
const struct ipt_addrtype_info_v1 *info = par->matchinfo;
const struct iphdr *iph = ip_hdr(skb);
const struct net_device *dev = NULL;
bool ret = true;
if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN)
dev = in;
dev = par->in;
else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT)
dev = out;
dev = par->out;
if (info->source)
ret &= match_type(dev, iph->saddr, info->source) ^
@ -74,12 +68,9 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in,
return ret;
}
static bool
addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
static bool addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
{
struct ipt_addrtype_info_v1 *info = matchinfo;
struct ipt_addrtype_info_v1 *info = par->matchinfo;
if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&
info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
@ -88,14 +79,16 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
return false;
}
if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) &&
if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_LOCAL_IN)) &&
info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
printk(KERN_ERR "ipt_addrtype: output interface limitation "
"not valid in PRE_ROUTING and INPUT\n");
return false;
}
if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) &&
if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
(1 << NF_INET_LOCAL_OUT)) &&
info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
printk(KERN_ERR "ipt_addrtype: input interface limitation "
"not valid in POST_ROUTING and OUTPUT\n");
@ -108,14 +101,14 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
static struct xt_match addrtype_mt_reg[] __read_mostly = {
{
.name = "addrtype",
.family = AF_INET,
.family = NFPROTO_IPV4,
.match = addrtype_mt_v0,
.matchsize = sizeof(struct ipt_addrtype_info),
.me = THIS_MODULE
},
{
.name = "addrtype",
.family = AF_INET,
.family = NFPROTO_IPV4,
.revision = 1,
.match = addrtype_mt_v1,
.checkentry = addrtype_mt_checkentry_v1,

View File

@ -36,27 +36,23 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
return r;
}
static bool
ah_mt(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
struct ip_auth_hdr _ahdr;
const struct ip_auth_hdr *ah;
const struct ipt_ah *ahinfo = matchinfo;
const struct ipt_ah *ahinfo = par->matchinfo;
/* Must not be a fragment. */
if (offset)
if (par->fragoff != 0)
return false;
ah = skb_header_pointer(skb, protoff,
sizeof(_ahdr), &_ahdr);
ah = skb_header_pointer(skb, par->thoff, sizeof(_ahdr), &_ahdr);
if (ah == NULL) {
/* We've been asked to examine this packet, and we
* can't. Hence, no choice but to drop.
*/
duprintf("Dropping evil AH tinygram.\n");
*hotdrop = true;
*par->hotdrop = true;
return 0;
}
@ -65,13 +61,9 @@ ah_mt(const struct sk_buff *skb, const struct net_device *in,
!!(ahinfo->invflags & IPT_AH_INV_SPI));
}
/* Called when user tries to insert an entry of this type. */
static bool
ah_mt_check(const char *tablename, const void *ip_void,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
static bool ah_mt_check(const struct xt_mtchk_param *par)
{
const struct ipt_ah *ahinfo = matchinfo;
const struct ipt_ah *ahinfo = par->matchinfo;
/* Must specify no unknown invflags */
if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
@ -83,7 +75,7 @@ ah_mt_check(const char *tablename, const void *ip_void,
static struct xt_match ah_mt_reg __read_mostly = {
.name = "ah",
.family = AF_INET,
.family = NFPROTO_IPV4,
.match = ah_mt,
.matchsize = sizeof(struct ipt_ah),
.proto = IPPROTO_AH,

View File

@ -67,12 +67,9 @@ static inline bool match_tcp(const struct sk_buff *skb,
return true;
}
static bool
ecn_mt(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ipt_ecn_info *info = matchinfo;
const struct ipt_ecn_info *info = par->matchinfo;
if (info->operation & IPT_ECN_OP_MATCH_IP)
if (!match_ip(skb, info))
@ -81,20 +78,17 @@ ecn_mt(const struct sk_buff *skb, const struct net_device *in,
if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
if (ip_hdr(skb)->protocol != IPPROTO_TCP)
return false;
if (!match_tcp(skb, info, hotdrop))
if (!match_tcp(skb, info, par->hotdrop))
return false;
}
return true;
}
static bool
ecn_mt_check(const char *tablename, const void *ip_void,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
static bool ecn_mt_check(const struct xt_mtchk_param *par)
{
const struct ipt_ecn_info *info = matchinfo;
const struct ipt_ip *ip = ip_void;
const struct ipt_ecn_info *info = par->matchinfo;
const struct ipt_ip *ip = par->entryinfo;
if (info->operation & IPT_ECN_OP_MATCH_MASK)
return false;
@ -114,7 +108,7 @@ ecn_mt_check(const char *tablename, const void *ip_void,
static struct xt_match ecn_mt_reg __read_mostly = {
.name = "ecn",
.family = AF_INET,
.family = NFPROTO_IPV4,
.match = ecn_mt,
.matchsize = sizeof(struct ipt_ecn_info),
.checkentry = ecn_mt_check,

View File

@ -18,12 +18,9 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
MODULE_DESCRIPTION("Xtables: IPv4 TTL field match");
MODULE_LICENSE("GPL");
static bool
ttl_mt(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
static bool ttl_mt(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ipt_ttl_info *info = matchinfo;
const struct ipt_ttl_info *info = par->matchinfo;
const u8 ttl = ip_hdr(skb)->ttl;
switch (info->mode) {
@ -46,7 +43,7 @@ ttl_mt(const struct sk_buff *skb, const struct net_device *in,
static struct xt_match ttl_mt_reg __read_mostly = {
.name = "ttl",
.family = AF_INET,
.family = NFPROTO_IPV4,
.match = ttl_mt,
.matchsize = sizeof(struct ipt_ttl_info),
.me = THIS_MODULE,

View File

@ -70,7 +70,7 @@ ipt_local_in_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ipt_do_table(skb, hook, in, out,
nf_local_in_net(in, out)->ipv4.iptable_filter);
dev_net(in)->ipv4.iptable_filter);
}
static unsigned int
@ -81,7 +81,7 @@ ipt_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ipt_do_table(skb, hook, in, out,
nf_forward_net(in, out)->ipv4.iptable_filter);
dev_net(in)->ipv4.iptable_filter);
}
static unsigned int
@ -101,7 +101,7 @@ ipt_local_out_hook(unsigned int hook,
}
return ipt_do_table(skb, hook, in, out,
nf_local_out_net(in, out)->ipv4.iptable_filter);
dev_net(out)->ipv4.iptable_filter);
}
static struct nf_hook_ops ipt_ops[] __read_mostly = {

View File

@ -81,7 +81,7 @@ ipt_pre_routing_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ipt_do_table(skb, hook, in, out,
nf_pre_routing_net(in, out)->ipv4.iptable_mangle);
dev_net(in)->ipv4.iptable_mangle);
}
static unsigned int
@ -92,7 +92,7 @@ ipt_post_routing_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ipt_do_table(skb, hook, in, out,
nf_post_routing_net(in, out)->ipv4.iptable_mangle);
dev_net(out)->ipv4.iptable_mangle);
}
static unsigned int
@ -103,7 +103,7 @@ ipt_local_in_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ipt_do_table(skb, hook, in, out,
nf_local_in_net(in, out)->ipv4.iptable_mangle);
dev_net(in)->ipv4.iptable_mangle);
}
static unsigned int
@ -114,7 +114,7 @@ ipt_forward_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ipt_do_table(skb, hook, in, out,
nf_forward_net(in, out)->ipv4.iptable_mangle);
dev_net(in)->ipv4.iptable_mangle);
}
static unsigned int
@ -147,7 +147,7 @@ ipt_local_hook(unsigned int hook,
tos = iph->tos;
ret = ipt_do_table(skb, hook, in, out,
nf_local_out_net(in, out)->ipv4.iptable_mangle);
dev_net(out)->ipv4.iptable_mangle);
/* Reroute for ANY change. */
if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
iph = ip_hdr(skb);

View File

@ -53,7 +53,7 @@ ipt_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ipt_do_table(skb, hook, in, out,
nf_pre_routing_net(in, out)->ipv4.iptable_raw);
dev_net(in)->ipv4.iptable_raw);
}
static unsigned int
@ -72,7 +72,7 @@ ipt_local_hook(unsigned int hook,
return NF_ACCEPT;
}
return ipt_do_table(skb, hook, in, out,
nf_local_out_net(in, out)->ipv4.iptable_raw);
dev_net(out)->ipv4.iptable_raw);
}
/* 'raw' is the very first table. */

View File

@ -73,7 +73,7 @@ ipt_local_in_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ipt_do_table(skb, hook, in, out,
nf_local_in_net(in, out)->ipv4.iptable_security);
dev_net(in)->ipv4.iptable_security);
}
static unsigned int
@ -84,7 +84,7 @@ ipt_forward_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ipt_do_table(skb, hook, in, out,
nf_forward_net(in, out)->ipv4.iptable_security);
dev_net(in)->ipv4.iptable_security);
}
static unsigned int
@ -103,7 +103,7 @@ ipt_local_out_hook(unsigned int hook,
return NF_ACCEPT;
}
return ipt_do_table(skb, hook, in, out,
nf_local_out_net(in, out)->ipv4.iptable_security);
dev_net(out)->ipv4.iptable_security);
}
static struct nf_hook_ops ipt_ops[] __read_mostly = {

View File

@ -1,3 +1,4 @@
/* (C) 1999-2001 Paul `Rusty' Russell
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
*
@ -24,6 +25,7 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
#include <net/netfilter/nf_nat_helper.h>
#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
struct nf_conn *ct,
@ -63,23 +65,6 @@ static int ipv4_print_tuple(struct seq_file *s,
NIPQUAD(tuple->dst.u3.ip));
}
/* Returns new sk_buff, or NULL */
static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
{
int err;
skb_orphan(skb);
local_bh_disable();
err = ip_defrag(skb, user);
local_bh_enable();
if (!err)
ip_send_check(ip_hdr(skb));
return err;
}
static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
unsigned int *dataoff, u_int8_t *protonum)
{
@ -144,35 +129,13 @@ out:
return nf_conntrack_confirm(skb);
}
static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
/* Previously seen (loopback)? Ignore. Do this before
fragment check. */
if (skb->nfct)
return NF_ACCEPT;
/* Gather fragments. */
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
if (nf_ct_ipv4_gather_frags(skb,
hooknum == NF_INET_PRE_ROUTING ?
IP_DEFRAG_CONNTRACK_IN :
IP_DEFRAG_CONNTRACK_OUT))
return NF_STOLEN;
}
return NF_ACCEPT;
}
static unsigned int ipv4_conntrack_in(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return nf_conntrack_in(PF_INET, hooknum, skb);
return nf_conntrack_in(dev_net(in), PF_INET, hooknum, skb);
}
static unsigned int ipv4_conntrack_local(unsigned int hooknum,
@ -188,19 +151,12 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum,
printk("ipt_hook: happy cracking.\n");
return NF_ACCEPT;
}
return nf_conntrack_in(PF_INET, hooknum, skb);
return nf_conntrack_in(dev_net(out), PF_INET, hooknum, skb);
}
/* Connection tracking may drop packets, but never alters them, so
make it the first hook. */
static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
{
.hook = ipv4_conntrack_defrag,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_DEFRAG,
},
{
.hook = ipv4_conntrack_in,
.owner = THIS_MODULE,
@ -208,13 +164,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_CONNTRACK,
},
{
.hook = ipv4_conntrack_defrag,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_CONNTRACK_DEFRAG,
},
{
.hook = ipv4_conntrack_local,
.owner = THIS_MODULE,
@ -254,7 +203,7 @@ static ctl_table ip_ct_sysctl_table[] = {
{
.ctl_name = NET_IPV4_NF_CONNTRACK_COUNT,
.procname = "ip_conntrack_count",
.data = &nf_conntrack_count,
.data = &init_net.ct.count,
.maxlen = sizeof(int),
.mode = 0444,
.proc_handler = &proc_dointvec,
@ -270,7 +219,7 @@ static ctl_table ip_ct_sysctl_table[] = {
{
.ctl_name = NET_IPV4_NF_CONNTRACK_CHECKSUM,
.procname = "ip_conntrack_checksum",
.data = &nf_conntrack_checksum,
.data = &init_net.ct.sysctl_checksum,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
@ -278,7 +227,7 @@ static ctl_table ip_ct_sysctl_table[] = {
{
.ctl_name = NET_IPV4_NF_CONNTRACK_LOG_INVALID,
.procname = "ip_conntrack_log_invalid",
.data = &nf_ct_log_invalid,
.data = &init_net.ct.sysctl_log_invalid,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = &proc_dointvec_minmax,
@ -323,7 +272,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
return -EINVAL;
}
h = nf_conntrack_find_get(&tuple);
h = nf_conntrack_find_get(sock_net(sk), &tuple);
if (h) {
struct sockaddr_in sin;
struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
@ -422,6 +371,7 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
int ret = 0;
need_conntrack();
nf_defrag_ipv4_enable();
ret = nf_register_sockopt(&so_getorigdst);
if (ret < 0) {

View File

@ -21,18 +21,20 @@
#include <net/netfilter/nf_conntrack_acct.h>
struct ct_iter_state {
struct seq_net_private p;
unsigned int bucket;
};
static struct hlist_node *ct_get_first(struct seq_file *seq)
{
struct net *net = seq_file_net(seq);
struct ct_iter_state *st = seq->private;
struct hlist_node *n;
for (st->bucket = 0;
st->bucket < nf_conntrack_htable_size;
st->bucket++) {
n = rcu_dereference(nf_conntrack_hash[st->bucket].first);
n = rcu_dereference(net->ct.hash[st->bucket].first);
if (n)
return n;
}
@ -42,13 +44,14 @@ static struct hlist_node *ct_get_first(struct seq_file *seq)
static struct hlist_node *ct_get_next(struct seq_file *seq,
struct hlist_node *head)
{
struct net *net = seq_file_net(seq);
struct ct_iter_state *st = seq->private;
head = rcu_dereference(head->next);
while (head == NULL) {
if (++st->bucket >= nf_conntrack_htable_size)
return NULL;
head = rcu_dereference(nf_conntrack_hash[st->bucket].first);
head = rcu_dereference(net->ct.hash[st->bucket].first);
}
return head;
}
@ -158,8 +161,8 @@ static const struct seq_operations ct_seq_ops = {
static int ct_open(struct inode *inode, struct file *file)
{
return seq_open_private(file, &ct_seq_ops,
sizeof(struct ct_iter_state));
return seq_open_net(inode, file, &ct_seq_ops,
sizeof(struct ct_iter_state));
}
static const struct file_operations ct_file_ops = {
@ -167,21 +170,23 @@ static const struct file_operations ct_file_ops = {
.open = ct_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_private,
.release = seq_release_net,
};
/* expects */
struct ct_expect_iter_state {
struct seq_net_private p;
unsigned int bucket;
};
static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
{
struct net *net = seq_file_net(seq);
struct ct_expect_iter_state *st = seq->private;
struct hlist_node *n;
for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
n = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
n = rcu_dereference(net->ct.expect_hash[st->bucket].first);
if (n)
return n;
}
@ -191,13 +196,14 @@ static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
struct hlist_node *head)
{
struct net *net = seq_file_net(seq);
struct ct_expect_iter_state *st = seq->private;
head = rcu_dereference(head->next);
while (head == NULL) {
if (++st->bucket >= nf_ct_expect_hsize)
return NULL;
head = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
head = rcu_dereference(net->ct.expect_hash[st->bucket].first);
}
return head;
}
@ -265,8 +271,8 @@ static const struct seq_operations exp_seq_ops = {
static int exp_open(struct inode *inode, struct file *file)
{
return seq_open_private(file, &exp_seq_ops,
sizeof(struct ct_expect_iter_state));
return seq_open_net(inode, file, &exp_seq_ops,
sizeof(struct ct_expect_iter_state));
}
static const struct file_operations ip_exp_file_ops = {
@ -274,11 +280,12 @@ static const struct file_operations ip_exp_file_ops = {
.open = exp_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_private,
.release = seq_release_net,
};
static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
{
struct net *net = seq_file_net(seq);
int cpu;
if (*pos == 0)
@ -288,7 +295,7 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
if (!cpu_possible(cpu))
continue;
*pos = cpu+1;
return &per_cpu(nf_conntrack_stat, cpu);
return per_cpu_ptr(net->ct.stat, cpu);
}
return NULL;
@ -296,13 +303,14 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct net *net = seq_file_net(seq);
int cpu;
for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
if (!cpu_possible(cpu))
continue;
*pos = cpu+1;
return &per_cpu(nf_conntrack_stat, cpu);
return per_cpu_ptr(net->ct.stat, cpu);
}
return NULL;
@ -314,7 +322,8 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
static int ct_cpu_seq_show(struct seq_file *seq, void *v)
{
unsigned int nr_conntracks = atomic_read(&nf_conntrack_count);
struct net *net = seq_file_net(seq);
unsigned int nr_conntracks = atomic_read(&net->ct.count);
const struct ip_conntrack_stat *st = v;
if (v == SEQ_START_TOKEN) {
@ -354,7 +363,8 @@ static const struct seq_operations ct_cpu_seq_ops = {
static int ct_cpu_seq_open(struct inode *inode, struct file *file)
{
return seq_open(file, &ct_cpu_seq_ops);
return seq_open_net(inode, file, &ct_cpu_seq_ops,
sizeof(struct seq_net_private));
}
static const struct file_operations ct_cpu_seq_fops = {
@ -362,39 +372,54 @@ static const struct file_operations ct_cpu_seq_fops = {
.open = ct_cpu_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
.release = seq_release_net,
};
int __init nf_conntrack_ipv4_compat_init(void)
static int __net_init ip_conntrack_net_init(struct net *net)
{
struct proc_dir_entry *proc, *proc_exp, *proc_stat;
proc = proc_net_fops_create(&init_net, "ip_conntrack", 0440, &ct_file_ops);
proc = proc_net_fops_create(net, "ip_conntrack", 0440, &ct_file_ops);
if (!proc)
goto err1;
proc_exp = proc_net_fops_create(&init_net, "ip_conntrack_expect", 0440,
proc_exp = proc_net_fops_create(net, "ip_conntrack_expect", 0440,
&ip_exp_file_ops);
if (!proc_exp)
goto err2;
proc_stat = proc_create("ip_conntrack", S_IRUGO,
init_net.proc_net_stat, &ct_cpu_seq_fops);
net->proc_net_stat, &ct_cpu_seq_fops);
if (!proc_stat)
goto err3;
return 0;
err3:
proc_net_remove(&init_net, "ip_conntrack_expect");
proc_net_remove(net, "ip_conntrack_expect");
err2:
proc_net_remove(&init_net, "ip_conntrack");
proc_net_remove(net, "ip_conntrack");
err1:
return -ENOMEM;
}
static void __net_exit ip_conntrack_net_exit(struct net *net)
{
remove_proc_entry("ip_conntrack", net->proc_net_stat);
proc_net_remove(net, "ip_conntrack_expect");
proc_net_remove(net, "ip_conntrack");
}
static struct pernet_operations ip_conntrack_net_ops = {
.init = ip_conntrack_net_init,
.exit = ip_conntrack_net_exit,
};
int __init nf_conntrack_ipv4_compat_init(void)
{
return register_pernet_subsys(&ip_conntrack_net_ops);
}
void __exit nf_conntrack_ipv4_compat_fini(void)
{
remove_proc_entry("ip_conntrack", init_net.proc_net_stat);
proc_net_remove(&init_net, "ip_conntrack_expect");
proc_net_remove(&init_net, "ip_conntrack");
unregister_pernet_subsys(&ip_conntrack_net_ops);
}

View File

@ -79,7 +79,7 @@ static int icmp_packet(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
int pf,
u_int8_t pf,
unsigned int hooknum)
{
/* Try to delete connection immediately after all replies:
@ -91,7 +91,7 @@ static int icmp_packet(struct nf_conn *ct,
nf_ct_kill_acct(ct, ctinfo, skb);
} else {
atomic_inc(&ct->proto.icmp.count);
nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
}
@ -123,7 +123,7 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,
/* Returns conntrack if it dealt with ICMP, and filled in skb fields */
static int
icmp_error_message(struct sk_buff *skb,
icmp_error_message(struct net *net, struct sk_buff *skb,
enum ip_conntrack_info *ctinfo,
unsigned int hooknum)
{
@ -155,7 +155,7 @@ icmp_error_message(struct sk_buff *skb,
*ctinfo = IP_CT_RELATED;
h = nf_conntrack_find_get(&innertuple);
h = nf_conntrack_find_get(net, &innertuple);
if (!h) {
pr_debug("icmp_error_message: no match\n");
return -NF_ACCEPT;
@ -172,8 +172,8 @@ icmp_error_message(struct sk_buff *skb,
/* Small and modified version of icmp_rcv */
static int
icmp_error(struct sk_buff *skb, unsigned int dataoff,
enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
icmp_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
{
const struct icmphdr *icmph;
struct icmphdr _ih;
@ -181,16 +181,16 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
/* Not enough header? */
icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih);
if (icmph == NULL) {
if (LOG_INVALID(IPPROTO_ICMP))
if (LOG_INVALID(net, IPPROTO_ICMP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
"nf_ct_icmp: short packet ");
return -NF_ACCEPT;
}
/* See ip_conntrack_proto_tcp.c */
if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
nf_ip_checksum(skb, hooknum, dataoff, 0)) {
if (LOG_INVALID(IPPROTO_ICMP))
if (LOG_INVALID(net, IPPROTO_ICMP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
"nf_ct_icmp: bad HW ICMP checksum ");
return -NF_ACCEPT;
@ -203,7 +203,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
* discarded.
*/
if (icmph->type > NR_ICMP_TYPES) {
if (LOG_INVALID(IPPROTO_ICMP))
if (LOG_INVALID(net, IPPROTO_ICMP))
nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
"nf_ct_icmp: invalid ICMP type ");
return -NF_ACCEPT;
@ -217,7 +217,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
&& icmph->type != ICMP_REDIRECT)
return NF_ACCEPT;
return icmp_error_message(skb, ctinfo, hooknum);
return icmp_error_message(net, skb, ctinfo, hooknum);
}
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)

View File

@ -0,0 +1,96 @@
/* (C) 1999-2001 Paul `Rusty' Russell
* (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/netfilter.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <net/route.h>
#include <net/ip.h>
#include <linux/netfilter_ipv4.h>
#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
/* Returns new sk_buff, or NULL */
static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
{
int err;
skb_orphan(skb);
local_bh_disable();
err = ip_defrag(skb, user);
local_bh_enable();
if (!err)
ip_send_check(ip_hdr(skb));
return err;
}
static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
/* Previously seen (loopback)? Ignore. Do this before
fragment check. */
if (skb->nfct)
return NF_ACCEPT;
#endif
/* Gather fragments. */
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
if (nf_ct_ipv4_gather_frags(skb,
hooknum == NF_INET_PRE_ROUTING ?
IP_DEFRAG_CONNTRACK_IN :
IP_DEFRAG_CONNTRACK_OUT))
return NF_STOLEN;
}
return NF_ACCEPT;
}
static struct nf_hook_ops ipv4_defrag_ops[] = {
{
.hook = ipv4_conntrack_defrag,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_DEFRAG,
},
{
.hook = ipv4_conntrack_defrag,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_CONNTRACK_DEFRAG,
},
};
static int __init nf_defrag_init(void)
{
return nf_register_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
}
static void __exit nf_defrag_fini(void)
{
nf_unregister_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
}
void nf_defrag_ipv4_enable(void)
{
}
EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable);
module_init(nf_defrag_init);
module_exit(nf_defrag_fini);
MODULE_LICENSE("GPL");

View File

@ -37,9 +37,6 @@ static struct nf_conntrack_l3proto *l3proto __read_mostly;
/* Calculated at init based on memory size */
static unsigned int nf_nat_htable_size __read_mostly;
static int nf_nat_vmalloced;
static struct hlist_head *bysource __read_mostly;
#define MAX_IP_NAT_PROTO 256
static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO]
@ -145,7 +142,8 @@ same_src(const struct nf_conn *ct,
/* Only called for SRC manip */
static int
find_appropriate_src(const struct nf_conntrack_tuple *tuple,
find_appropriate_src(struct net *net,
const struct nf_conntrack_tuple *tuple,
struct nf_conntrack_tuple *result,
const struct nf_nat_range *range)
{
@ -155,7 +153,7 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple,
const struct hlist_node *n;
rcu_read_lock();
hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) {
hlist_for_each_entry_rcu(nat, n, &net->ipv4.nat_bysource[h], bysource) {
ct = nat->ct;
if (same_src(ct, tuple)) {
/* Copy source part from reply tuple. */
@ -231,6 +229,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
struct nf_conn *ct,
enum nf_nat_manip_type maniptype)
{
struct net *net = nf_ct_net(ct);
const struct nf_nat_protocol *proto;
/* 1) If this srcip/proto/src-proto-part is currently mapped,
@ -242,7 +241,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
manips not an issue. */
if (maniptype == IP_NAT_MANIP_SRC &&
!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) {
if (find_appropriate_src(orig_tuple, tuple, range)) {
if (find_appropriate_src(net, orig_tuple, tuple, range)) {
pr_debug("get_unique_tuple: Found current src map\n");
if (!nf_nat_used_tuple(tuple, ct))
return;
@ -283,6 +282,7 @@ nf_nat_setup_info(struct nf_conn *ct,
const struct nf_nat_range *range,
enum nf_nat_manip_type maniptype)
{
struct net *net = nf_ct_net(ct);
struct nf_conntrack_tuple curr_tuple, new_tuple;
struct nf_conn_nat *nat;
int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK);
@ -334,7 +334,8 @@ nf_nat_setup_info(struct nf_conn *ct,
/* nf_conntrack_alter_reply might re-allocate exntension aera */
nat = nfct_nat(ct);
nat->ct = ct;
hlist_add_head_rcu(&nat->bysource, &bysource[srchash]);
hlist_add_head_rcu(&nat->bysource,
&net->ipv4.nat_bysource[srchash]);
spin_unlock_bh(&nf_nat_lock);
}
@ -583,6 +584,40 @@ static struct nf_ct_ext_type nat_extend __read_mostly = {
.flags = NF_CT_EXT_F_PREALLOC,
};
static int __net_init nf_nat_net_init(struct net *net)
{
net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
&net->ipv4.nat_vmalloced);
if (!net->ipv4.nat_bysource)
return -ENOMEM;
return 0;
}
/* Clear NAT section of all conntracks, in case we're loaded again. */
static int clean_nat(struct nf_conn *i, void *data)
{
struct nf_conn_nat *nat = nfct_nat(i);
if (!nat)
return 0;
memset(nat, 0, sizeof(*nat));
i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
return 0;
}
static void __net_exit nf_nat_net_exit(struct net *net)
{
nf_ct_iterate_cleanup(net, &clean_nat, NULL);
synchronize_rcu();
nf_ct_free_hashtable(net->ipv4.nat_bysource, net->ipv4.nat_vmalloced,
nf_nat_htable_size);
}
static struct pernet_operations nf_nat_net_ops = {
.init = nf_nat_net_init,
.exit = nf_nat_net_exit,
};
static int __init nf_nat_init(void)
{
size_t i;
@ -599,12 +634,9 @@ static int __init nf_nat_init(void)
/* Leave them the same for the moment. */
nf_nat_htable_size = nf_conntrack_htable_size;
bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
&nf_nat_vmalloced);
if (!bysource) {
ret = -ENOMEM;
ret = register_pernet_subsys(&nf_nat_net_ops);
if (ret < 0)
goto cleanup_extend;
}
/* Sew in builtin protocols. */
spin_lock_bh(&nf_nat_lock);
@ -629,23 +661,9 @@ static int __init nf_nat_init(void)
return ret;
}
/* Clear NAT section of all conntracks, in case we're loaded again. */
static int clean_nat(struct nf_conn *i, void *data)
{
struct nf_conn_nat *nat = nfct_nat(i);
if (!nat)
return 0;
memset(nat, 0, sizeof(*nat));
i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
return 0;
}
static void __exit nf_nat_cleanup(void)
{
nf_ct_iterate_cleanup(&clean_nat, NULL);
synchronize_rcu();
nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size);
unregister_pernet_subsys(&nf_nat_net_ops);
nf_ct_l3proto_put(l3proto);
nf_ct_extend_unregister(&nat_extend);
rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);

View File

@ -193,7 +193,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb,
nf_conntrack_tcp_update(skb, ip_hdrlen(skb),
ct, CTINFO2DIR(ctinfo));
nf_conntrack_event_cache(IPCT_NATSEQADJ, skb);
nf_conntrack_event_cache(IPCT_NATSEQADJ, ct);
}
return 1;
}

View File

@ -40,6 +40,7 @@ MODULE_ALIAS("ip_nat_pptp");
static void pptp_nat_expected(struct nf_conn *ct,
struct nf_conntrack_expect *exp)
{
struct net *net = nf_ct_net(ct);
const struct nf_conn *master = ct->master;
struct nf_conntrack_expect *other_exp;
struct nf_conntrack_tuple t;
@ -73,7 +74,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
pr_debug("trying to unexpect other dir: ");
nf_ct_dump_tuple_ip(&t);
other_exp = nf_ct_expect_find_get(&t);
other_exp = nf_ct_expect_find_get(net, &t);
if (other_exp) {
nf_ct_unexpect_related(other_exp);
nf_ct_expect_put(other_exp);

View File

@ -33,7 +33,7 @@ static struct
struct ipt_replace repl;
struct ipt_standard entries[3];
struct ipt_error term;
} nat_initial_table __initdata = {
} nat_initial_table __net_initdata = {
.repl = {
.name = "nat",
.valid_hooks = NAT_VALID_HOOKS,
@ -58,47 +58,42 @@ static struct
.term = IPT_ERROR_INIT, /* ERROR */
};
static struct xt_table __nat_table = {
static struct xt_table nat_table = {
.name = "nat",
.valid_hooks = NAT_VALID_HOOKS,
.lock = __RW_LOCK_UNLOCKED(__nat_table.lock),
.me = THIS_MODULE,
.af = AF_INET,
};
static struct xt_table *nat_table;
/* Source NAT */
static unsigned int ipt_snat_target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
static unsigned int
ipt_snat_target(struct sk_buff *skb, const struct xt_target_param *par)
{
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
const struct nf_nat_multi_range_compat *mr = targinfo;
const struct nf_nat_multi_range_compat *mr = par->targinfo;
NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING);
NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING);
ct = nf_ct_get(skb, &ctinfo);
/* Connection must be valid and new. */
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
NF_CT_ASSERT(out);
NF_CT_ASSERT(par->out != NULL);
return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
}
/* Before 2.6.11 we did implicit source NAT if required. Warn about change. */
static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
static void warn_if_extra_mangle(struct net *net, __be32 dstip, __be32 srcip)
{
static int warned = 0;
struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
struct rtable *rt;
if (ip_route_output_key(&init_net, &rt, &fl) != 0)
if (ip_route_output_key(net, &rt, &fl) != 0)
return;
if (rt->rt_src != srcip && !warned) {
@ -110,40 +105,32 @@ static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
ip_rt_put(rt);
}
static unsigned int ipt_dnat_target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
static unsigned int
ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par)
{
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
const struct nf_nat_multi_range_compat *mr = targinfo;
const struct nf_nat_multi_range_compat *mr = par->targinfo;
NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING ||
hooknum == NF_INET_LOCAL_OUT);
NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
par->hooknum == NF_INET_LOCAL_OUT);
ct = nf_ct_get(skb, &ctinfo);
/* Connection must be valid and new. */
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
if (hooknum == NF_INET_LOCAL_OUT &&
if (par->hooknum == NF_INET_LOCAL_OUT &&
mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
warn_if_extra_mangle(ip_hdr(skb)->daddr,
warn_if_extra_mangle(dev_net(par->out), ip_hdr(skb)->daddr,
mr->range[0].min_ip);
return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST);
}
static bool ipt_snat_checkentry(const char *tablename,
const void *entry,
const struct xt_target *target,
void *targinfo,
unsigned int hook_mask)
static bool ipt_snat_checkentry(const struct xt_tgchk_param *par)
{
const struct nf_nat_multi_range_compat *mr = targinfo;
const struct nf_nat_multi_range_compat *mr = par->targinfo;
/* Must be a valid range */
if (mr->rangesize != 1) {
@ -153,13 +140,9 @@ static bool ipt_snat_checkentry(const char *tablename,
return true;
}
static bool ipt_dnat_checkentry(const char *tablename,
const void *entry,
const struct xt_target *target,
void *targinfo,
unsigned int hook_mask)
static bool ipt_dnat_checkentry(const struct xt_tgchk_param *par)
{
const struct nf_nat_multi_range_compat *mr = targinfo;
const struct nf_nat_multi_range_compat *mr = par->targinfo;
/* Must be a valid range */
if (mr->rangesize != 1) {
@ -194,9 +177,10 @@ int nf_nat_rule_find(struct sk_buff *skb,
const struct net_device *out,
struct nf_conn *ct)
{
struct net *net = nf_ct_net(ct);
int ret;
ret = ipt_do_table(skb, hooknum, in, out, nat_table);
ret = ipt_do_table(skb, hooknum, in, out, net->ipv4.nat_table);
if (ret == NF_ACCEPT) {
if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
@ -226,14 +210,32 @@ static struct xt_target ipt_dnat_reg __read_mostly = {
.family = AF_INET,
};
static int __net_init nf_nat_rule_net_init(struct net *net)
{
net->ipv4.nat_table = ipt_register_table(net, &nat_table,
&nat_initial_table.repl);
if (IS_ERR(net->ipv4.nat_table))
return PTR_ERR(net->ipv4.nat_table);
return 0;
}
static void __net_exit nf_nat_rule_net_exit(struct net *net)
{
ipt_unregister_table(net->ipv4.nat_table);
}
static struct pernet_operations nf_nat_rule_net_ops = {
.init = nf_nat_rule_net_init,
.exit = nf_nat_rule_net_exit,
};
int __init nf_nat_rule_init(void)
{
int ret;
nat_table = ipt_register_table(&init_net, &__nat_table,
&nat_initial_table.repl);
if (IS_ERR(nat_table))
return PTR_ERR(nat_table);
ret = register_pernet_subsys(&nf_nat_rule_net_ops);
if (ret != 0)
goto out;
ret = xt_register_target(&ipt_snat_reg);
if (ret != 0)
goto unregister_table;
@ -247,8 +249,8 @@ int __init nf_nat_rule_init(void)
unregister_snat:
xt_unregister_target(&ipt_snat_reg);
unregister_table:
ipt_unregister_table(nat_table);
unregister_pernet_subsys(&nf_nat_rule_net_ops);
out:
return ret;
}
@ -256,5 +258,5 @@ void nf_nat_rule_cleanup(void)
{
xt_unregister_target(&ipt_dnat_reg);
xt_unregister_target(&ipt_snat_reg);
ipt_unregister_table(nat_table);
unregister_pernet_subsys(&nf_nat_rule_net_ops);
}

View File

@ -23,7 +23,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
.saddr = iph->saddr, } },
};
dst = ip6_route_output(&init_net, skb->sk, &fl);
dst = ip6_route_output(dev_net(skb->dst->dev), skb->sk, &fl);
#ifdef CONFIG_XFRM
if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&

View File

@ -55,30 +55,29 @@ config IP6_NF_IPTABLES
To compile it as a module, choose M here. If unsure, say N.
if IP6_NF_IPTABLES
# The simple matches.
config IP6_NF_MATCH_RT
tristate '"rt" Routing header match support'
depends on IP6_NF_IPTABLES
config IP6_NF_MATCH_AH
tristate '"ah" match support'
depends on NETFILTER_ADVANCED
help
rt matching allows you to match packets based on the routing
header of the packet.
This module allows one to match AH packets.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_OPTS
tristate '"hopbyhop" and "dst" opts header match support'
depends on IP6_NF_IPTABLES
config IP6_NF_MATCH_EUI64
tristate '"eui64" address check'
depends on NETFILTER_ADVANCED
help
This allows one to match packets based on the hop-by-hop
and destination options headers of a packet.
This module performs checking on the IPv6 source address
Compares the last 64 bits with the EUI64 (delivered
from the MAC address) address
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_FRAG
tristate '"frag" Fragmentation header match support'
depends on IP6_NF_IPTABLES
depends on NETFILTER_ADVANCED
help
frag matching allows you to match packets based on the fragmentation
@ -86,9 +85,17 @@ config IP6_NF_MATCH_FRAG
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_OPTS
tristate '"hbh" hop-by-hop and "dst" opts header match support'
depends on NETFILTER_ADVANCED
help
This allows one to match packets based on the hop-by-hop
and destination options headers of a packet.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_HL
tristate '"hl" match support'
depends on IP6_NF_IPTABLES
depends on NETFILTER_ADVANCED
help
HL matching allows you to match packets based on the hop
@ -98,7 +105,6 @@ config IP6_NF_MATCH_HL
config IP6_NF_MATCH_IPV6HEADER
tristate '"ipv6header" IPv6 Extension Headers Match'
depends on IP6_NF_IPTABLES
default m if NETFILTER_ADVANCED=n
help
This module allows one to match packets based upon
@ -106,39 +112,35 @@ config IP6_NF_MATCH_IPV6HEADER
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_AH
tristate '"ah" match support'
depends on IP6_NF_IPTABLES
depends on NETFILTER_ADVANCED
help
This module allows one to match AH packets.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_MH
tristate '"mh" match support'
depends on IP6_NF_IPTABLES
depends on NETFILTER_ADVANCED
help
This module allows one to match MH packets.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_MATCH_EUI64
tristate '"eui64" address check'
depends on IP6_NF_IPTABLES
config IP6_NF_MATCH_RT
tristate '"rt" Routing header match support'
depends on NETFILTER_ADVANCED
help
This module performs checking on the IPv6 source address
Compares the last 64 bits with the EUI64 (delivered
from the MAC address) address
rt matching allows you to match packets based on the routing
header of the packet.
To compile it as a module, choose M here. If unsure, say N.
# The targets
config IP6_NF_TARGET_LOG
tristate "LOG target support"
default m if NETFILTER_ADVANCED=n
help
This option adds a `LOG' target, which allows you to create rules in
any iptables table which records the packet header to the syslog.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_FILTER
tristate "Packet filtering"
depends on IP6_NF_IPTABLES
default m if NETFILTER_ADVANCED=n
help
Packet filtering defines a table `filter', which has a series of
@ -147,16 +149,6 @@ config IP6_NF_FILTER
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_TARGET_LOG
tristate "LOG target support"
depends on IP6_NF_FILTER
default m if NETFILTER_ADVANCED=n
help
This option adds a `LOG' target, which allows you to create rules in
any iptables table which records the packet header to the syslog.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_TARGET_REJECT
tristate "REJECT target support"
depends on IP6_NF_FILTER
@ -170,7 +162,6 @@ config IP6_NF_TARGET_REJECT
config IP6_NF_MANGLE
tristate "Packet mangling"
depends on IP6_NF_IPTABLES
default m if NETFILTER_ADVANCED=n
help
This option adds a `mangle' table to iptables: see the man page for
@ -198,7 +189,6 @@ config IP6_NF_TARGET_HL
config IP6_NF_RAW
tristate 'raw table support (required for TRACE)'
depends on IP6_NF_IPTABLES
depends on NETFILTER_ADVANCED
help
This option adds a `raw' table to ip6tables. This table is the very
@ -211,7 +201,6 @@ config IP6_NF_RAW
# security table for MAC policy
config IP6_NF_SECURITY
tristate "Security table"
depends on IP6_NF_IPTABLES
depends on SECURITY
depends on NETFILTER_ADVANCED
help
@ -220,5 +209,7 @@ config IP6_NF_SECURITY
If unsure, say N.
endif # IP6_NF_IPTABLES
endmenu

View File

@ -200,32 +200,25 @@ ip6_checkentry(const struct ip6t_ip6 *ipv6)
}
static unsigned int
ip6t_error(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
ip6t_error(struct sk_buff *skb, const struct xt_target_param *par)
{
if (net_ratelimit())
printk("ip6_tables: error: `%s'\n", (char *)targinfo);
printk("ip6_tables: error: `%s'\n",
(const char *)par->targinfo);
return NF_DROP;
}
/* Performance critical - called for every packet */
static inline bool
do_match(struct ip6t_entry_match *m,
const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int offset,
unsigned int protoff,
bool *hotdrop)
do_match(struct ip6t_entry_match *m, const struct sk_buff *skb,
struct xt_match_param *par)
{
par->match = m->u.kernel.match;
par->matchinfo = m->data;
/* Stop iteration if it doesn't match */
if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data,
offset, protoff, hotdrop))
if (!m->u.kernel.match->match(skb, par))
return true;
else
return false;
@ -355,8 +348,6 @@ ip6t_do_table(struct sk_buff *skb,
struct xt_table *table)
{
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
int offset = 0;
unsigned int protoff = 0;
bool hotdrop = false;
/* Initializing verdict to NF_DROP keeps gcc happy. */
unsigned int verdict = NF_DROP;
@ -364,6 +355,8 @@ ip6t_do_table(struct sk_buff *skb,
void *table_base;
struct ip6t_entry *e, *back;
struct xt_table_info *private;
struct xt_match_param mtpar;
struct xt_target_param tgpar;
/* Initialization */
indev = in ? in->name : nulldevname;
@ -374,6 +367,11 @@ ip6t_do_table(struct sk_buff *skb,
* things we don't know, ie. tcp syn flag or ports). If the
* rule is also a fragment-specific rule, non-fragments won't
* match it. */
mtpar.hotdrop = &hotdrop;
mtpar.in = tgpar.in = in;
mtpar.out = tgpar.out = out;
mtpar.family = tgpar.family = NFPROTO_IPV6;
tgpar.hooknum = hook;
read_lock_bh(&table->lock);
IP_NF_ASSERT(table->valid_hooks & (1 << hook));
@ -388,12 +386,10 @@ ip6t_do_table(struct sk_buff *skb,
IP_NF_ASSERT(e);
IP_NF_ASSERT(back);
if (ip6_packet_match(skb, indev, outdev, &e->ipv6,
&protoff, &offset, &hotdrop)) {
&mtpar.thoff, &mtpar.fragoff, &hotdrop)) {
struct ip6t_entry_target *t;
if (IP6T_MATCH_ITERATE(e, do_match,
skb, in, out,
offset, protoff, &hotdrop) != 0)
if (IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0)
goto no_match;
ADD_COUNTER(e->counters,
@ -441,15 +437,15 @@ ip6t_do_table(struct sk_buff *skb,
} else {
/* Targets which reenter must return
abs. verdicts */
tgpar.target = t->u.kernel.target;
tgpar.targinfo = t->data;
#ifdef CONFIG_NETFILTER_DEBUG
((struct ip6t_entry *)table_base)->comefrom
= 0xeeeeeeec;
#endif
verdict = t->u.kernel.target->target(skb,
in, out,
hook,
t->u.kernel.target,
t->data);
&tgpar);
#ifdef CONFIG_NETFILTER_DEBUG
if (((struct ip6t_entry *)table_base)->comefrom
@ -602,12 +598,17 @@ mark_source_chains(struct xt_table_info *newinfo,
static int
cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
{
struct xt_mtdtor_param par;
if (i && (*i)-- == 0)
return 1;
if (m->u.kernel.match->destroy)
m->u.kernel.match->destroy(m->u.kernel.match, m->data);
module_put(m->u.kernel.match->me);
par.match = m->u.kernel.match;
par.matchinfo = m->data;
par.family = NFPROTO_IPV6;
if (par.match->destroy != NULL)
par.match->destroy(&par);
module_put(par.match->me);
return 0;
}
@ -632,34 +633,28 @@ check_entry(struct ip6t_entry *e, const char *name)
return 0;
}
static int check_match(struct ip6t_entry_match *m, const char *name,
const struct ip6t_ip6 *ipv6,
unsigned int hookmask, unsigned int *i)
static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
unsigned int *i)
{
struct xt_match *match;
const struct ip6t_ip6 *ipv6 = par->entryinfo;
int ret;
match = m->u.kernel.match;
ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m),
name, hookmask, ipv6->proto,
ipv6->invflags & IP6T_INV_PROTO);
if (!ret && m->u.kernel.match->checkentry
&& !m->u.kernel.match->checkentry(name, ipv6, match, m->data,
hookmask)) {
par->match = m->u.kernel.match;
par->matchinfo = m->data;
ret = xt_check_match(par, m->u.match_size - sizeof(*m),
ipv6->proto, ipv6->invflags & IP6T_INV_PROTO);
if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n",
m->u.kernel.match->name);
ret = -EINVAL;
par.match->name);
return ret;
}
if (!ret)
(*i)++;
return ret;
++*i;
return 0;
}
static int
find_check_match(struct ip6t_entry_match *m,
const char *name,
const struct ip6t_ip6 *ipv6,
unsigned int hookmask,
find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
unsigned int *i)
{
struct xt_match *match;
@ -674,7 +669,7 @@ find_check_match(struct ip6t_entry_match *m,
}
m->u.kernel.match = match;
ret = check_match(m, name, ipv6, hookmask, i);
ret = check_match(m, par, i);
if (ret)
goto err;
@ -686,23 +681,26 @@ err:
static int check_target(struct ip6t_entry *e, const char *name)
{
struct ip6t_entry_target *t;
struct xt_target *target;
struct ip6t_entry_target *t = ip6t_get_target(e);
struct xt_tgchk_param par = {
.table = name,
.entryinfo = e,
.target = t->u.kernel.target,
.targinfo = t->data,
.hook_mask = e->comefrom,
.family = NFPROTO_IPV6,
};
int ret;
t = ip6t_get_target(e);
target = t->u.kernel.target;
ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t),
name, e->comefrom, e->ipv6.proto,
e->ipv6.invflags & IP6T_INV_PROTO);
if (!ret && t->u.kernel.target->checkentry
&& !t->u.kernel.target->checkentry(name, e, target, t->data,
e->comefrom)) {
ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO);
if (ret < 0) {
duprintf("ip_tables: check failed for `%s'.\n",
t->u.kernel.target->name);
ret = -EINVAL;
return ret;
}
return ret;
return 0;
}
static int
@ -713,14 +711,18 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
struct xt_target *target;
int ret;
unsigned int j;
struct xt_mtchk_param mtpar;
ret = check_entry(e, name);
if (ret)
return ret;
j = 0;
ret = IP6T_MATCH_ITERATE(e, find_check_match, name, &e->ipv6,
e->comefrom, &j);
mtpar.table = name;
mtpar.entryinfo = &e->ipv6;
mtpar.hook_mask = e->comefrom;
mtpar.family = NFPROTO_IPV6;
ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
if (ret != 0)
goto cleanup_matches;
@ -795,6 +797,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
static int
cleanup_entry(struct ip6t_entry *e, unsigned int *i)
{
struct xt_tgdtor_param par;
struct ip6t_entry_target *t;
if (i && (*i)-- == 0)
@ -803,9 +806,13 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
/* Cleanup all matches */
IP6T_MATCH_ITERATE(e, cleanup_match, NULL);
t = ip6t_get_target(e);
if (t->u.kernel.target->destroy)
t->u.kernel.target->destroy(t->u.kernel.target, t->data);
module_put(t->u.kernel.target->me);
par.target = t->u.kernel.target;
par.targinfo = t->data;
par.family = NFPROTO_IPV6;
if (par.target->destroy != NULL)
par.target->destroy(&par);
module_put(par.target->me);
return 0;
}
@ -1677,10 +1684,14 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
{
unsigned int j;
int ret;
struct xt_mtchk_param mtpar;
j = 0;
ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6,
e->comefrom, &j);
mtpar.table = name;
mtpar.entryinfo = &e->ipv6;
mtpar.hook_mask = e->comefrom;
mtpar.family = NFPROTO_IPV6;
ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j);
if (ret)
goto cleanup_matches;
@ -2146,30 +2157,23 @@ icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
}
static bool
icmp6_match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const struct xt_match *match,
const void *matchinfo,
int offset,
unsigned int protoff,
bool *hotdrop)
icmp6_match(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct icmp6hdr *ic;
struct icmp6hdr _icmph;
const struct ip6t_icmp *icmpinfo = matchinfo;
const struct ip6t_icmp *icmpinfo = par->matchinfo;
/* Must not be a fragment. */
if (offset)
if (par->fragoff != 0)
return false;
ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph);
ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
if (ic == NULL) {
/* We've been asked to examine this packet, and we
* can't. Hence, no choice but to drop.
*/
duprintf("Dropping evil ICMP tinygram.\n");
*hotdrop = true;
*par->hotdrop = true;
return false;
}
@ -2181,14 +2185,9 @@ icmp6_match(const struct sk_buff *skb,
}
/* Called when user tries to insert an entry of this type. */
static bool
icmp6_checkentry(const char *tablename,
const void *entry,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask)
static bool icmp6_checkentry(const struct xt_mtchk_param *par)
{
const struct ip6t_icmp *icmpinfo = matchinfo;
const struct ip6t_icmp *icmpinfo = par->matchinfo;
/* Must specify no unknown invflags */
return !(icmpinfo->invflags & ~IP6T_ICMP_INV);

View File

@ -19,12 +19,10 @@ MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field modification target");
MODULE_LICENSE("GPL");
static unsigned int
hl_tg6(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
hl_tg6(struct sk_buff *skb, const struct xt_target_param *par)
{
struct ipv6hdr *ip6h;
const struct ip6t_HL_info *info = targinfo;
const struct ip6t_HL_info *info = par->targinfo;
int new_hl;
if (!skb_make_writable(skb, skb->len))
@ -56,12 +54,9 @@ hl_tg6(struct sk_buff *skb, const struct net_device *in,
return XT_CONTINUE;
}
static bool
hl_tg6_check(const char *tablename, const void *entry,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
static bool hl_tg6_check(const struct xt_tgchk_param *par)
{
const struct ip6t_HL_info *info = targinfo;
const struct ip6t_HL_info *info = par->targinfo;
if (info->mode > IP6T_HL_MAXMODE) {
printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
@ -78,7 +73,7 @@ hl_tg6_check(const char *tablename, const void *entry,
static struct xt_target hl_tg6_reg __read_mostly = {
.name = "HL",
.family = AF_INET6,
.family = NFPROTO_IPV6,
.target = hl_tg6,
.targetsize = sizeof(struct ip6t_HL_info),
.table = "mangle",

View File

@ -385,7 +385,7 @@ static struct nf_loginfo default_loginfo = {
};
static void
ip6t_log_packet(unsigned int pf,
ip6t_log_packet(u_int8_t pf,
unsigned int hooknum,
const struct sk_buff *skb,
const struct net_device *in,
@ -438,28 +438,24 @@ ip6t_log_packet(unsigned int pf,
}
static unsigned int
log_tg6(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
log_tg6(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct ip6t_log_info *loginfo = targinfo;
const struct ip6t_log_info *loginfo = par->targinfo;
struct nf_loginfo li;
li.type = NF_LOG_TYPE_LOG;
li.u.log.level = loginfo->level;
li.u.log.logflags = loginfo->logflags;
ip6t_log_packet(PF_INET6, hooknum, skb, in, out, &li, loginfo->prefix);
ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in, par->out,
&li, loginfo->prefix);
return XT_CONTINUE;
}
static bool
log_tg6_check(const char *tablename, const void *entry,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
static bool log_tg6_check(const struct xt_tgchk_param *par)
{
const struct ip6t_log_info *loginfo = targinfo;
const struct ip6t_log_info *loginfo = par->targinfo;
if (loginfo->level >= 8) {
pr_debug("LOG: level %u >= 8\n", loginfo->level);
@ -475,7 +471,7 @@ log_tg6_check(const char *tablename, const void *entry,
static struct xt_target log_tg6_reg __read_mostly = {
.name = "LOG",
.family = AF_INET6,
.family = NFPROTO_IPV6,
.target = log_tg6,
.targetsize = sizeof(struct ip6t_log_info),
.checkentry = log_tg6_check,
@ -495,7 +491,7 @@ static int __init log_tg6_init(void)
ret = xt_register_target(&log_tg6_reg);
if (ret < 0)
return ret;
nf_log_register(PF_INET6, &ip6t_logger);
nf_log_register(NFPROTO_IPV6, &ip6t_logger);
return 0;
}

View File

@ -35,7 +35,7 @@ MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv6");
MODULE_LICENSE("GPL");
/* Send RST reply */
static void send_reset(struct sk_buff *oldskb)
static void send_reset(struct net *net, struct sk_buff *oldskb)
{
struct sk_buff *nskb;
struct tcphdr otcph, *tcph;
@ -94,7 +94,7 @@ static void send_reset(struct sk_buff *oldskb)
fl.fl_ip_sport = otcph.dest;
fl.fl_ip_dport = otcph.source;
security_skb_classify_flow(oldskb, &fl);
dst = ip6_route_output(&init_net, NULL, &fl);
dst = ip6_route_output(net, NULL, &fl);
if (dst == NULL)
return;
if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0))
@ -163,20 +163,20 @@ static void send_reset(struct sk_buff *oldskb)
}
static inline void
send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum)
send_unreach(struct net *net, struct sk_buff *skb_in, unsigned char code,
unsigned int hooknum)
{
if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
skb_in->dev = init_net.loopback_dev;
skb_in->dev = net->loopback_dev;
icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL);
}
static unsigned int
reject_tg6(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
reject_tg6(struct sk_buff *skb, const struct xt_target_param *par)
{
const struct ip6t_reject_info *reject = targinfo;
const struct ip6t_reject_info *reject = par->targinfo;
struct net *net = dev_net((par->in != NULL) ? par->in : par->out);
pr_debug("%s: medium point\n", __func__);
/* WARNING: This code causes reentry within ip6tables.
@ -184,25 +184,25 @@ reject_tg6(struct sk_buff *skb, const struct net_device *in,
must return an absolute verdict. --RR */
switch (reject->with) {
case IP6T_ICMP6_NO_ROUTE:
send_unreach(skb, ICMPV6_NOROUTE, hooknum);
send_unreach(net, skb, ICMPV6_NOROUTE, par->hooknum);
break;
case IP6T_ICMP6_ADM_PROHIBITED:
send_unreach(skb, ICMPV6_ADM_PROHIBITED, hooknum);
send_unreach(net, skb, ICMPV6_ADM_PROHIBITED, par->hooknum);
break;
case IP6T_ICMP6_NOT_NEIGHBOUR:
send_unreach(skb, ICMPV6_NOT_NEIGHBOUR, hooknum);
send_unreach(net, skb, ICMPV6_NOT_NEIGHBOUR, par->hooknum);
break;
case IP6T_ICMP6_ADDR_UNREACH:
send_unreach(skb, ICMPV6_ADDR_UNREACH, hooknum);
send_unreach(net, skb, ICMPV6_ADDR_UNREACH, par->hooknum);
break;
case IP6T_ICMP6_PORT_UNREACH:
send_unreach(skb, ICMPV6_PORT_UNREACH, hooknum);
send_unreach(net, skb, ICMPV6_PORT_UNREACH, par->hooknum);
break;
case IP6T_ICMP6_ECHOREPLY:
/* Do nothing */
break;
case IP6T_TCP_RESET:
send_reset(skb);
send_reset(net, skb);
break;
default:
if (net_ratelimit())
@ -213,13 +213,10 @@ reject_tg6(struct sk_buff *skb, const struct net_device *in,
return NF_DROP;
}
static bool
reject_tg6_check(const char *tablename, const void *entry,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
static bool reject_tg6_check(const struct xt_tgchk_param *par)
{
const struct ip6t_reject_info *rejinfo = targinfo;
const struct ip6t_entry *e = entry;
const struct ip6t_reject_info *rejinfo = par->targinfo;
const struct ip6t_entry *e = par->entryinfo;
if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
@ -237,7 +234,7 @@ reject_tg6_check(const char *tablename, const void *entry,
static struct xt_target reject_tg6_reg __read_mostly = {
.name = "REJECT",
.family = AF_INET6,
.family = NFPROTO_IPV6,
.target = reject_tg6,
.targetsize = sizeof(struct ip6t_reject_info),
.table = "filter",

View File

@ -36,14 +36,11 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
return r;
}
static bool
ah_mt6(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
{
struct ip_auth_hdr _ah;
const struct ip_auth_hdr *ah;
const struct ip6t_ah *ahinfo = matchinfo;
const struct ip6t_ah *ahinfo = par->matchinfo;
unsigned int ptr;
unsigned int hdrlen = 0;
int err;
@ -51,13 +48,13 @@ ah_mt6(const struct sk_buff *skb, const struct net_device *in,
err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
if (err < 0) {
if (err != -ENOENT)
*hotdrop = true;
*par->hotdrop = true;
return false;
}
ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
if (ah == NULL) {
*hotdrop = true;
*par->hotdrop = true;
return false;
}
@ -93,13 +90,9 @@ ah_mt6(const struct sk_buff *skb, const struct net_device *in,
!(ahinfo->hdrres && ah->reserved);
}
/* Called when user tries to insert an entry of this type. */
static bool
ah_mt6_check(const char *tablename, const void *entry,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
static bool ah_mt6_check(const struct xt_mtchk_param *par)
{
const struct ip6t_ah *ahinfo = matchinfo;
const struct ip6t_ah *ahinfo = par->matchinfo;
if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
@ -110,7 +103,7 @@ ah_mt6_check(const char *tablename, const void *entry,
static struct xt_match ah_mt6_reg __read_mostly = {
.name = "ah",
.family = AF_INET6,
.family = NFPROTO_IPV6,
.match = ah_mt6,
.matchsize = sizeof(struct ip6t_ah),
.checkentry = ah_mt6_check,

View File

@ -20,18 +20,15 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
static bool
eui64_mt6(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff,
bool *hotdrop)
eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
{
unsigned char eui64[8];
int i = 0;
if (!(skb_mac_header(skb) >= skb->head &&
skb_mac_header(skb) + ETH_HLEN <= skb->data) &&
offset != 0) {
*hotdrop = true;
par->fragoff != 0) {
*par->hotdrop = true;
return false;
}
@ -60,7 +57,7 @@ eui64_mt6(const struct sk_buff *skb, const struct net_device *in,
static struct xt_match eui64_mt6_reg __read_mostly = {
.name = "eui64",
.family = AF_INET6,
.family = NFPROTO_IPV6,
.match = eui64_mt6,
.matchsize = sizeof(int),
.hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) |

View File

@ -35,27 +35,24 @@ id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
}
static bool
frag_mt6(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff,
bool *hotdrop)
frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
{
struct frag_hdr _frag;
const struct frag_hdr *fh;
const struct ip6t_frag *fraginfo = matchinfo;
const struct ip6t_frag *fraginfo = par->matchinfo;
unsigned int ptr;
int err;
err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
if (err < 0) {
if (err != -ENOENT)
*hotdrop = true;
*par->hotdrop = true;
return false;
}
fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
if (fh == NULL) {
*hotdrop = true;
*par->hotdrop = true;
return false;
}
@ -110,13 +107,9 @@ frag_mt6(const struct sk_buff *skb, const struct net_device *in,
&& (ntohs(fh->frag_off) & IP6_MF));
}
/* Called when user tries to insert an entry of this type. */
static bool
frag_mt6_check(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
static bool frag_mt6_check(const struct xt_mtchk_param *par)
{
const struct ip6t_frag *fraginfo = matchinfo;
const struct ip6t_frag *fraginfo = par->matchinfo;
if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
@ -127,7 +120,7 @@ frag_mt6_check(const char *tablename, const void *ip,
static struct xt_match frag_mt6_reg __read_mostly = {
.name = "frag",
.family = AF_INET6,
.family = NFPROTO_IPV6,
.match = frag_mt6,
.matchsize = sizeof(struct ip6t_frag),
.checkentry = frag_mt6_check,

View File

@ -42,14 +42,11 @@ MODULE_ALIAS("ip6t_dst");
*/
static bool
hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff,
bool *hotdrop)
hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
{
struct ipv6_opt_hdr _optsh;
const struct ipv6_opt_hdr *oh;
const struct ip6t_opts *optinfo = matchinfo;
const struct ip6t_opts *optinfo = par->matchinfo;
unsigned int temp;
unsigned int ptr;
unsigned int hdrlen = 0;
@ -61,16 +58,16 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
unsigned int optlen;
int err;
err = ipv6_find_hdr(skb, &ptr, match->data, NULL);
err = ipv6_find_hdr(skb, &ptr, par->match->data, NULL);
if (err < 0) {
if (err != -ENOENT)
*hotdrop = true;
*par->hotdrop = true;
return false;
}
oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
if (oh == NULL) {
*hotdrop = true;
*par->hotdrop = true;
return false;
}
@ -163,13 +160,9 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
return false;
}
/* Called when user tries to insert an entry of this type. */
static bool
hbh_mt6_check(const char *tablename, const void *entry,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
static bool hbh_mt6_check(const struct xt_mtchk_param *par)
{
const struct ip6t_opts *optsinfo = matchinfo;
const struct ip6t_opts *optsinfo = par->matchinfo;
if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
@ -187,7 +180,7 @@ hbh_mt6_check(const char *tablename, const void *entry,
static struct xt_match hbh_mt6_reg[] __read_mostly = {
{
.name = "hbh",
.family = AF_INET6,
.family = NFPROTO_IPV6,
.match = hbh_mt6,
.matchsize = sizeof(struct ip6t_opts),
.checkentry = hbh_mt6_check,
@ -196,7 +189,7 @@ static struct xt_match hbh_mt6_reg[] __read_mostly = {
},
{
.name = "dst",
.family = AF_INET6,
.family = NFPROTO_IPV6,
.match = hbh_mt6,
.matchsize = sizeof(struct ip6t_opts),
.checkentry = hbh_mt6_check,

View File

@ -19,12 +19,9 @@ MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match");
MODULE_LICENSE("GPL");
static bool
hl_mt6(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
static bool hl_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ip6t_hl_info *info = matchinfo;
const struct ip6t_hl_info *info = par->matchinfo;
const struct ipv6hdr *ip6h = ipv6_hdr(skb);
switch (info->mode) {
@ -51,7 +48,7 @@ hl_mt6(const struct sk_buff *skb, const struct net_device *in,
static struct xt_match hl_mt6_reg __read_mostly = {
.name = "hl",
.family = AF_INET6,
.family = NFPROTO_IPV6,
.match = hl_mt6,
.matchsize = sizeof(struct ip6t_hl_info),
.me = THIS_MODULE,

View File

@ -27,12 +27,9 @@ MODULE_DESCRIPTION("Xtables: IPv6 header types match");
MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
static bool
ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff,
bool *hotdrop)
ipv6header_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
{
const struct ip6t_ipv6header_info *info = matchinfo;
const struct ip6t_ipv6header_info *info = par->matchinfo;
unsigned int temp;
int len;
u8 nexthdr;
@ -121,12 +118,9 @@ ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in,
}
}
static bool
ipv6header_mt6_check(const char *tablename, const void *ip,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
static bool ipv6header_mt6_check(const struct xt_mtchk_param *par)
{
const struct ip6t_ipv6header_info *info = matchinfo;
const struct ip6t_ipv6header_info *info = par->matchinfo;
/* invflags is 0 or 0xff in hard mode */
if ((!info->modeflag) && info->invflags != 0x00 &&
@ -138,7 +132,7 @@ ipv6header_mt6_check(const char *tablename, const void *ip,
static struct xt_match ipv6header_mt6_reg __read_mostly = {
.name = "ipv6header",
.family = AF_INET6,
.family = NFPROTO_IPV6,
.match = ipv6header_mt6,
.matchsize = sizeof(struct ip6t_ipv6header_info),
.checkentry = ipv6header_mt6_check,

View File

@ -37,32 +37,29 @@ type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
return (type >= min && type <= max) ^ invert;
}
static bool
mh_mt6(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
{
struct ip6_mh _mh;
const struct ip6_mh *mh;
const struct ip6t_mh *mhinfo = matchinfo;
const struct ip6t_mh *mhinfo = par->matchinfo;
/* Must not be a fragment. */
if (offset)
if (par->fragoff != 0)
return false;
mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh);
mh = skb_header_pointer(skb, par->thoff, sizeof(_mh), &_mh);
if (mh == NULL) {
/* We've been asked to examine this packet, and we
can't. Hence, no choice but to drop. */
duprintf("Dropping evil MH tinygram.\n");
*hotdrop = true;
*par->hotdrop = true;
return false;
}
if (mh->ip6mh_proto != IPPROTO_NONE) {
duprintf("Dropping invalid MH Payload Proto: %u\n",
mh->ip6mh_proto);
*hotdrop = true;
*par->hotdrop = true;
return false;
}
@ -70,13 +67,9 @@ mh_mt6(const struct sk_buff *skb, const struct net_device *in,
!!(mhinfo->invflags & IP6T_MH_INV_TYPE));
}
/* Called when user tries to insert an entry of this type. */
static bool
mh_mt6_check(const char *tablename, const void *entry,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
static bool mh_mt6_check(const struct xt_mtchk_param *par)
{
const struct ip6t_mh *mhinfo = matchinfo;
const struct ip6t_mh *mhinfo = par->matchinfo;
/* Must specify no unknown invflags */
return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
@ -84,7 +77,7 @@ mh_mt6_check(const char *tablename, const void *entry,
static struct xt_match mh_mt6_reg __read_mostly = {
.name = "mh",
.family = AF_INET6,
.family = NFPROTO_IPV6,
.checkentry = mh_mt6_check,
.match = mh_mt6,
.matchsize = sizeof(struct ip6t_mh),

View File

@ -36,14 +36,11 @@ segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
return r;
}
static bool
rt_mt6(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
{
struct ipv6_rt_hdr _route;
const struct ipv6_rt_hdr *rh;
const struct ip6t_rt *rtinfo = matchinfo;
const struct ip6t_rt *rtinfo = par->matchinfo;
unsigned int temp;
unsigned int ptr;
unsigned int hdrlen = 0;
@ -55,13 +52,13 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in,
err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
if (err < 0) {
if (err != -ENOENT)
*hotdrop = true;
*par->hotdrop = true;
return false;
}
rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
if (rh == NULL) {
*hotdrop = true;
*par->hotdrop = true;
return false;
}
@ -189,13 +186,9 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in,
return false;
}
/* Called when user tries to insert an entry of this type. */
static bool
rt_mt6_check(const char *tablename, const void *entry,
const struct xt_match *match, void *matchinfo,
unsigned int hook_mask)
static bool rt_mt6_check(const struct xt_mtchk_param *par)
{
const struct ip6t_rt *rtinfo = matchinfo;
const struct ip6t_rt *rtinfo = par->matchinfo;
if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
@ -214,7 +207,7 @@ rt_mt6_check(const char *tablename, const void *entry,
static struct xt_match rt_mt6_reg __read_mostly = {
.name = "rt",
.family = AF_INET6,
.family = NFPROTO_IPV6,
.match = rt_mt6,
.matchsize = sizeof(struct ip6t_rt),
.checkentry = rt_mt6_check,

View File

@ -68,7 +68,7 @@ ip6t_local_in_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out,
nf_local_in_net(in, out)->ipv6.ip6table_filter);
dev_net(in)->ipv6.ip6table_filter);
}
static unsigned int
@ -79,7 +79,7 @@ ip6t_forward_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out,
nf_forward_net(in, out)->ipv6.ip6table_filter);
dev_net(in)->ipv6.ip6table_filter);
}
static unsigned int
@ -100,7 +100,7 @@ ip6t_local_out_hook(unsigned int hook,
#endif
return ip6t_do_table(skb, hook, in, out,
nf_local_out_net(in, out)->ipv6.ip6table_filter);
dev_net(out)->ipv6.ip6table_filter);
}
static struct nf_hook_ops ip6t_ops[] __read_mostly = {

View File

@ -67,17 +67,29 @@ static struct xt_table packet_mangler = {
/* The work comes in here from netfilter.c. */
static unsigned int
ip6t_route_hook(unsigned int hook,
ip6t_in_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle);
return ip6t_do_table(skb, hook, in, out,
dev_net(in)->ipv6.ip6table_mangle);
}
static unsigned int
ip6t_local_hook(unsigned int hook,
ip6t_post_routing_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out,
dev_net(out)->ipv6.ip6table_mangle);
}
static unsigned int
ip6t_local_out_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
@ -108,7 +120,8 @@ ip6t_local_hook(unsigned int hook,
/* flowlabel and prio (includes version, which shouldn't change either */
flowlabel = *((u_int32_t *)ipv6_hdr(skb));
ret = ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle);
ret = ip6t_do_table(skb, hook, in, out,
dev_net(out)->ipv6.ip6table_mangle);
if (ret != NF_DROP && ret != NF_STOLEN
&& (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr))
@ -122,35 +135,35 @@ ip6t_local_hook(unsigned int hook,
static struct nf_hook_ops ip6t_ops[] __read_mostly = {
{
.hook = ip6t_route_hook,
.hook = ip6t_in_hook,
.owner = THIS_MODULE,
.pf = PF_INET6,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_MANGLE,
},
{
.hook = ip6t_route_hook,
.hook = ip6t_in_hook,
.owner = THIS_MODULE,
.pf = PF_INET6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_MANGLE,
},
{
.hook = ip6t_route_hook,
.hook = ip6t_in_hook,
.owner = THIS_MODULE,
.pf = PF_INET6,
.hooknum = NF_INET_FORWARD,
.priority = NF_IP6_PRI_MANGLE,
},
{
.hook = ip6t_local_hook,
.hook = ip6t_local_out_hook,
.owner = THIS_MODULE,
.pf = PF_INET6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_MANGLE,
},
{
.hook = ip6t_route_hook,
.hook = ip6t_post_routing_hook,
.owner = THIS_MODULE,
.pf = PF_INET6,
.hooknum = NF_INET_POST_ROUTING,

View File

@ -45,25 +45,37 @@ static struct xt_table packet_raw = {
/* The work comes in here from netfilter.c. */
static unsigned int
ip6t_hook(unsigned int hook,
ip6t_pre_routing_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_raw);
return ip6t_do_table(skb, hook, in, out,
dev_net(in)->ipv6.ip6table_raw);
}
static unsigned int
ip6t_local_out_hook(unsigned int hook,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out,
dev_net(out)->ipv6.ip6table_raw);
}
static struct nf_hook_ops ip6t_ops[] __read_mostly = {
{
.hook = ip6t_hook,
.hook = ip6t_pre_routing_hook,
.pf = PF_INET6,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_FIRST,
.owner = THIS_MODULE,
},
{
.hook = ip6t_hook,
.hook = ip6t_local_out_hook,
.pf = PF_INET6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_FIRST,

View File

@ -72,7 +72,7 @@ ip6t_local_in_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out,
nf_local_in_net(in, out)->ipv6.ip6table_security);
dev_net(in)->ipv6.ip6table_security);
}
static unsigned int
@ -83,7 +83,7 @@ ip6t_forward_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
return ip6t_do_table(skb, hook, in, out,
nf_forward_net(in, out)->ipv6.ip6table_security);
dev_net(in)->ipv6.ip6table_security);
}
static unsigned int
@ -95,7 +95,7 @@ ip6t_local_out_hook(unsigned int hook,
{
/* TBD: handle short packets via raw socket */
return ip6t_do_table(skb, hook, in, out,
nf_local_out_net(in, out)->ipv6.ip6table_security);
dev_net(out)->ipv6.ip6table_security);
}
static struct nf_hook_ops ip6t_ops[] __read_mostly = {

View File

@ -211,11 +211,10 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
return NF_STOLEN;
}
static unsigned int ipv6_conntrack_in(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
static unsigned int __ipv6_conntrack_in(struct net *net,
unsigned int hooknum,
struct sk_buff *skb,
int (*okfn)(struct sk_buff *))
{
struct sk_buff *reasm = skb->nfct_reasm;
@ -225,7 +224,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
if (!reasm->nfct) {
unsigned int ret;
ret = nf_conntrack_in(PF_INET6, hooknum, reasm);
ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm);
if (ret != NF_ACCEPT)
return ret;
}
@ -235,7 +234,16 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
return NF_ACCEPT;
}
return nf_conntrack_in(PF_INET6, hooknum, skb);
return nf_conntrack_in(net, PF_INET6, hooknum, skb);
}
static unsigned int ipv6_conntrack_in(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn);
}
static unsigned int ipv6_conntrack_local(unsigned int hooknum,
@ -250,7 +258,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
printk("ipv6_conntrack_local: packet too short\n");
return NF_ACCEPT;
}
return ipv6_conntrack_in(hooknum, skb, in, out, okfn);
return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn);
}
static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {

View File

@ -81,7 +81,7 @@ static int icmpv6_packet(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
int pf,
u_int8_t pf,
unsigned int hooknum)
{
/* Try to delete connection immediately after all replies:
@ -93,7 +93,7 @@ static int icmpv6_packet(struct nf_conn *ct,
nf_ct_kill_acct(ct, ctinfo, skb);
} else {
atomic_inc(&ct->proto.icmp.count);
nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
}
@ -122,7 +122,8 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
}
static int
icmpv6_error_message(struct sk_buff *skb,
icmpv6_error_message(struct net *net,
struct sk_buff *skb,
unsigned int icmp6off,
enum ip_conntrack_info *ctinfo,
unsigned int hooknum)
@ -156,7 +157,7 @@ icmpv6_error_message(struct sk_buff *skb,
*ctinfo = IP_CT_RELATED;
h = nf_conntrack_find_get(&intuple);
h = nf_conntrack_find_get(net, &intuple);
if (!h) {
pr_debug("icmpv6_error: no match\n");
return -NF_ACCEPT;
@ -172,21 +173,21 @@ icmpv6_error_message(struct sk_buff *skb,
}
static int
icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum)
icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
{
const struct icmp6hdr *icmp6h;
struct icmp6hdr _ih;
icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
if (icmp6h == NULL) {
if (LOG_INVALID(IPPROTO_ICMPV6))
if (LOG_INVALID(net, IPPROTO_ICMPV6))
nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
"nf_ct_icmpv6: short packet ");
return -NF_ACCEPT;
}
if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) {
nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
"nf_ct_icmpv6: ICMPv6 checksum failed\n");
@ -197,7 +198,7 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
if (icmp6h->icmp6_type >= 128)
return NF_ACCEPT;
return icmpv6_error_message(skb, dataoff, ctinfo, hooknum);
return icmpv6_error_message(net, skb, dataoff, ctinfo, hooknum);
}
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)

View File

@ -38,10 +38,11 @@ config NF_CONNTRACK
To compile it as a module, choose M here. If unsure, say N.
if NF_CONNTRACK
config NF_CT_ACCT
bool "Connection tracking flow accounting"
depends on NETFILTER_ADVANCED
depends on NF_CONNTRACK
help
If this option is enabled, the connection tracking code will
keep per-flow packet and byte counters.
@ -63,7 +64,6 @@ config NF_CT_ACCT
config NF_CONNTRACK_MARK
bool 'Connection mark tracking support'
depends on NETFILTER_ADVANCED
depends on NF_CONNTRACK
help
This option enables support for connection marks, used by the
`CONNMARK' target and `connmark' match. Similar to the mark value
@ -72,7 +72,7 @@ config NF_CONNTRACK_MARK
config NF_CONNTRACK_SECMARK
bool 'Connection tracking security mark support'
depends on NF_CONNTRACK && NETWORK_SECMARK
depends on NETWORK_SECMARK
default m if NETFILTER_ADVANCED=n
help
This option enables security markings to be applied to
@ -85,7 +85,6 @@ config NF_CONNTRACK_SECMARK
config NF_CONNTRACK_EVENTS
bool "Connection tracking events"
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
help
If this option is enabled, the connection tracking code will
@ -96,7 +95,7 @@ config NF_CONNTRACK_EVENTS
config NF_CT_PROTO_DCCP
tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)'
depends on EXPERIMENTAL && NF_CONNTRACK
depends on EXPERIMENTAL
depends on NETFILTER_ADVANCED
default IP_DCCP
help
@ -107,11 +106,10 @@ config NF_CT_PROTO_DCCP
config NF_CT_PROTO_GRE
tristate
depends on NF_CONNTRACK
config NF_CT_PROTO_SCTP
tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
depends on EXPERIMENTAL && NF_CONNTRACK
depends on EXPERIMENTAL
depends on NETFILTER_ADVANCED
default IP_SCTP
help
@ -123,7 +121,6 @@ config NF_CT_PROTO_SCTP
config NF_CT_PROTO_UDPLITE
tristate 'UDP-Lite protocol connection tracking support'
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
help
With this option enabled, the layer 3 independent connection
@ -134,7 +131,6 @@ config NF_CT_PROTO_UDPLITE
config NF_CONNTRACK_AMANDA
tristate "Amanda backup protocol support"
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
select TEXTSEARCH
select TEXTSEARCH_KMP
@ -150,7 +146,6 @@ config NF_CONNTRACK_AMANDA
config NF_CONNTRACK_FTP
tristate "FTP protocol support"
depends on NF_CONNTRACK
default m if NETFILTER_ADVANCED=n
help
Tracking FTP connections is problematic: special helpers are
@ -165,7 +160,7 @@ config NF_CONNTRACK_FTP
config NF_CONNTRACK_H323
tristate "H.323 protocol support"
depends on NF_CONNTRACK && (IPV6 || IPV6=n)
depends on (IPV6 || IPV6=n)
depends on NETFILTER_ADVANCED
help
H.323 is a VoIP signalling protocol from ITU-T. As one of the most
@ -185,7 +180,6 @@ config NF_CONNTRACK_H323
config NF_CONNTRACK_IRC
tristate "IRC protocol support"
depends on NF_CONNTRACK
default m if NETFILTER_ADVANCED=n
help
There is a commonly-used extension to IRC called
@ -201,7 +195,6 @@ config NF_CONNTRACK_IRC
config NF_CONNTRACK_NETBIOS_NS
tristate "NetBIOS name service protocol support"
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
help
NetBIOS name service requests are sent as broadcast messages from an
@ -221,7 +214,6 @@ config NF_CONNTRACK_NETBIOS_NS
config NF_CONNTRACK_PPTP
tristate "PPtP protocol support"
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
select NF_CT_PROTO_GRE
help
@ -241,7 +233,7 @@ config NF_CONNTRACK_PPTP
config NF_CONNTRACK_SANE
tristate "SANE protocol support (EXPERIMENTAL)"
depends on EXPERIMENTAL && NF_CONNTRACK
depends on EXPERIMENTAL
depends on NETFILTER_ADVANCED
help
SANE is a protocol for remote access to scanners as implemented
@ -255,7 +247,6 @@ config NF_CONNTRACK_SANE
config NF_CONNTRACK_SIP
tristate "SIP protocol support"
depends on NF_CONNTRACK
default m if NETFILTER_ADVANCED=n
help
SIP is an application-layer control protocol that can establish,
@ -268,7 +259,6 @@ config NF_CONNTRACK_SIP
config NF_CONNTRACK_TFTP
tristate "TFTP protocol support"
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
help
TFTP connection tracking helper, this is required depending
@ -280,13 +270,29 @@ config NF_CONNTRACK_TFTP
config NF_CT_NETLINK
tristate 'Connection tracking netlink interface'
depends on NF_CONNTRACK
select NETFILTER_NETLINK
depends on NF_NAT=n || NF_NAT
default m if NETFILTER_ADVANCED=n
help
This option enables support for a netlink-based userspace interface
# transparent proxy support
config NETFILTER_TPROXY
tristate "Transparent proxying support (EXPERIMENTAL)"
depends on EXPERIMENTAL
depends on IP_NF_MANGLE
depends on NETFILTER_ADVANCED
help
This option enables transparent proxying support, that is,
support for handling non-locally bound IPv4 TCP and UDP sockets.
For it to work you will have to configure certain iptables rules
and use policy routing. For more information on how to set it up
see Documentation/networking/tproxy.txt.
To compile it as a module, choose M here. If unsure, say N.
endif # NF_CONNTRACK
config NETFILTER_XTABLES
tristate "Netfilter Xtables support (required for ip_tables)"
default m if NETFILTER_ADVANCED=n
@ -294,11 +300,12 @@ config NETFILTER_XTABLES
This is required if you intend to use any of ip_tables,
ip6_tables or arp_tables.
if NETFILTER_XTABLES
# alphabetically ordered list of targets
config NETFILTER_XT_TARGET_CLASSIFY
tristate '"CLASSIFY" target support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
This option adds a `CLASSIFY' target, which enables the user to set
@ -311,8 +318,6 @@ config NETFILTER_XT_TARGET_CLASSIFY
config NETFILTER_XT_TARGET_CONNMARK
tristate '"CONNMARK" target support'
depends on NETFILTER_XTABLES
depends on IP_NF_MANGLE || IP6_NF_MANGLE
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
select NF_CONNTRACK_MARK
@ -325,9 +330,20 @@ config NETFILTER_XT_TARGET_CONNMARK
<file:Documentation/kbuild/modules.txt>. The module will be called
ipt_CONNMARK.ko. If unsure, say `N'.
config NETFILTER_XT_TARGET_CONNSECMARK
tristate '"CONNSECMARK" target support'
depends on NF_CONNTRACK && NF_CONNTRACK_SECMARK
default m if NETFILTER_ADVANCED=n
help
The CONNSECMARK target copies security markings from packets
to connections, and restores security markings from connections
to packets (if the packets are not already marked). This would
normally be used in conjunction with the SECMARK target.
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_TARGET_DSCP
tristate '"DSCP" and "TOS" target support'
depends on NETFILTER_XTABLES
depends on IP_NF_MANGLE || IP6_NF_MANGLE
depends on NETFILTER_ADVANCED
help
@ -344,7 +360,6 @@ config NETFILTER_XT_TARGET_DSCP
config NETFILTER_XT_TARGET_MARK
tristate '"MARK" target support'
depends on NETFILTER_XTABLES
default m if NETFILTER_ADVANCED=n
help
This option adds a `MARK' target, which allows you to create rules
@ -356,21 +371,8 @@ config NETFILTER_XT_TARGET_MARK
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_TARGET_NFQUEUE
tristate '"NFQUEUE" target Support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
This target replaced the old obsolete QUEUE target.
As opposed to QUEUE, it supports 65535 different queues,
not just one.
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_TARGET_NFLOG
tristate '"NFLOG" target support'
depends on NETFILTER_XTABLES
default m if NETFILTER_ADVANCED=n
help
This option enables the NFLOG target, which allows to LOG
@ -380,9 +382,19 @@ config NETFILTER_XT_TARGET_NFLOG
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_TARGET_NFQUEUE
tristate '"NFQUEUE" target Support'
depends on NETFILTER_ADVANCED
help
This target replaced the old obsolete QUEUE target.
As opposed to QUEUE, it supports 65535 different queues,
not just one.
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_TARGET_NOTRACK
tristate '"NOTRACK" target support'
depends on NETFILTER_XTABLES
depends on IP_NF_RAW || IP6_NF_RAW
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
@ -397,7 +409,6 @@ config NETFILTER_XT_TARGET_NOTRACK
config NETFILTER_XT_TARGET_RATEEST
tristate '"RATEEST" target support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
This option adds a `RATEEST' target, which allows to measure
@ -406,9 +417,23 @@ config NETFILTER_XT_TARGET_RATEEST
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_TARGET_TPROXY
tristate '"TPROXY" target support (EXPERIMENTAL)'
depends on EXPERIMENTAL
depends on NETFILTER_TPROXY
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
select NF_DEFRAG_IPV4
help
This option adds a `TPROXY' target, which is somewhat similar to
REDIRECT. It can only be used in the mangle table and is useful
to redirect traffic to a transparent proxy. It does _not_ depend
on Netfilter connection tracking and NAT, unlike REDIRECT.
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_TARGET_TRACE
tristate '"TRACE" target support'
depends on NETFILTER_XTABLES
depends on IP_NF_RAW || IP6_NF_RAW
depends on NETFILTER_ADVANCED
help
@ -421,7 +446,7 @@ config NETFILTER_XT_TARGET_TRACE
config NETFILTER_XT_TARGET_SECMARK
tristate '"SECMARK" target support'
depends on NETFILTER_XTABLES && NETWORK_SECMARK
depends on NETWORK_SECMARK
default m if NETFILTER_ADVANCED=n
help
The SECMARK target allows security marking of network
@ -429,21 +454,9 @@ config NETFILTER_XT_TARGET_SECMARK
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_TARGET_CONNSECMARK
tristate '"CONNSECMARK" target support'
depends on NETFILTER_XTABLES && NF_CONNTRACK && NF_CONNTRACK_SECMARK
default m if NETFILTER_ADVANCED=n
help
The CONNSECMARK target copies security markings from packets
to connections, and restores security markings from connections
to packets (if the packets are not already marked). This would
normally be used in conjunction with the SECMARK target.
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_TARGET_TCPMSS
tristate '"TCPMSS" target support'
depends on NETFILTER_XTABLES && (IPV6 || IPV6=n)
depends on (IPV6 || IPV6=n)
default m if NETFILTER_ADVANCED=n
---help---
This option adds a `TCPMSS' target, which allows you to alter the
@ -470,7 +483,7 @@ config NETFILTER_XT_TARGET_TCPMSS
config NETFILTER_XT_TARGET_TCPOPTSTRIP
tristate '"TCPOPTSTRIP" target support (EXPERIMENTAL)'
depends on EXPERIMENTAL && NETFILTER_XTABLES
depends on EXPERIMENTAL
depends on IP_NF_MANGLE || IP6_NF_MANGLE
depends on NETFILTER_ADVANCED
help
@ -479,7 +492,6 @@ config NETFILTER_XT_TARGET_TCPOPTSTRIP
config NETFILTER_XT_MATCH_COMMENT
tristate '"comment" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
This option adds a `comment' dummy-match, which allows you to put
@ -490,7 +502,6 @@ config NETFILTER_XT_MATCH_COMMENT
config NETFILTER_XT_MATCH_CONNBYTES
tristate '"connbytes" per-connection counter match support'
depends on NETFILTER_XTABLES
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
select NF_CT_ACCT
@ -503,7 +514,6 @@ config NETFILTER_XT_MATCH_CONNBYTES
config NETFILTER_XT_MATCH_CONNLIMIT
tristate '"connlimit" match support"'
depends on NETFILTER_XTABLES
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
---help---
@ -512,7 +522,6 @@ config NETFILTER_XT_MATCH_CONNLIMIT
config NETFILTER_XT_MATCH_CONNMARK
tristate '"connmark" connection mark match support'
depends on NETFILTER_XTABLES
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
select NF_CONNTRACK_MARK
@ -526,7 +535,6 @@ config NETFILTER_XT_MATCH_CONNMARK
config NETFILTER_XT_MATCH_CONNTRACK
tristate '"conntrack" connection tracking match support'
depends on NETFILTER_XTABLES
depends on NF_CONNTRACK
default m if NETFILTER_ADVANCED=n
help
@ -540,7 +548,6 @@ config NETFILTER_XT_MATCH_CONNTRACK
config NETFILTER_XT_MATCH_DCCP
tristate '"dccp" protocol match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
default IP_DCCP
help
@ -553,7 +560,6 @@ config NETFILTER_XT_MATCH_DCCP
config NETFILTER_XT_MATCH_DSCP
tristate '"dscp" and "tos" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
This option adds a `DSCP' match, which allows you to match against
@ -569,7 +575,6 @@ config NETFILTER_XT_MATCH_DSCP
config NETFILTER_XT_MATCH_ESP
tristate '"esp" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
This match extension allows you to match a range of SPIs
@ -577,9 +582,23 @@ config NETFILTER_XT_MATCH_ESP
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_MATCH_HASHLIMIT
tristate '"hashlimit" match support'
depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
depends on NETFILTER_ADVANCED
help
This option adds a `hashlimit' match.
As opposed to `limit', this match dynamically creates a hash table
of limit buckets, based on your selection of source/destination
addresses and/or ports.
It enables you to express policies like `10kpps for any given
destination address' or `500pps from any given source address'
with a single rule.
config NETFILTER_XT_MATCH_HELPER
tristate '"helper" match support'
depends on NETFILTER_XTABLES
depends on NF_CONNTRACK
depends on NETFILTER_ADVANCED
help
@ -590,7 +609,6 @@ config NETFILTER_XT_MATCH_HELPER
config NETFILTER_XT_MATCH_IPRANGE
tristate '"iprange" address range match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
---help---
This option adds a "iprange" match, which allows you to match based on
@ -601,7 +619,6 @@ config NETFILTER_XT_MATCH_IPRANGE
config NETFILTER_XT_MATCH_LENGTH
tristate '"length" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
This option allows you to match the length of a packet against a
@ -611,7 +628,6 @@ config NETFILTER_XT_MATCH_LENGTH
config NETFILTER_XT_MATCH_LIMIT
tristate '"limit" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
limit matching allows you to control the rate at which a rule can be
@ -622,7 +638,6 @@ config NETFILTER_XT_MATCH_LIMIT
config NETFILTER_XT_MATCH_MAC
tristate '"mac" address match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
MAC matching allows you to match packets based on the source
@ -632,7 +647,6 @@ config NETFILTER_XT_MATCH_MAC
config NETFILTER_XT_MATCH_MARK
tristate '"mark" match support'
depends on NETFILTER_XTABLES
default m if NETFILTER_ADVANCED=n
help
Netfilter mark matching allows you to match packets based on the
@ -641,29 +655,8 @@ config NETFILTER_XT_MATCH_MARK
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_MATCH_OWNER
tristate '"owner" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
---help---
Socket owner matching allows you to match locally-generated packets
based on who created the socket: the user or group. It is also
possible to check whether a socket actually exists.
config NETFILTER_XT_MATCH_POLICY
tristate 'IPsec "policy" match support'
depends on NETFILTER_XTABLES && XFRM
default m if NETFILTER_ADVANCED=n
help
Policy matching allows you to match packets based on the
IPsec policy that was used during decapsulation/will
be used during encapsulation.
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_MATCH_MULTIPORT
tristate '"multiport" Multiple port match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
Multiport matching allows you to match TCP or UDP packets based on
@ -672,9 +665,28 @@ config NETFILTER_XT_MATCH_MULTIPORT
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_MATCH_OWNER
tristate '"owner" match support'
depends on NETFILTER_ADVANCED
---help---
Socket owner matching allows you to match locally-generated packets
based on who created the socket: the user or group. It is also
possible to check whether a socket actually exists.
config NETFILTER_XT_MATCH_POLICY
tristate 'IPsec "policy" match support'
depends on XFRM
default m if NETFILTER_ADVANCED=n
help
Policy matching allows you to match packets based on the
IPsec policy that was used during decapsulation/will
be used during encapsulation.
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_MATCH_PHYSDEV
tristate '"physdev" match support'
depends on NETFILTER_XTABLES && BRIDGE && BRIDGE_NETFILTER
depends on BRIDGE && BRIDGE_NETFILTER
depends on NETFILTER_ADVANCED
help
Physdev packet matching matches against the physical bridge ports
@ -684,7 +696,6 @@ config NETFILTER_XT_MATCH_PHYSDEV
config NETFILTER_XT_MATCH_PKTTYPE
tristate '"pkttype" packet type match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
Packet type matching allows you to match a packet by
@ -697,7 +708,6 @@ config NETFILTER_XT_MATCH_PKTTYPE
config NETFILTER_XT_MATCH_QUOTA
tristate '"quota" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
This option adds a `quota' match, which allows to match on a
@ -708,7 +718,6 @@ config NETFILTER_XT_MATCH_QUOTA
config NETFILTER_XT_MATCH_RATEEST
tristate '"rateest" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
select NETFILTER_XT_TARGET_RATEEST
help
@ -719,7 +728,6 @@ config NETFILTER_XT_MATCH_RATEEST
config NETFILTER_XT_MATCH_REALM
tristate '"realm" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
select NET_CLS_ROUTE
help
@ -732,9 +740,26 @@ config NETFILTER_XT_MATCH_REALM
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
config NETFILTER_XT_MATCH_RECENT
tristate '"recent" match support'
depends on NETFILTER_ADVANCED
---help---
This match is used for creating one or many lists of recently
used addresses and then matching against that/those list(s).
Short options are available by using 'iptables -m recent -h'
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
tristate '"sctp" protocol match support (EXPERIMENTAL)'
depends on NETFILTER_XTABLES && EXPERIMENTAL
depends on EXPERIMENTAL
depends on NETFILTER_ADVANCED
default IP_SCTP
help
@ -745,9 +770,23 @@ config NETFILTER_XT_MATCH_SCTP
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
config NETFILTER_XT_MATCH_SOCKET
tristate '"socket" match support (EXPERIMENTAL)'
depends on EXPERIMENTAL
depends on NETFILTER_TPROXY
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
select NF_DEFRAG_IPV4
help
This option adds a `socket' match, which can be used to match
packets for which a TCP or UDP socket lookup finds a valid socket.
It can be used in combination with the MARK target and policy
routing to implement full featured non-locally bound sockets.
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_MATCH_STATE
tristate '"state" match support'
depends on NETFILTER_XTABLES
depends on NF_CONNTRACK
default m if NETFILTER_ADVANCED=n
help
@ -759,7 +798,6 @@ config NETFILTER_XT_MATCH_STATE
config NETFILTER_XT_MATCH_STATISTIC
tristate '"statistic" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
This option adds a `statistic' match, which allows you to match
@ -769,7 +807,6 @@ config NETFILTER_XT_MATCH_STATISTIC
config NETFILTER_XT_MATCH_STRING
tristate '"string" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
select TEXTSEARCH
select TEXTSEARCH_KMP
@ -783,7 +820,6 @@ config NETFILTER_XT_MATCH_STRING
config NETFILTER_XT_MATCH_TCPMSS
tristate '"tcpmss" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
help
This option adds a `tcpmss' match, which allows you to examine the
@ -794,7 +830,6 @@ config NETFILTER_XT_MATCH_TCPMSS
config NETFILTER_XT_MATCH_TIME
tristate '"time" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
---help---
This option adds a "time" match, which allows you to match based on
@ -809,7 +844,6 @@ config NETFILTER_XT_MATCH_TIME
config NETFILTER_XT_MATCH_U32
tristate '"u32" match support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
---help---
u32 allows you to extract quantities of up to 4 bytes from a packet,
@ -821,20 +855,6 @@ config NETFILTER_XT_MATCH_U32
Details and examples are in the kernel module source.
config NETFILTER_XT_MATCH_HASHLIMIT
tristate '"hashlimit" match support'
depends on NETFILTER_XTABLES && (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
depends on NETFILTER_ADVANCED
help
This option adds a `hashlimit' match.
As opposed to `limit', this match dynamically creates a hash table
of limit buckets, based on your selection of source/destination
addresses and/or ports.
It enables you to express policies like `10kpps for any given
destination address' or `500pps from any given source address'
with a single rule.
endif # NETFILTER_XTABLES
endmenu

View File

@ -34,6 +34,9 @@ obj-$(CONFIG_NF_CONNTRACK_SANE) += nf_conntrack_sane.o
obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o
obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o
# transparent proxy support
obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
# generic X tables
obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
@ -48,6 +51,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o
obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
@ -76,7 +80,9 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o
obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) += xt_recent.o
obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o

View File

@ -26,7 +26,7 @@
static DEFINE_MUTEX(afinfo_mutex);
const struct nf_afinfo *nf_afinfo[NPROTO] __read_mostly;
const struct nf_afinfo *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly;
EXPORT_SYMBOL(nf_afinfo);
int nf_register_afinfo(const struct nf_afinfo *afinfo)
@ -51,7 +51,7 @@ void nf_unregister_afinfo(const struct nf_afinfo *afinfo)
}
EXPORT_SYMBOL_GPL(nf_unregister_afinfo);
struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS] __read_mostly;
struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly;
EXPORT_SYMBOL(nf_hooks);
static DEFINE_MUTEX(nf_hook_mutex);
@ -113,7 +113,7 @@ EXPORT_SYMBOL(nf_unregister_hooks);
unsigned int nf_iterate(struct list_head *head,
struct sk_buff *skb,
int hook,
unsigned int hook,
const struct net_device *indev,
const struct net_device *outdev,
struct list_head **i,
@ -155,7 +155,7 @@ unsigned int nf_iterate(struct list_head *head,
/* Returns 1 if okfn() needs to be executed by the caller,
* -EPERM for NF_DROP, 0 otherwise. */
int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
struct net_device *indev,
struct net_device *outdev,
int (*okfn)(struct sk_buff *),
@ -165,14 +165,6 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
unsigned int verdict;
int ret = 0;
#ifdef CONFIG_NET_NS
struct net *net;
net = indev == NULL ? dev_net(outdev) : dev_net(indev);
if (net != &init_net)
return 1;
#endif
/* We may already have this, but read-locks nest anyway */
rcu_read_lock();
@ -264,7 +256,7 @@ EXPORT_SYMBOL(proc_net_netfilter);
void __init netfilter_init(void)
{
int i, h;
for (i = 0; i < NPROTO; i++) {
for (i = 0; i < ARRAY_SIZE(nf_hooks); i++) {
for (h = 0; h < NF_MAX_HOOKS; h++)
INIT_LIST_HEAD(&nf_hooks[i][h]);
}

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