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:
commit
364ae953a4
@ -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>
|
||||
|
85
Documentation/networking/tproxy.txt
Normal file
85
Documentation/networking/tproxy.txt
Normal 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
|
@ -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*/
|
||||
|
@ -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
|
||||
|
@ -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__ */
|
||||
|
@ -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,
|
||||
|
14
include/linux/netfilter/xt_TPROXY.h
Normal file
14
include/linux/netfilter/xt_TPROXY.h
Normal 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 */
|
26
include/linux/netfilter/xt_recent.h
Normal file
26
include/linux/netfilter/xt_recent.h
Normal 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 */
|
@ -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)
|
||||
|
||||
|
@ -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*/
|
||||
|
@ -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;
|
||||
};
|
||||
|
6
include/net/netfilter/ipv4/nf_defrag_ipv4.h
Normal file
6
include/net/netfilter/ipv4/nf_defrag_ipv4.h
Normal 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 */
|
@ -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)
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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*/
|
||||
|
@ -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 *);
|
||||
|
@ -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*/
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
32
include/net/netfilter/nf_tproxy_core.h
Normal file
32
include/net/netfilter/nf_tproxy_core.h
Normal 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
|
30
include/net/netns/conntrack.h
Normal file
30
include/net/netns/conntrack.h
Normal 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
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 = {
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
},
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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 = {
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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 = {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
96
net/ipv4/netfilter/nf_defrag_ipv4.c
Normal file
96
net/ipv4/netfilter/nf_defrag_ipv4.c
Normal 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");
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) &&
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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) |
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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 = {
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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 = {
|
||||
|
@ -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 = {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user