Commit 364ae953 authored by David S. Miller's avatar David S. Miller
parents 075f6646 f39a9410
...@@ -250,6 +250,9 @@ What (Why): ...@@ -250,6 +250,9 @@ What (Why):
- xt_mark match revision 0 - xt_mark match revision 0
(superseded by xt_mark match revision 1) (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 When: January 2009 or Linux 2.7.0, whichever comes first
Why: Superseded by newer revisions or modules Why: Superseded by newer revisions or modules
Who: Jan Engelhardt <jengelh@computergmbh.de> Who: Jan Engelhardt <jengelh@computergmbh.de>
......
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 @@ ...@@ -5,13 +5,11 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/net.h> #include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/if.h> #include <linux/if.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/in6.h> #include <linux/in6.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/list.h> #include <linux/list.h>
#include <net/net_namespace.h>
#endif #endif
#include <linux/types.h> #include <linux/types.h>
#include <linux/compiler.h> #include <linux/compiler.h>
...@@ -52,6 +50,16 @@ enum nf_inet_hooks { ...@@ -52,6 +50,16 @@ enum nf_inet_hooks {
NF_INET_NUMHOOKS 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 { union nf_inet_addr {
__u32 all[4]; __u32 all[4];
__be32 ip; __be32 ip;
...@@ -92,8 +100,8 @@ struct nf_hook_ops ...@@ -92,8 +100,8 @@ struct nf_hook_ops
/* User fills in from here down. */ /* User fills in from here down. */
nf_hookfn *hook; nf_hookfn *hook;
struct module *owner; struct module *owner;
int pf; u_int8_t pf;
int hooknum; unsigned int hooknum;
/* Hooks are ordered in ascending priority. */ /* Hooks are ordered in ascending priority. */
int priority; int priority;
}; };
...@@ -102,7 +110,7 @@ struct nf_sockopt_ops ...@@ -102,7 +110,7 @@ struct nf_sockopt_ops
{ {
struct list_head list; struct list_head list;
int pf; u_int8_t pf;
/* Non-inclusive ranges: use 0/0/NULL to never get called. */ /* Non-inclusive ranges: use 0/0/NULL to never get called. */
int set_optmin; int set_optmin;
...@@ -138,9 +146,9 @@ extern struct ctl_path nf_net_netfilter_sysctl_path[]; ...@@ -138,9 +146,9 @@ extern struct ctl_path nf_net_netfilter_sysctl_path[];
extern struct ctl_path nf_net_ipv4_netfilter_sysctl_path[]; extern struct ctl_path nf_net_ipv4_netfilter_sysctl_path[];
#endif /* CONFIG_SYSCTL */ #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, struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sk_buff *), int thresh); int (*okfn)(struct sk_buff *), int thresh);
...@@ -151,7 +159,7 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, ...@@ -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 * okfn must be invoked by the caller in this case. Any other return
* value indicates the packet has been consumed by the hook. * 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 sk_buff *skb,
struct net_device *indev, struct net_device *indev,
struct net_device *outdev, struct net_device *outdev,
...@@ -167,7 +175,7 @@ static inline int nf_hook_thresh(int pf, unsigned int hook, ...@@ -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); 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, struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sk_buff *)) int (*okfn)(struct sk_buff *))
{ {
...@@ -212,14 +220,14 @@ __ret;}) ...@@ -212,14 +220,14 @@ __ret;})
NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN) NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN)
/* Call setsockopt() */ /* 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 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 *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); 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); char __user *opt, int *len);
/* Call this before modifying an existing packet: ensures it is /* Call this before modifying an existing packet: ensures it is
...@@ -247,7 +255,7 @@ struct nf_afinfo { ...@@ -247,7 +255,7 @@ struct nf_afinfo {
int route_key_size; 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) static inline const struct nf_afinfo *nf_get_afinfo(unsigned short family)
{ {
return rcu_dereference(nf_afinfo[family]); return rcu_dereference(nf_afinfo[family]);
...@@ -292,7 +300,7 @@ extern void nf_unregister_afinfo(const struct nf_afinfo *afinfo); ...@@ -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 *); extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
static inline void 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 #ifdef CONFIG_NF_NAT_NEEDED
void (*decodefn)(struct sk_buff *, struct flowi *); void (*decodefn)(struct sk_buff *, struct flowi *);
...@@ -315,7 +323,7 @@ extern struct proc_dir_entry *proc_net_netfilter; ...@@ -315,7 +323,7 @@ extern struct proc_dir_entry *proc_net_netfilter;
#else /* !CONFIG_NETFILTER */ #else /* !CONFIG_NETFILTER */
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (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 sk_buff *skb,
struct net_device *indev, struct net_device *indev,
struct net_device *outdev, struct net_device *outdev,
...@@ -324,7 +332,7 @@ static inline int nf_hook_thresh(int pf, unsigned int hook, ...@@ -324,7 +332,7 @@ static inline int nf_hook_thresh(int pf, unsigned int hook,
{ {
return okfn(skb); 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, struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sk_buff *)) int (*okfn)(struct sk_buff *))
{ {
...@@ -332,7 +340,9 @@ static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb, ...@@ -332,7 +340,9 @@ static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
} }
struct flowi; struct flowi;
static inline void 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*/ #endif /*CONFIG_NETFILTER*/
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
...@@ -343,56 +353,5 @@ extern void (*nf_ct_destroy)(struct nf_conntrack *); ...@@ -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) {} static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
#endif #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 /*__KERNEL__*/
#endif /*__LINUX_NETFILTER_H*/ #endif /*__LINUX_NETFILTER_H*/
...@@ -32,6 +32,7 @@ header-y += xt_owner.h ...@@ -32,6 +32,7 @@ header-y += xt_owner.h
header-y += xt_pkttype.h header-y += xt_pkttype.h
header-y += xt_rateest.h header-y += xt_rateest.h
header-y += xt_realm.h header-y += xt_realm.h
header-y += xt_recent.h
header-y += xt_sctp.h header-y += xt_sctp.h
header-y += xt_state.h header-y += xt_state.h
header-y += xt_statistic.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, ...@@ -87,7 +87,7 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
/* delete keymap entries */ /* delete keymap entries */
void nf_ct_gre_keymap_destroy(struct nf_conn *ct); 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); extern void nf_nat_need_gre(void);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -173,6 +173,98 @@ struct xt_counters_info ...@@ -173,6 +173,98 @@ struct xt_counters_info
#include <linux/netdevice.h> #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 xt_match
{ {
struct list_head list; struct list_head list;
...@@ -185,24 +277,13 @@ struct xt_match ...@@ -185,24 +277,13 @@ struct xt_match
non-linear skb, using skb_header_pointer and non-linear skb, using skb_header_pointer and
skb_ip_make_writable. */ skb_ip_make_writable. */
bool (*match)(const struct sk_buff *skb, bool (*match)(const struct sk_buff *skb,
const struct net_device *in, const struct xt_match_param *);
const struct net_device *out,
const struct xt_match *match,
const void *matchinfo,
int offset,
unsigned int protoff,
bool *hotdrop);
/* Called when user tries to insert an entry of this type. */ /* Called when user tries to insert an entry of this type. */
/* Should return true or false. */ bool (*checkentry)(const struct xt_mtchk_param *);
bool (*checkentry)(const char *tablename,
const void *ip,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask);
/* Called when entry of this type deleted. */ /* 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 */ /* Called when userspace align differs from kernel space one */
void (*compat_from_user)(void *dst, void *src); void (*compat_from_user)(void *dst, void *src);
...@@ -235,24 +316,16 @@ struct xt_target ...@@ -235,24 +316,16 @@ struct xt_target
must now handle non-linear skbs, using skb_copy_bits and must now handle non-linear skbs, using skb_copy_bits and
skb_ip_make_writable. */ skb_ip_make_writable. */
unsigned int (*target)(struct sk_buff *skb, unsigned int (*target)(struct sk_buff *skb,
const struct net_device *in, const struct xt_target_param *);
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo);
/* Called when user tries to insert an entry of this type: /* Called when user tries to insert an entry of this type:
hook_mask is a bitmask of hooks from which it can be hook_mask is a bitmask of hooks from which it can be
called. */ called. */
/* Should return true or false. */ /* Should return true or false. */
bool (*checkentry)(const char *tablename, bool (*checkentry)(const struct xt_tgchk_param *);
const void *entry,
const struct xt_target *target,
void *targinfo,
unsigned int hook_mask);
/* Called when entry of this type deleted. */ /* 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 */ /* Called when userspace align differs from kernel space one */
void (*compat_from_user)(void *dst, void *src); void (*compat_from_user)(void *dst, void *src);
...@@ -292,7 +365,7 @@ struct xt_table ...@@ -292,7 +365,7 @@ struct xt_table
/* Set this to THIS_MODULE if you are a module, otherwise NULL */ /* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me; struct module *me;
int af; /* address/protocol family */ u_int8_t af; /* address/protocol family */
}; };
#include <linux/netfilter_ipv4.h> #include <linux/netfilter_ipv4.h>
...@@ -328,12 +401,10 @@ extern void xt_unregister_match(struct xt_match *target); ...@@ -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 int xt_register_matches(struct xt_match *match, unsigned int n);
extern void xt_unregister_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, extern int xt_check_match(struct xt_mtchk_param *,
unsigned int size, const char *table, unsigned int hook, unsigned int size, u_int8_t proto, bool inv_proto);
unsigned short proto, int inv_proto); extern int xt_check_target(struct xt_tgchk_param *,
extern int xt_check_target(const struct xt_target *target, unsigned short family, unsigned int size, u_int8_t proto, bool inv_proto);
unsigned int size, const char *table, unsigned int hook,
unsigned short proto, int inv_proto);
extern struct xt_table *xt_register_table(struct net *net, extern struct xt_table *xt_register_table(struct net *net,
struct xt_table *table, struct xt_table *table,
...@@ -346,19 +417,19 @@ extern struct xt_table_info *xt_replace_table(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, struct xt_table_info *newinfo,
int *error); int *error);
extern struct xt_match *xt_find_match(int af, const char *name, u8 revision); extern struct xt_match *xt_find_match(u8 af, const char *name, u8 revision);
extern struct xt_target *xt_find_target(int 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(int af, const char *name, extern struct xt_target *xt_request_find_target(u8 af, const char *name,
u8 revision); u8 revision);
extern int xt_find_revision(int af, const char *name, u8 revision, int target, extern int xt_find_revision(u8 af, const char *name, u8 revision,
int *err); 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); const char *name);
extern void xt_table_unlock(struct xt_table *t); extern void xt_table_unlock(struct xt_table *t);
extern int xt_proto_init(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, int 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 struct xt_table_info *xt_alloc_table_info(unsigned int size);
extern void xt_free_table_info(struct xt_table_info *info); extern void xt_free_table_info(struct xt_table_info *info);
...@@ -423,12 +494,12 @@ struct compat_xt_counters_info ...@@ -423,12 +494,12 @@ struct compat_xt_counters_info
#define COMPAT_XT_ALIGN(s) (((s) + (__alignof__(struct compat_xt_counters)-1)) \ #define COMPAT_XT_ALIGN(s) (((s) + (__alignof__(struct compat_xt_counters)-1)) \
& ~(__alignof__(struct compat_xt_counters)-1)) & ~(__alignof__(struct compat_xt_counters)-1))
extern void xt_compat_lock(int af); extern void xt_compat_lock(u_int8_t af);
extern void xt_compat_unlock(int af); extern void xt_compat_unlock(u_int8_t af);
extern int xt_compat_add_offset(int af, unsigned int offset, short delta); extern int xt_compat_add_offset(u_int8_t af, unsigned int offset, short delta);
extern void xt_compat_flush_offsets(int af); extern void xt_compat_flush_offsets(u_int8_t af);
extern short xt_compat_calc_jump(int af, unsigned int offset); 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_offset(const struct xt_match *match);
extern int xt_compat_match_from_user(struct xt_entry_match *m, extern int xt_compat_match_from_user(struct xt_entry_match *m,
......
#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 */
#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 @@ ...@@ -31,6 +31,9 @@
* The 4 lsb are more than enough to store the verdict. */ * The 4 lsb are more than enough to store the verdict. */
#define EBT_VERDICT_BITS 0x0000000F #define EBT_VERDICT_BITS 0x0000000F
struct xt_match;
struct xt_target;
struct ebt_counter struct ebt_counter
{ {
uint64_t pcnt; uint64_t pcnt;
...@@ -121,7 +124,7 @@ struct ebt_entry_match ...@@ -121,7 +124,7 @@ struct ebt_entry_match
{ {
union { union {
char name[EBT_FUNCTION_MAXNAMELEN]; char name[EBT_FUNCTION_MAXNAMELEN];
struct ebt_match *match; struct xt_match *match;
} u; } u;
/* size of data */ /* size of data */
unsigned int match_size; unsigned int match_size;
...@@ -132,7 +135,7 @@ struct ebt_entry_watcher ...@@ -132,7 +135,7 @@ struct ebt_entry_watcher
{ {
union { union {
char name[EBT_FUNCTION_MAXNAMELEN]; char name[EBT_FUNCTION_MAXNAMELEN];
struct ebt_watcher *watcher; struct xt_target *watcher;
} u; } u;
/* size of data */ /* size of data */
unsigned int watcher_size; unsigned int watcher_size;
...@@ -143,7 +146,7 @@ struct ebt_entry_target ...@@ -143,7 +146,7 @@ struct ebt_entry_target
{ {
union { union {
char name[EBT_FUNCTION_MAXNAMELEN]; char name[EBT_FUNCTION_MAXNAMELEN];
struct ebt_target *target; struct xt_target *target;
} u; } u;
/* size of data */ /* size of data */
unsigned int target_size; unsigned int target_size;
...@@ -207,14 +210,17 @@ struct ebt_match ...@@ -207,14 +210,17 @@ struct ebt_match
{ {
struct list_head list; struct list_head list;
const char name[EBT_FUNCTION_MAXNAMELEN]; const char name[EBT_FUNCTION_MAXNAMELEN];
/* 0 == it matches */ bool (*match)(const struct sk_buff *skb, const struct net_device *in,
int (*match)(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const struct xt_match *match,
const struct net_device *out, const void *matchdata, const void *matchinfo, int offset, unsigned int protoff,
unsigned int datalen); bool *hotdrop);
/* 0 == let it in */ bool (*checkentry)(const char *table, const void *entry,
int (*check)(const char *tablename, unsigned int hookmask, const struct xt_match *match, void *matchinfo,
const struct ebt_entry *e, void *matchdata, unsigned int datalen); unsigned int hook_mask);
void (*destroy)(void *matchdata, unsigned int datalen); void (*destroy)(const struct xt_match *match, void *matchinfo);
unsigned int matchsize;
u_int8_t revision;
u_int8_t family;
struct module *me; struct module *me;
}; };
...@@ -222,13 +228,17 @@ struct ebt_watcher ...@@ -222,13 +228,17 @@ struct ebt_watcher
{ {
struct list_head list; struct list_head list;
const char name[EBT_FUNCTION_MAXNAMELEN]; const char name[EBT_FUNCTION_MAXNAMELEN];
void (*watcher)(const struct sk_buff *skb, unsigned int hooknr, unsigned int (*target)(struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out,
const void *watcherdata, unsigned int datalen); unsigned int hook_num, const struct xt_target *target,
/* 0 == let it in */ const void *targinfo);
int (*check)(const char *tablename, unsigned int hookmask, bool (*checkentry)(const char *table, const void *entry,
const struct ebt_entry *e, void *watcherdata, unsigned int datalen); const struct xt_target *target, void *targinfo,
void (*destroy)(void *watcherdata, unsigned int datalen); 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; struct module *me;
}; };
...@@ -236,14 +246,18 @@ struct ebt_target ...@@ -236,14 +246,18 @@ struct ebt_target
{ {
struct list_head list; struct list_head list;
const char name[EBT_FUNCTION_MAXNAMELEN]; const char name[EBT_FUNCTION_MAXNAMELEN];
/* returns one of the standard verdicts */ /* returns one of the standard EBT_* verdicts */
int (*target)(struct sk_buff *skb, unsigned int hooknr, unsigned int (*target)(struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out,
const void *targetdata, unsigned int datalen); unsigned int hook_num, const struct xt_target *target,
/* 0 == let it in */ const void *targinfo);
int (*check)(const char *tablename, unsigned int hookmask, bool (*checkentry)(const char *table, const void *entry,
const struct ebt_entry *e, void *targetdata, unsigned int datalen); const struct xt_target *target, void *targinfo,
void (*destroy)(void *targetdata, unsigned int datalen); 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; struct module *me;
}; };
...@@ -288,12 +302,6 @@ struct ebt_table ...@@ -288,12 +302,6 @@ struct ebt_table
~(__alignof__(struct ebt_replace)-1)) ~(__alignof__(struct ebt_replace)-1))
extern int ebt_register_table(struct ebt_table *table); extern int ebt_register_table(struct ebt_table *table);
extern void ebt_unregister_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, extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out,
struct ebt_table *table); struct ebt_table *table);
...@@ -302,9 +310,9 @@ extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb, ...@@ -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)) #define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg))
/* True if the hook mask denotes that the rule is in a base chain, /* True if the hook mask denotes that the rule is in a base chain,
* used in the check() functions */ * 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 */ /* 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 */ /* True if the target is not a standard target */
#define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0) #define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0)
......
#ifndef _IPT_RECENT_H #ifndef _IPT_RECENT_H
#define _IPT_RECENT_H #define _IPT_RECENT_H
#define RECENT_NAME "ipt_recent" #include <linux/netfilter/xt_recent.h>
#define RECENT_VER "v0.3.1"
#define IPT_RECENT_CHECK 1 #define ipt_recent_info xt_recent_mtinfo
#define IPT_RECENT_SET 2
#define IPT_RECENT_UPDATE 4
#define IPT_RECENT_REMOVE 8
#define IPT_RECENT_TTL 16
#define IPT_RECENT_SOURCE 0 enum {
#define IPT_RECENT_DEST 1 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 { IPT_RECENT_NAME_LEN = XT_RECENT_NAME_LEN,
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;
}; };
#endif /*_IPT_RECENT_H*/ #endif /*_IPT_RECENT_H*/
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
#include <net/netns/ipv6.h> #include <net/netns/ipv6.h>
#include <net/netns/dccp.h> #include <net/netns/dccp.h>
#include <net/netns/x_tables.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 proc_dir_entry;
struct net_device; struct net_device;
...@@ -67,6 +70,9 @@ struct net { ...@@ -67,6 +70,9 @@ struct net {
#endif #endif
#ifdef CONFIG_NETFILTER #ifdef CONFIG_NETFILTER
struct netns_xt xt; struct netns_xt xt;
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct netns_ct ct;
#endif
#endif #endif
struct net_generic *gen; struct net_generic *gen;
}; };
......
#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 ...@@ -123,7 +123,9 @@ struct nf_conn
/* Extensions */ /* Extensions */
struct nf_ct_ext *ext; struct nf_ct_ext *ext;
#ifdef CONFIG_NET_NS
struct net *ct_net;
#endif
struct rcu_head rcu; struct rcu_head rcu;
}; };
...@@ -147,6 +149,17 @@ static inline u_int8_t nf_ct_protonum(const struct nf_conn *ct) ...@@ -147,6 +149,17 @@ static inline u_int8_t nf_ct_protonum(const struct nf_conn *ct)
/* get master conntrack via master expectation */ /* get master conntrack via master expectation */
#define master_ct(conntr) (conntr->master) #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). */ /* Alter reply tuple (maybe alter helper). */
extern void extern void
nf_conntrack_alter_reply(struct nf_conn *ct, nf_conntrack_alter_reply(struct nf_conn *ct,
...@@ -182,11 +195,11 @@ extern void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, ...@@ -182,11 +195,11 @@ extern void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced,
unsigned int size); unsigned int size);
extern struct nf_conntrack_tuple_hash * 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_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, extern bool nf_ct_get_tuplepr(const struct sk_buff *skb,
unsigned int nhoff, u_int16_t l3num, unsigned int nhoff, u_int16_t l3num,
...@@ -248,10 +261,11 @@ extern struct nf_conn nf_conntrack_untracked; ...@@ -248,10 +261,11 @@ extern struct nf_conn nf_conntrack_untracked;
/* Iterate over all conntracks: if iter returns true, it's deleted. */ /* Iterate over all conntracks: if iter returns true, it's deleted. */
extern void 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 void nf_conntrack_free(struct nf_conn *ct);
extern struct nf_conn * 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, const struct nf_conntrack_tuple *repl,
gfp_t gfp); gfp_t gfp);
...@@ -273,16 +287,14 @@ static inline int nf_ct_is_untracked(const struct sk_buff *skb) ...@@ -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 int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
extern unsigned int nf_conntrack_htable_size; extern unsigned int nf_conntrack_htable_size;
extern int nf_conntrack_checksum;
extern atomic_t nf_conntrack_count;
extern int nf_conntrack_max; extern int nf_conntrack_max;
DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat); #define NF_CT_STAT_INC(net, count) \
#define NF_CT_STAT_INC(count) (__get_cpu_var(nf_conntrack_stat).count++) (per_cpu_ptr((net)->ct.stat, raw_smp_processor_id())->count++)
#define NF_CT_STAT_INC_ATOMIC(count) \ #define NF_CT_STAT_INC_ATOMIC(net, count) \
do { \ do { \
local_bh_disable(); \ local_bh_disable(); \
__get_cpu_var(nf_conntrack_stat).count++; \ per_cpu_ptr((net)->ct.stat, raw_smp_processor_id())->count++; \
local_bh_enable(); \ local_bh_enable(); \
} while (0) } while (0)
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#ifndef _NF_CONNTRACK_ACCT_H #ifndef _NF_CONNTRACK_ACCT_H
#define _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_common.h>
#include <linux/netfilter/nf_conntrack_tuple_common.h> #include <linux/netfilter/nf_conntrack_tuple_common.h>
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack.h>
...@@ -18,8 +19,6 @@ struct nf_conn_counter { ...@@ -18,8 +19,6 @@ struct nf_conn_counter {
u_int64_t bytes; u_int64_t bytes;
}; };
extern int nf_ct_acct;
static inline static inline
struct nf_conn_counter *nf_conn_acct_find(const struct nf_conn *ct) 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) ...@@ -29,9 +28,10 @@ struct nf_conn_counter *nf_conn_acct_find(const struct nf_conn *ct)
static inline static inline
struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp) 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; struct nf_conn_counter *acct;
if (!nf_ct_acct) if (!net->ct.sysctl_acct)
return NULL; return NULL;
acct = nf_ct_ext_add(ct, NF_CT_EXT_ACCT, gfp); 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) ...@@ -45,7 +45,7 @@ struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp)
extern unsigned int extern unsigned int
seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir); seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir);
extern int nf_conntrack_acct_init(void); extern int nf_conntrack_acct_init(struct net *net);
extern void nf_conntrack_acct_fini(void); extern void nf_conntrack_acct_fini(struct net *net);
#endif /* _NF_CONNTRACK_ACCT_H */ #endif /* _NF_CONNTRACK_ACCT_H */
...@@ -20,12 +20,13 @@ ...@@ -20,12 +20,13 @@
/* This header is used to share core functionality between the /* This header is used to share core functionality between the
standalone connection tracking module, and the compatibility layer's use standalone connection tracking module, and the compatibility layer's use
of connection tracking. */ 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, unsigned int hooknum,
struct sk_buff *skb); struct sk_buff *skb);
extern int nf_conntrack_init(void); extern int nf_conntrack_init(struct net *net);
extern void nf_conntrack_cleanup(void); extern void nf_conntrack_cleanup(struct net *net);
extern int nf_conntrack_proto_init(void); extern int nf_conntrack_proto_init(void);
extern void nf_conntrack_proto_fini(void); extern void nf_conntrack_proto_fini(void);
...@@ -48,7 +49,7 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse, ...@@ -48,7 +49,7 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
/* Find a connection corresponding to a tuple. */ /* Find a connection corresponding to a tuple. */
extern struct nf_conntrack_tuple_hash * 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); 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, ...@@ -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_l3proto *l3proto,
const struct nf_conntrack_l4proto *proto); const struct nf_conntrack_l4proto *proto);
extern struct hlist_head *nf_conntrack_hash;
extern spinlock_t nf_conntrack_lock ; extern spinlock_t nf_conntrack_lock ;
extern struct hlist_head unconfirmed;
#endif /* _NF_CONNTRACK_CORE_H */ #endif /* _NF_CONNTRACK_CORE_H */
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <net/net_namespace.h>
#include <net/netfilter/nf_conntrack_expect.h> #include <net/netfilter/nf_conntrack_expect.h>
#ifdef CONFIG_NF_CONNTRACK_EVENTS #ifdef CONFIG_NF_CONNTRACK_EVENTS
...@@ -15,9 +16,6 @@ struct nf_conntrack_ecache { ...@@ -15,9 +16,6 @@ struct nf_conntrack_ecache {
struct nf_conn *ct; struct nf_conn *ct;
unsigned int events; 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 struct atomic_notifier_head nf_conntrack_chain;
extern int nf_conntrack_register_notifier(struct notifier_block *nb); extern int nf_conntrack_register_notifier(struct notifier_block *nb);
...@@ -25,17 +23,16 @@ extern int nf_conntrack_unregister_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_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_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 static inline void
nf_conntrack_event_cache(enum ip_conntrack_events event, nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
const struct sk_buff *skb)
{ {
struct nf_conn *ct = (struct nf_conn *)skb->nfct; struct net *net = nf_ct_net(ct);
struct nf_conntrack_ecache *ecache; struct nf_conntrack_ecache *ecache;
local_bh_disable(); 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) if (ct != ecache->ct)
__nf_ct_event_cache_init(ct); __nf_ct_event_cache_init(ct);
ecache->events |= event; ecache->events |= event;
...@@ -60,6 +57,9 @@ nf_ct_expect_event(enum ip_conntrack_expect_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); 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 */ #else /* CONFIG_NF_CONNTRACK_EVENTS */
static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, 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, ...@@ -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_deliver_cached_events(const struct nf_conn *ct) {}
static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event, static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
struct nf_conntrack_expect *exp) {} 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 /* CONFIG_NF_CONNTRACK_EVENTS */
#endif /*_NF_CONNTRACK_ECACHE_H*/ #endif /*_NF_CONNTRACK_ECACHE_H*/
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define _NF_CONNTRACK_EXPECT_H #define _NF_CONNTRACK_EXPECT_H
#include <net/netfilter/nf_conntrack.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_hsize;
extern unsigned int nf_ct_expect_max; extern unsigned int nf_ct_expect_max;
...@@ -56,6 +55,15 @@ struct nf_conntrack_expect ...@@ -56,6 +55,15 @@ struct nf_conntrack_expect
struct rcu_head rcu; 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 struct nf_conntrack_expect_policy
{ {
unsigned int max_expected; unsigned int max_expected;
...@@ -67,17 +75,17 @@ struct nf_conntrack_expect_policy ...@@ -67,17 +75,17 @@ struct nf_conntrack_expect_policy
#define NF_CT_EXPECT_PERMANENT 0x1 #define NF_CT_EXPECT_PERMANENT 0x1
#define NF_CT_EXPECT_INACTIVE 0x2 #define NF_CT_EXPECT_INACTIVE 0x2
int nf_conntrack_expect_init(void); int nf_conntrack_expect_init(struct net *net);
void nf_conntrack_expect_fini(void); void nf_conntrack_expect_fini(struct net *net);
struct nf_conntrack_expect * 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 * 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 * 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_unlink_expect(struct nf_conntrack_expect *exp);
void nf_ct_remove_expectations(struct nf_conn *ct); void nf_ct_remove_expectations(struct nf_conn *ct);
...@@ -86,7 +94,7 @@ void nf_ct_unexpect_related(struct nf_conntrack_expect *exp); ...@@ -86,7 +94,7 @@ void nf_ct_unexpect_related(struct nf_conntrack_expect *exp);
/* Allocate space for an expectation: this is mandatory before calling /* Allocate space for an expectation: this is mandatory before calling
nf_ct_expect_related. You will have to call put afterwards. */ nf_ct_expect_related. You will have to call put afterwards. */
struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me); 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 *,
const union nf_inet_addr *, const union nf_inet_addr *,
u_int8_t, const __be16 *, const __be16 *); u_int8_t, const __be16 *, const __be16 *);
......
...@@ -39,7 +39,7 @@ struct nf_conntrack_l4proto ...@@ -39,7 +39,7 @@ struct nf_conntrack_l4proto
const struct sk_buff *skb, const struct sk_buff *skb,
unsigned int dataoff, unsigned int dataoff,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
int pf, u_int8_t pf,
unsigned int hooknum); unsigned int hooknum);
/* Called when a new connection for this protocol found; /* Called when a new connection for this protocol found;
...@@ -50,9 +50,9 @@ struct nf_conntrack_l4proto ...@@ -50,9 +50,9 @@ struct nf_conntrack_l4proto
/* Called when a conntrack entry is destroyed */ /* Called when a conntrack entry is destroyed */
void (*destroy)(struct nf_conn *ct); 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, 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_* */ /* Print out the per-protocol part of the tuple. Return like seq_* */
int (*print_tuple)(struct seq_file *s, int (*print_tuple)(struct seq_file *s,
...@@ -117,20 +117,19 @@ extern int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[], ...@@ -117,20 +117,19 @@ extern int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
struct nf_conntrack_tuple *t); struct nf_conntrack_tuple *t);
extern const struct nla_policy nf_ct_port_nla_policy[]; extern const struct nla_policy nf_ct_port_nla_policy[];
/* Log invalid packets */
extern unsigned int nf_ct_log_invalid;
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
#ifdef DEBUG_INVALID_PACKETS #ifdef DEBUG_INVALID_PACKETS
#define LOG_INVALID(proto) \ #define LOG_INVALID(net, proto) \
(nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW) ((net)->ct.sysctl_log_invalid == (proto) || \
(net)->ct.sysctl_log_invalid == IPPROTO_RAW)
#else #else
#define LOG_INVALID(proto) \ #define LOG_INVALID(net, proto) \
((nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW) \ (((net)->ct.sysctl_log_invalid == (proto) || \
(net)->ct.sysctl_log_invalid == IPPROTO_RAW) \
&& net_ratelimit()) && net_ratelimit())
#endif #endif
#else #else
#define LOG_INVALID(proto) 0 #define LOG_INVALID(net, proto) 0
#endif /* CONFIG_SYSCTL */ #endif /* CONFIG_SYSCTL */
#endif /*_NF_CONNTRACK_PROTOCOL_H*/ #endif /*_NF_CONNTRACK_PROTOCOL_H*/
...@@ -28,7 +28,7 @@ struct nf_loginfo { ...@@ -28,7 +28,7 @@ struct nf_loginfo {
} u; } u;
}; };
typedef void nf_logfn(unsigned int pf, typedef void nf_logfn(u_int8_t pf,
unsigned int hooknum, unsigned int hooknum,
const struct sk_buff *skb, const struct sk_buff *skb,
const struct net_device *in, const struct net_device *in,
...@@ -43,12 +43,12 @@ struct nf_logger { ...@@ -43,12 +43,12 @@ struct nf_logger {
}; };
/* Function to register/unregister log function. */ /* 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(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 */ /* Calls the registered backend logging function */
void nf_log_packet(int pf, void nf_log_packet(u_int8_t pf,
unsigned int hooknum, unsigned int hooknum,
const struct sk_buff *skb, const struct sk_buff *skb,
const struct net_device *in, const struct net_device *in,
......
...@@ -8,7 +8,7 @@ struct nf_queue_entry { ...@@ -8,7 +8,7 @@ struct nf_queue_entry {
unsigned int id; unsigned int id;
struct nf_hook_ops *elem; struct nf_hook_ops *elem;
int pf; u_int8_t pf;
unsigned int hook; unsigned int hook;
struct net_device *indev; struct net_device *indev;
struct net_device *outdev; struct net_device *outdev;
...@@ -24,9 +24,9 @@ struct nf_queue_handler { ...@@ -24,9 +24,9 @@ struct nf_queue_handler {
char *name; 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); 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); const struct nf_queue_handler *qh);
extern void nf_unregister_queue_handlers(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); extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
......
#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
#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 { ...@@ -38,6 +38,9 @@ struct netns_ipv4 {
struct xt_table *iptable_raw; struct xt_table *iptable_raw;
struct xt_table *arptable_filter; struct xt_table *arptable_filter;
struct xt_table *iptable_security; struct xt_table *iptable_security;
struct xt_table *nat_table;
struct hlist_head *nat_bysource;
int nat_vmalloced;
#endif #endif
int sysctl_icmp_echo_ignore_all; int sysctl_icmp_echo_ignore_all;
......
...@@ -657,7 +657,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, ...@@ -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 nf_bridge_info *nf_bridge;
struct net_device *parent; struct net_device *parent;
int pf; u_int8_t pf;
if (!skb->nf_bridge) if (!skb->nf_bridge)
return NF_ACCEPT; return NF_ACCEPT;
...@@ -791,7 +791,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb, ...@@ -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 nf_bridge_info *nf_bridge = skb->nf_bridge;
struct net_device *realoutdev = bridge_parent(skb->dev); struct net_device *realoutdev = bridge_parent(skb->dev);
int pf; u_int8_t pf;
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
/* Be very paranoid. This probably won't happen anymore, but let's /* Be very paranoid. This probably won't happen anymore, but let's
......
...@@ -2,21 +2,21 @@ ...@@ -2,21 +2,21 @@
# Bridge netfilter configuration # Bridge netfilter configuration
# #
menu "Bridge: Netfilter Configuration" menuconfig BRIDGE_NF_EBTABLES
depends on BRIDGE && BRIDGE_NETFILTER
config BRIDGE_NF_EBTABLES
tristate "Ethernet Bridge tables (ebtables) support" tristate "Ethernet Bridge tables (ebtables) support"
select NETFILTER_XTABLES
help help
ebtables is a general, extensible frame/packet identification ebtables is a general, extensible frame/packet identification
framework. Say 'Y' or 'M' here if you want to do Ethernet framework. Say 'Y' or 'M' here if you want to do Ethernet
filtering/NAT/brouting on the Ethernet bridge. filtering/NAT/brouting on the Ethernet bridge.
if BRIDGE_NF_EBTABLES
# #
# tables # tables
# #
config BRIDGE_EBT_BROUTE config BRIDGE_EBT_BROUTE
tristate "ebt: broute table support" tristate "ebt: broute table support"
depends on BRIDGE_NF_EBTABLES
help help
The ebtables broute table is used to define rules that decide between The ebtables broute table is used to define rules that decide between
bridging and routing frames, giving Linux the functionality of a bridging and routing frames, giving Linux the functionality of a
...@@ -27,7 +27,6 @@ config BRIDGE_EBT_BROUTE ...@@ -27,7 +27,6 @@ config BRIDGE_EBT_BROUTE
config BRIDGE_EBT_T_FILTER config BRIDGE_EBT_T_FILTER
tristate "ebt: filter table support" tristate "ebt: filter table support"
depends on BRIDGE_NF_EBTABLES
help help
The ebtables filter table is used to define frame filtering rules at The ebtables filter table is used to define frame filtering rules at
local input, forwarding and local output. See the man page for local input, forwarding and local output. See the man page for
...@@ -37,7 +36,6 @@ config BRIDGE_EBT_T_FILTER ...@@ -37,7 +36,6 @@ config BRIDGE_EBT_T_FILTER
config BRIDGE_EBT_T_NAT config BRIDGE_EBT_T_NAT
tristate "ebt: nat table support" tristate "ebt: nat table support"
depends on BRIDGE_NF_EBTABLES
help help
The ebtables nat table is used to define rules that alter the MAC The ebtables nat table is used to define rules that alter the MAC
source address (MAC SNAT) or the MAC destination address (MAC DNAT). source address (MAC SNAT) or the MAC destination address (MAC DNAT).
...@@ -49,7 +47,6 @@ config BRIDGE_EBT_T_NAT ...@@ -49,7 +47,6 @@ config BRIDGE_EBT_T_NAT
# #
config BRIDGE_EBT_802_3 config BRIDGE_EBT_802_3
tristate "ebt: 802.3 filter support" tristate "ebt: 802.3 filter support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds matching support for 802.3 Ethernet frames. This option adds matching support for 802.3 Ethernet frames.
...@@ -57,7 +54,6 @@ config BRIDGE_EBT_802_3 ...@@ -57,7 +54,6 @@ config BRIDGE_EBT_802_3
config BRIDGE_EBT_AMONG config BRIDGE_EBT_AMONG
tristate "ebt: among filter support" tristate "ebt: among filter support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the among match, which allows matching the MAC source This option adds the among match, which allows matching the MAC source
and/or destination address on a list of addresses. Optionally, and/or destination address on a list of addresses. Optionally,
...@@ -67,7 +63,6 @@ config BRIDGE_EBT_AMONG ...@@ -67,7 +63,6 @@ config BRIDGE_EBT_AMONG
config BRIDGE_EBT_ARP config BRIDGE_EBT_ARP
tristate "ebt: ARP filter support" tristate "ebt: ARP filter support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the ARP match, which allows ARP and RARP header field This option adds the ARP match, which allows ARP and RARP header field
filtering. filtering.
...@@ -76,7 +71,6 @@ config BRIDGE_EBT_ARP ...@@ -76,7 +71,6 @@ config BRIDGE_EBT_ARP
config BRIDGE_EBT_IP config BRIDGE_EBT_IP
tristate "ebt: IP filter support" tristate "ebt: IP filter support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the IP match, which allows basic IP header field This option adds the IP match, which allows basic IP header field
filtering. filtering.
...@@ -94,7 +88,6 @@ config BRIDGE_EBT_IP6 ...@@ -94,7 +88,6 @@ config BRIDGE_EBT_IP6
config BRIDGE_EBT_LIMIT config BRIDGE_EBT_LIMIT
tristate "ebt: limit match support" tristate "ebt: limit match support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the limit match, which allows you to control This option adds the limit match, which allows you to control
the rate at which a rule can be matched. This match is the the rate at which a rule can be matched. This match is the
...@@ -105,7 +98,6 @@ config BRIDGE_EBT_LIMIT ...@@ -105,7 +98,6 @@ config BRIDGE_EBT_LIMIT
config BRIDGE_EBT_MARK config BRIDGE_EBT_MARK
tristate "ebt: mark filter support" tristate "ebt: mark filter support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the mark match, which allows matching frames based on 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. the 'nfmark' value in the frame. This can be set by the mark target.
...@@ -116,7 +108,6 @@ config BRIDGE_EBT_MARK ...@@ -116,7 +108,6 @@ config BRIDGE_EBT_MARK
config BRIDGE_EBT_PKTTYPE config BRIDGE_EBT_PKTTYPE
tristate "ebt: packet type filter support" tristate "ebt: packet type filter support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the packet type match, which allows matching on the This option adds the packet type match, which allows matching on the
type of packet based on its Ethernet "class" (as determined by type of packet based on its Ethernet "class" (as determined by
...@@ -127,7 +118,6 @@ config BRIDGE_EBT_PKTTYPE ...@@ -127,7 +118,6 @@ config BRIDGE_EBT_PKTTYPE
config BRIDGE_EBT_STP config BRIDGE_EBT_STP
tristate "ebt: STP filter support" tristate "ebt: STP filter support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the Spanning Tree Protocol match, which This option adds the Spanning Tree Protocol match, which
allows STP header field filtering. allows STP header field filtering.
...@@ -136,7 +126,6 @@ config BRIDGE_EBT_STP ...@@ -136,7 +126,6 @@ config BRIDGE_EBT_STP
config BRIDGE_EBT_VLAN config BRIDGE_EBT_VLAN
tristate "ebt: 802.1Q VLAN filter support" tristate "ebt: 802.1Q VLAN filter support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the 802.1Q vlan match, which allows the filtering of This option adds the 802.1Q vlan match, which allows the filtering of
802.1Q vlan fields. 802.1Q vlan fields.
...@@ -156,7 +145,6 @@ config BRIDGE_EBT_ARPREPLY ...@@ -156,7 +145,6 @@ config BRIDGE_EBT_ARPREPLY
config BRIDGE_EBT_DNAT config BRIDGE_EBT_DNAT
tristate "ebt: dnat target support" tristate "ebt: dnat target support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the MAC DNAT target, which allows altering the MAC This option adds the MAC DNAT target, which allows altering the MAC
destination address of frames. destination address of frames.
...@@ -165,7 +153,6 @@ config BRIDGE_EBT_DNAT ...@@ -165,7 +153,6 @@ config BRIDGE_EBT_DNAT
config BRIDGE_EBT_MARK_T config BRIDGE_EBT_MARK_T
tristate "ebt: mark target support" tristate "ebt: mark target support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the mark target, which allows marking frames by This option adds the mark target, which allows marking frames by
setting the 'nfmark' value in the frame. setting the 'nfmark' value in the frame.
...@@ -176,7 +163,6 @@ config BRIDGE_EBT_MARK_T ...@@ -176,7 +163,6 @@ config BRIDGE_EBT_MARK_T
config BRIDGE_EBT_REDIRECT config BRIDGE_EBT_REDIRECT
tristate "ebt: redirect target support" tristate "ebt: redirect target support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the MAC redirect target, which allows altering the MAC 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. destination address of a frame to that of the device it arrived on.
...@@ -185,7 +171,6 @@ config BRIDGE_EBT_REDIRECT ...@@ -185,7 +171,6 @@ config BRIDGE_EBT_REDIRECT
config BRIDGE_EBT_SNAT config BRIDGE_EBT_SNAT
tristate "ebt: snat target support" tristate "ebt: snat target support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the MAC SNAT target, which allows altering the MAC This option adds the MAC SNAT target, which allows altering the MAC
source address of frames. source address of frames.
...@@ -196,7 +181,6 @@ config BRIDGE_EBT_SNAT ...@@ -196,7 +181,6 @@ config BRIDGE_EBT_SNAT
# #
config BRIDGE_EBT_LOG config BRIDGE_EBT_LOG
tristate "ebt: log support" tristate "ebt: log support"
depends on BRIDGE_NF_EBTABLES
help help
This option adds the log watcher, that you can use in any rule This option adds the log watcher, that you can use in any rule
in any ebtables table. It records info about the frame header in any ebtables table. It records info about the frame header
...@@ -206,7 +190,6 @@ config BRIDGE_EBT_LOG ...@@ -206,7 +190,6 @@ config BRIDGE_EBT_LOG
config BRIDGE_EBT_ULOG config BRIDGE_EBT_ULOG
tristate "ebt: ulog support (OBSOLETE)" tristate "ebt: ulog support (OBSOLETE)"
depends on BRIDGE_NF_EBTABLES
help help
This option enables the old bridge-specific "ebt_ulog" implementation This option enables the old bridge-specific "ebt_ulog" implementation
which has been obsoleted by the new "nfnetlink_log" code (see which has been obsoleted by the new "nfnetlink_log" code (see
...@@ -223,7 +206,6 @@ config BRIDGE_EBT_ULOG ...@@ -223,7 +206,6 @@ config BRIDGE_EBT_ULOG
config BRIDGE_EBT_NFLOG config BRIDGE_EBT_NFLOG
tristate "ebt: nflog support" tristate "ebt: nflog support"
depends on BRIDGE_NF_EBTABLES
help help
This option enables the nflog watcher, which allows to LOG This option enables the nflog watcher, which allows to LOG
messages through the netfilter logging API, which can use messages through the netfilter logging API, which can use
...@@ -235,4 +217,4 @@ config BRIDGE_EBT_NFLOG ...@@ -235,4 +217,4 @@ config BRIDGE_EBT_NFLOG
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
endmenu endif # BRIDGE_NF_EBTABLES
...@@ -7,64 +7,63 @@ ...@@ -7,64 +7,63 @@
* May 2003 * May 2003
* *
*/ */
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h> #include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_802_3.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, static bool
const struct net_device *out, const void *data, unsigned int datalen) 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); 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; __be16 type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type;
if (info->bitmask & EBT_802_3_SAP) { if (info->bitmask & EBT_802_3_SAP) {
if (FWINV(info->sap != hdr->llc.ui.ssap, 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)) 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 (info->bitmask & EBT_802_3_TYPE) {
if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_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)) 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 bool ebt_802_3_mt_check(const struct xt_mtchk_param *par)
static int ebt_802_3_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
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) 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 = { static struct xt_match ebt_802_3_mt_reg __read_mostly = {
.name = EBT_802_3_MATCH, .name = "802_3",
.match = ebt_filter_802_3, .revision = 0,
.check = ebt_802_3_check, .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, .me = THIS_MODULE,
}; };
static int __init ebt_802_3_init(void) 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) 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); module_init(ebt_802_3_init);
......
...@@ -7,15 +7,15 @@ ...@@ -7,15 +7,15 @@
* August, 2003 * August, 2003
* *
*/ */
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_among.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/module.h> #include <linux/module.h>
#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, static bool ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
const char *mac, __be32 ip) const char *mac, __be32 ip)
{ {
/* You may be puzzled as to how this code works. /* You may be puzzled as to how this code works.
* Some tricks were used, refer to * Some tricks were used, refer to
...@@ -33,23 +33,19 @@ static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh, ...@@ -33,23 +33,19 @@ static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
if (ip) { if (ip) {
for (i = start; i < limit; i++) { for (i = start; i < limit; i++) {
p = &wh->pool[i]; p = &wh->pool[i];
if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) { if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0])
if (p->ip == 0 || p->ip == ip) { if (p->ip == 0 || p->ip == ip)
return 1; return true;
}
}
} }
} else { } else {
for (i = start; i < limit; i++) { for (i = start; i < limit; i++) {
p = &wh->pool[i]; p = &wh->pool[i];
if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) { if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0])
if (p->ip == 0) { if (p->ip == 0)
return 1; return true;
}
}
} }
} }
return 0; return false;
} }
static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash 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) ...@@ -131,12 +127,10 @@ static int get_ip_src(const struct sk_buff *skb, __be32 *addr)
return 0; return 0;
} }
static int ebt_filter_among(const struct sk_buff *skb, static bool
const struct net_device *in, ebt_among_mt(const struct sk_buff *skb, const struct xt_match_param *par)
const struct net_device *out, const void *data,
unsigned int datalen)
{ {
const struct ebt_among_info *info = data; const struct ebt_among_info *info = par->matchinfo;
const char *dmac, *smac; const char *dmac, *smac;
const struct ebt_mac_wormhash *wh_dst, *wh_src; const struct ebt_mac_wormhash *wh_dst, *wh_src;
__be32 dip = 0, sip = 0; __be32 dip = 0, sip = 0;
...@@ -147,41 +141,41 @@ static int ebt_filter_among(const struct sk_buff *skb, ...@@ -147,41 +141,41 @@ static int ebt_filter_among(const struct sk_buff *skb,
if (wh_src) { if (wh_src) {
smac = eth_hdr(skb)->h_source; smac = eth_hdr(skb)->h_source;
if (get_ip_src(skb, &sip)) if (get_ip_src(skb, &sip))
return EBT_NOMATCH; return false;
if (!(info->bitmask & EBT_AMONG_SRC_NEG)) { if (!(info->bitmask & EBT_AMONG_SRC_NEG)) {
/* we match only if it contains */ /* we match only if it contains */
if (!ebt_mac_wormhash_contains(wh_src, smac, sip)) if (!ebt_mac_wormhash_contains(wh_src, smac, sip))
return EBT_NOMATCH; return false;
} else { } else {
/* we match only if it DOES NOT contain */ /* we match only if it DOES NOT contain */
if (ebt_mac_wormhash_contains(wh_src, smac, sip)) if (ebt_mac_wormhash_contains(wh_src, smac, sip))
return EBT_NOMATCH; return false;
} }
} }
if (wh_dst) { if (wh_dst) {
dmac = eth_hdr(skb)->h_dest; dmac = eth_hdr(skb)->h_dest;
if (get_ip_dst(skb, &dip)) if (get_ip_dst(skb, &dip))
return EBT_NOMATCH; return false;
if (!(info->bitmask & EBT_AMONG_DST_NEG)) { if (!(info->bitmask & EBT_AMONG_DST_NEG)) {
/* we match only if it contains */ /* we match only if it contains */
if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip)) if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip))
return EBT_NOMATCH; return false;
} else { } else {
/* we match only if it DOES NOT contain */ /* we match only if it DOES NOT contain */
if (ebt_mac_wormhash_contains(wh_dst, dmac, dip)) 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, static bool ebt_among_mt_check(const struct xt_mtchk_param *par)
const struct ebt_entry *e, void *data,
unsigned int datalen)
{ {
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); int expected_length = sizeof(struct ebt_among_info);
const struct ebt_mac_wormhash *wh_dst, *wh_src; const struct ebt_mac_wormhash *wh_dst, *wh_src;
int err; int err;
...@@ -191,42 +185,45 @@ static int ebt_among_check(const char *tablename, unsigned int hookmask, ...@@ -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_dst);
expected_length += ebt_mac_wormhash_size(wh_src); 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 printk(KERN_WARNING
"ebtables: among: wrong size: %d " "ebtables: among: wrong size: %d "
"against expected %d, rounded to %Zd\n", "against expected %d, rounded to %Zd\n",
datalen, expected_length, em->match_size, expected_length,
EBT_ALIGN(expected_length)); EBT_ALIGN(expected_length));
return -EINVAL; return false;
} }
if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) { if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) {
printk(KERN_WARNING printk(KERN_WARNING
"ebtables: among: dst integrity fail: %x\n", -err); "ebtables: among: dst integrity fail: %x\n", -err);
return -EINVAL; return false;
} }
if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) { if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) {
printk(KERN_WARNING printk(KERN_WARNING
"ebtables: among: src integrity fail: %x\n", -err); "ebtables: among: src integrity fail: %x\n", -err);
return -EINVAL; return false;
} }
return 0; return true;
} }
static struct ebt_match filter_among __read_mostly = { static struct xt_match ebt_among_mt_reg __read_mostly = {
.name = EBT_AMONG_MATCH, .name = "among",
.match = ebt_filter_among, .revision = 0,
.check = ebt_among_check, .family = NFPROTO_BRIDGE,
.match = ebt_among_mt,
.checkentry = ebt_among_mt_check,
.matchsize = -1, /* special case */
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static int __init ebt_among_init(void) 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) static void __exit ebt_among_fini(void)
{ {
ebt_unregister_match(&filter_among); xt_unregister_match(&ebt_among_mt_reg);
} }
module_init(ebt_among_init); module_init(ebt_among_init);
......
...@@ -8,58 +8,58 @@ ...@@ -8,58 +8,58 @@
* April, 2002 * April, 2002
* *
*/ */
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_arp.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/module.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, static bool
const struct net_device *out, const void *data, unsigned int datalen) 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; const struct arphdr *ah;
struct arphdr _arph; struct arphdr _arph;
ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph); ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
if (ah == NULL) if (ah == NULL)
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode != if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode !=
ah->ar_op, EBT_ARP_OPCODE)) ah->ar_op, EBT_ARP_OPCODE))
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype != if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype !=
ah->ar_hrd, EBT_ARP_HTYPE)) ah->ar_hrd, EBT_ARP_HTYPE))
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype != if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype !=
ah->ar_pro, EBT_ARP_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)) { if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) {
const __be32 *sap, *dap; const __be32 *sap, *dap;
__be32 saddr, daddr; __be32 saddr, daddr;
if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP)) 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) + sap = skb_header_pointer(skb, sizeof(struct arphdr) +
ah->ar_hln, sizeof(saddr), ah->ar_hln, sizeof(saddr),
&saddr); &saddr);
if (sap == NULL) if (sap == NULL)
return EBT_NOMATCH; return false;
dap = skb_header_pointer(skb, sizeof(struct arphdr) + dap = skb_header_pointer(skb, sizeof(struct arphdr) +
2*ah->ar_hln+sizeof(saddr), 2*ah->ar_hln+sizeof(saddr),
sizeof(daddr), &daddr); sizeof(daddr), &daddr);
if (dap == NULL) if (dap == NULL)
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_ARP_SRC_IP && if (info->bitmask & EBT_ARP_SRC_IP &&
FWINV(info->saddr != (*sap & info->smsk), 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 && if (info->bitmask & EBT_ARP_DST_IP &&
FWINV(info->daddr != (*dap & info->dmsk), 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 && if (info->bitmask & EBT_ARP_GRAT &&
FWINV(*dap != *sap, 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)) { 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 ...@@ -68,18 +68,18 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
uint8_t verdict, i; uint8_t verdict, i;
if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER)) if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER))
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_ARP_SRC_MAC) { if (info->bitmask & EBT_ARP_SRC_MAC) {
mp = skb_header_pointer(skb, sizeof(struct arphdr), mp = skb_header_pointer(skb, sizeof(struct arphdr),
sizeof(_mac), &_mac); sizeof(_mac), &_mac);
if (mp == NULL) if (mp == NULL)
return EBT_NOMATCH; return false;
verdict = 0; verdict = 0;
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
verdict |= (mp[i] ^ info->smaddr[i]) & verdict |= (mp[i] ^ info->smaddr[i]) &
info->smmsk[i]; info->smmsk[i];
if (FWINV(verdict != 0, EBT_ARP_SRC_MAC)) if (FWINV(verdict != 0, EBT_ARP_SRC_MAC))
return EBT_NOMATCH; return false;
} }
if (info->bitmask & EBT_ARP_DST_MAC) { 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 ...@@ -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, ah->ar_hln + ah->ar_pln,
sizeof(_mac), &_mac); sizeof(_mac), &_mac);
if (mp == NULL) if (mp == NULL)
return EBT_NOMATCH; return false;
verdict = 0; verdict = 0;
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
verdict |= (mp[i] ^ info->dmaddr[i]) & verdict |= (mp[i] ^ info->dmaddr[i]) &
info->dmmsk[i]; info->dmmsk[i];
if (FWINV(verdict != 0, EBT_ARP_DST_MAC)) 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, static bool ebt_arp_mt_check(const struct xt_mtchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
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) && if ((e->ethproto != htons(ETH_P_ARP) &&
e->ethproto != htons(ETH_P_RARP)) || e->ethproto != htons(ETH_P_RARP)) ||
e->invflags & EBT_IPROTO) e->invflags & EBT_IPROTO)
return -EINVAL; return false;
if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK) if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK)
return -EINVAL; return false;
return 0; return true;
} }
static struct ebt_match filter_arp __read_mostly = { static struct xt_match ebt_arp_mt_reg __read_mostly = {
.name = EBT_ARP_MATCH, .name = "arp",
.match = ebt_filter_arp, .revision = 0,
.check = ebt_arp_check, .family = NFPROTO_BRIDGE,
.match = ebt_arp_mt,
.checkentry = ebt_arp_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_arp_info)),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static int __init ebt_arp_init(void) 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) static void __exit ebt_arp_fini(void)
{ {
ebt_unregister_match(&filter_arp); xt_unregister_match(&ebt_arp_mt_reg);
} }
module_init(ebt_arp_init); module_init(ebt_arp_init);
......
...@@ -8,18 +8,17 @@ ...@@ -8,18 +8,17 @@
* August, 2003 * August, 2003
* *
*/ */
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_arpreply.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <net/arp.h> #include <net/arp.h>
#include <linux/module.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, static unsigned int
const struct net_device *in, const struct net_device *out, ebt_arpreply_tg(struct sk_buff *skb, const struct xt_target_param *par)
const void *data, unsigned int datalen)
{ {
struct ebt_arpreply_info *info = (void *)data; const struct ebt_arpreply_info *info = par->targinfo;
const __be32 *siptr, *diptr; const __be32 *siptr, *diptr;
__be32 _sip, _dip; __be32 _sip, _dip;
const struct arphdr *ap; const struct arphdr *ap;
...@@ -52,45 +51,45 @@ static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr, ...@@ -52,45 +51,45 @@ static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
if (diptr == NULL) if (diptr == NULL)
return EBT_DROP; 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); *diptr, shp, info->mac, shp);
return info->target; return info->target;
} }
static int ebt_target_reply_check(const char *tablename, unsigned int hookmask, static bool ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
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) if (BASE_CHAIN && info->target == EBT_RETURN)
return -EINVAL; return false;
if (e->ethproto != htons(ETH_P_ARP) || if (e->ethproto != htons(ETH_P_ARP) ||
e->invflags & EBT_IPROTO) e->invflags & EBT_IPROTO)
return -EINVAL; return false;
CLEAR_BASE_CHAIN_BIT; return true;
if (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING))
return -EINVAL;
return 0;
} }
static struct ebt_target reply_target __read_mostly = { static struct xt_target ebt_arpreply_tg_reg __read_mostly = {
.name = EBT_ARPREPLY_TARGET, .name = "arpreply",
.target = ebt_target_reply, .revision = 0,
.check = ebt_target_reply_check, .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, .me = THIS_MODULE,
}; };
static int __init ebt_arpreply_init(void) 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) static void __exit ebt_arpreply_fini(void)
{ {
ebt_unregister_target(&reply_target); xt_unregister_target(&ebt_arpreply_tg_reg);
} }
module_init(ebt_arpreply_init); module_init(ebt_arpreply_init);
......
...@@ -7,18 +7,17 @@ ...@@ -7,18 +7,17 @@
* June, 2002 * June, 2002
* *
*/ */
#include <linux/module.h>
#include <net/sock.h>
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h> #include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nat.h> #include <linux/netfilter_bridge/ebt_nat.h>
#include <linux/module.h>
#include <net/sock.h>
static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr, static unsigned int
const struct net_device *in, const struct net_device *out, ebt_dnat_tg(struct sk_buff *skb, const struct xt_target_param *par)
const void *data, unsigned int datalen)
{ {
const struct ebt_nat_info *info = data; const struct ebt_nat_info *info = par->targinfo;
if (!skb_make_writable(skb, 0)) if (!skb_make_writable(skb, 0))
return EBT_DROP; return EBT_DROP;
...@@ -27,40 +26,46 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr, ...@@ -27,40 +26,46 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
return info->target; return info->target;
} }
static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask, static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
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) if (BASE_CHAIN && info->target == EBT_RETURN)
return -EINVAL; return false;
CLEAR_BASE_CHAIN_BIT;
if ( (strcmp(tablename, "nat") || hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
(hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) && if ((strcmp(par->table, "nat") != 0 ||
(strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) (hook_mask & ~((1 << NF_BR_PRE_ROUTING) |
return -EINVAL; (1 << NF_BR_LOCAL_OUT)))) &&
if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info))) (strcmp(par->table, "broute") != 0 ||
return -EINVAL; hook_mask & ~(1 << NF_BR_BROUTING)))
return false;
if (INVALID_TARGET) if (INVALID_TARGET)
return -EINVAL; return false;
return 0; return true;
} }
static struct ebt_target dnat __read_mostly = { static struct xt_target ebt_dnat_tg_reg __read_mostly = {
.name = EBT_DNAT_TARGET, .name = "dnat",
.target = ebt_target_dnat, .revision = 0,
.check = ebt_target_dnat_check, .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, .me = THIS_MODULE,
}; };
static int __init ebt_dnat_init(void) 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) static void __exit ebt_dnat_fini(void)
{ {
ebt_unregister_target(&dnat); xt_unregister_target(&ebt_dnat_tg_reg);
} }
module_init(ebt_dnat_init); module_init(ebt_dnat_init);
......
...@@ -11,24 +11,23 @@ ...@@ -11,24 +11,23 @@
* Innominate Security Technologies AG <mhopf@innominate.com> * Innominate Security Technologies AG <mhopf@innominate.com>
* September, 2002 * September, 2002
*/ */
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_ip.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <net/ip.h> #include <net/ip.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/module.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 { struct tcpudphdr {
__be16 src; __be16 src;
__be16 dst; __be16 dst;
}; };
static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, static bool
const struct net_device *out, const void *data, ebt_ip_mt(const struct sk_buff *skb, const struct xt_match_param *par)
unsigned int datalen)
{ {
const struct ebt_ip_info *info = data; const struct ebt_ip_info *info = par->matchinfo;
const struct iphdr *ih; const struct iphdr *ih;
struct iphdr _iph; struct iphdr _iph;
const struct tcpudphdr *pptr; const struct tcpudphdr *pptr;
...@@ -36,92 +35,93 @@ static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, ...@@ -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); ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
if (ih == NULL) if (ih == NULL)
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_IP_TOS && if (info->bitmask & EBT_IP_TOS &&
FWINV(info->tos != ih->tos, EBT_IP_TOS)) FWINV(info->tos != ih->tos, EBT_IP_TOS))
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_IP_SOURCE && if (info->bitmask & EBT_IP_SOURCE &&
FWINV((ih->saddr & info->smsk) != FWINV((ih->saddr & info->smsk) !=
info->saddr, EBT_IP_SOURCE)) info->saddr, EBT_IP_SOURCE))
return EBT_NOMATCH; return false;
if ((info->bitmask & EBT_IP_DEST) && if ((info->bitmask & EBT_IP_DEST) &&
FWINV((ih->daddr & info->dmsk) != FWINV((ih->daddr & info->dmsk) !=
info->daddr, EBT_IP_DEST)) info->daddr, EBT_IP_DEST))
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_IP_PROTO) { if (info->bitmask & EBT_IP_PROTO) {
if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO)) if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO))
return EBT_NOMATCH; return false;
if (!(info->bitmask & EBT_IP_DPORT) && if (!(info->bitmask & EBT_IP_DPORT) &&
!(info->bitmask & EBT_IP_SPORT)) !(info->bitmask & EBT_IP_SPORT))
return EBT_MATCH; return true;
if (ntohs(ih->frag_off) & IP_OFFSET) if (ntohs(ih->frag_off) & IP_OFFSET)
return EBT_NOMATCH; return false;
pptr = skb_header_pointer(skb, ih->ihl*4, pptr = skb_header_pointer(skb, ih->ihl*4,
sizeof(_ports), &_ports); sizeof(_ports), &_ports);
if (pptr == NULL) if (pptr == NULL)
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_IP_DPORT) { if (info->bitmask & EBT_IP_DPORT) {
u32 dst = ntohs(pptr->dst); u32 dst = ntohs(pptr->dst);
if (FWINV(dst < info->dport[0] || if (FWINV(dst < info->dport[0] ||
dst > info->dport[1], dst > info->dport[1],
EBT_IP_DPORT)) EBT_IP_DPORT))
return EBT_NOMATCH; return false;
} }
if (info->bitmask & EBT_IP_SPORT) { if (info->bitmask & EBT_IP_SPORT) {
u32 src = ntohs(pptr->src); u32 src = ntohs(pptr->src);
if (FWINV(src < info->sport[0] || if (FWINV(src < info->sport[0] ||
src > info->sport[1], src > info->sport[1],
EBT_IP_SPORT)) EBT_IP_SPORT))
return EBT_NOMATCH; return false;
} }
} }
return EBT_MATCH; return true;
} }
static int ebt_ip_check(const char *tablename, unsigned int hookmask, static bool ebt_ip_mt_check(const struct xt_mtchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
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) || if (e->ethproto != htons(ETH_P_IP) ||
e->invflags & EBT_IPROTO) e->invflags & EBT_IPROTO)
return -EINVAL; return false;
if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK) 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->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) {
if (info->invflags & EBT_IP_PROTO) if (info->invflags & EBT_IP_PROTO)
return -EINVAL; return false;
if (info->protocol != IPPROTO_TCP && if (info->protocol != IPPROTO_TCP &&
info->protocol != IPPROTO_UDP && info->protocol != IPPROTO_UDP &&
info->protocol != IPPROTO_UDPLITE && info->protocol != IPPROTO_UDPLITE &&
info->protocol != IPPROTO_SCTP && info->protocol != IPPROTO_SCTP &&
info->protocol != IPPROTO_DCCP) info->protocol != IPPROTO_DCCP)
return -EINVAL; return false;
} }
if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1]) if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
return -EINVAL; return false;
if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1]) if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
return -EINVAL; return false;
return 0; return true;
} }
static struct ebt_match filter_ip __read_mostly = { static struct xt_match ebt_ip_mt_reg __read_mostly = {
.name = EBT_IP_MATCH, .name = "ip",
.match = ebt_filter_ip, .revision = 0,
.check = ebt_ip_check, .family = NFPROTO_BRIDGE,
.match = ebt_ip_mt,
.checkentry = ebt_ip_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_ip_info)),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static int __init ebt_ip_init(void) 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) static void __exit ebt_ip_fini(void)
{ {
ebt_unregister_match(&filter_ip); xt_unregister_match(&ebt_ip_mt_reg);
} }
module_init(ebt_ip_init); module_init(ebt_ip_init);
......
...@@ -13,26 +13,24 @@ ...@@ -13,26 +13,24 @@
* *
* Jan, 2008 * Jan, 2008
*/ */
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_ip6.h>
#include <linux/ipv6.h> #include <linux/ipv6.h>
#include <net/ipv6.h> #include <net/ipv6.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/module.h> #include <linux/module.h>
#include <net/dsfield.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 { struct tcpudphdr {
__be16 src; __be16 src;
__be16 dst; __be16 dst;
}; };
static int ebt_filter_ip6(const struct sk_buff *skb, static bool
const struct net_device *in, ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
const struct net_device *out, const void *data,
unsigned int datalen)
{ {
const struct ebt_ip6_info *info = (struct ebt_ip6_info *)data; const struct ebt_ip6_info *info = par->matchinfo;
const struct ipv6hdr *ih6; const struct ipv6hdr *ih6;
struct ipv6hdr _ip6h; struct ipv6hdr _ip6h;
const struct tcpudphdr *pptr; const struct tcpudphdr *pptr;
...@@ -42,100 +40,100 @@ static int ebt_filter_ip6(const struct sk_buff *skb, ...@@ -42,100 +40,100 @@ static int ebt_filter_ip6(const struct sk_buff *skb,
ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h); ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h);
if (ih6 == NULL) if (ih6 == NULL)
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_IP6_TCLASS && if (info->bitmask & EBT_IP6_TCLASS &&
FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS)) FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS))
return EBT_NOMATCH; return false;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] & tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] &
info->smsk.in6_u.u6_addr32[i]; info->smsk.in6_u.u6_addr32[i];
if (info->bitmask & EBT_IP6_SOURCE && if (info->bitmask & EBT_IP6_SOURCE &&
FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0), FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0),
EBT_IP6_SOURCE)) EBT_IP6_SOURCE))
return EBT_NOMATCH; return false;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] & tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] &
info->dmsk.in6_u.u6_addr32[i]; info->dmsk.in6_u.u6_addr32[i];
if (info->bitmask & EBT_IP6_DEST && if (info->bitmask & EBT_IP6_DEST &&
FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), 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) { if (info->bitmask & EBT_IP6_PROTO) {
uint8_t nexthdr = ih6->nexthdr; uint8_t nexthdr = ih6->nexthdr;
int offset_ph; int offset_ph;
offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr); offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr);
if (offset_ph == -1) if (offset_ph == -1)
return EBT_NOMATCH; return false;
if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO)) if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO))
return EBT_NOMATCH; return false;
if (!(info->bitmask & EBT_IP6_DPORT) && if (!(info->bitmask & EBT_IP6_DPORT) &&
!(info->bitmask & EBT_IP6_SPORT)) !(info->bitmask & EBT_IP6_SPORT))
return EBT_MATCH; return true;
pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports), pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports),
&_ports); &_ports);
if (pptr == NULL) if (pptr == NULL)
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_IP6_DPORT) { if (info->bitmask & EBT_IP6_DPORT) {
u32 dst = ntohs(pptr->dst); u32 dst = ntohs(pptr->dst);
if (FWINV(dst < info->dport[0] || if (FWINV(dst < info->dport[0] ||
dst > info->dport[1], EBT_IP6_DPORT)) dst > info->dport[1], EBT_IP6_DPORT))
return EBT_NOMATCH; return false;
} }
if (info->bitmask & EBT_IP6_SPORT) { if (info->bitmask & EBT_IP6_SPORT) {
u32 src = ntohs(pptr->src); u32 src = ntohs(pptr->src);
if (FWINV(src < info->sport[0] || if (FWINV(src < info->sport[0] ||
src > info->sport[1], EBT_IP6_SPORT)) 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, static bool ebt_ip6_mt_check(const struct xt_mtchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
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) 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) 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->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) {
if (info->invflags & EBT_IP6_PROTO) if (info->invflags & EBT_IP6_PROTO)
return -EINVAL; return false;
if (info->protocol != IPPROTO_TCP && if (info->protocol != IPPROTO_TCP &&
info->protocol != IPPROTO_UDP && info->protocol != IPPROTO_UDP &&
info->protocol != IPPROTO_UDPLITE && info->protocol != IPPROTO_UDPLITE &&
info->protocol != IPPROTO_SCTP && info->protocol != IPPROTO_SCTP &&
info->protocol != IPPROTO_DCCP) info->protocol != IPPROTO_DCCP)
return -EINVAL; return false;
} }
if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1]) if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1])
return -EINVAL; return false;
if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1]) if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1])
return -EINVAL; return false;
return 0; return true;
} }
static struct ebt_match filter_ip6 = static struct xt_match ebt_ip6_mt_reg __read_mostly = {
{ .name = "ip6",
.name = EBT_IP6_MATCH, .revision = 0,
.match = ebt_filter_ip6, .family = NFPROTO_BRIDGE,
.check = ebt_ip6_check, .match = ebt_ip6_mt,
.checkentry = ebt_ip6_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_ip6_info)),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static int __init ebt_ip6_init(void) 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) static void __exit ebt_ip6_fini(void)
{ {
ebt_unregister_match(&filter_ip6); xt_unregister_match(&ebt_ip6_mt_reg);
} }
module_init(ebt_ip6_init); module_init(ebt_ip6_init);
......
...@@ -10,13 +10,12 @@ ...@@ -10,13 +10,12 @@
* September, 2003 * September, 2003
* *
*/ */
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_limit.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/spinlock.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); static DEFINE_SPINLOCK(limit_lock);
...@@ -31,11 +30,10 @@ static DEFINE_SPINLOCK(limit_lock); ...@@ -31,11 +30,10 @@ static DEFINE_SPINLOCK(limit_lock);
#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
static int ebt_limit_match(const struct sk_buff *skb, static bool
const struct net_device *in, const struct net_device *out, ebt_limit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
const void *data, unsigned int datalen)
{ {
struct ebt_limit_info *info = (struct ebt_limit_info *)data; struct ebt_limit_info *info = (void *)par->matchinfo;
unsigned long now = jiffies; unsigned long now = jiffies;
spin_lock_bh(&limit_lock); spin_lock_bh(&limit_lock);
...@@ -47,11 +45,11 @@ static int ebt_limit_match(const struct sk_buff *skb, ...@@ -47,11 +45,11 @@ static int ebt_limit_match(const struct sk_buff *skb,
/* We're not limited. */ /* We're not limited. */
info->credit -= info->cost; info->credit -= info->cost;
spin_unlock_bh(&limit_lock); spin_unlock_bh(&limit_lock);
return EBT_MATCH; return true;
} }
spin_unlock_bh(&limit_lock); spin_unlock_bh(&limit_lock);
return EBT_NOMATCH; return false;
} }
/* Precision saver. */ /* Precision saver. */
...@@ -66,20 +64,16 @@ user2credits(u_int32_t user) ...@@ -66,20 +64,16 @@ user2credits(u_int32_t user)
return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE; return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE;
} }
static int ebt_limit_check(const char *tablename, unsigned int hookmask, static bool ebt_limit_mt_check(const struct xt_mtchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
struct ebt_limit_info *info = data; struct ebt_limit_info *info = par->matchinfo;
if (datalen != EBT_ALIGN(sizeof(struct ebt_limit_info)))
return -EINVAL;
/* Check for overflow. */ /* Check for overflow. */
if (info->burst == 0 || if (info->burst == 0 ||
user2credits(info->avg * info->burst) < user2credits(info->avg)) { user2credits(info->avg * info->burst) < user2credits(info->avg)) {
printk("Overflow in ebt_limit, try lower: %u/%u\n", printk("Overflow in ebt_limit, try lower: %u/%u\n",
info->avg, info->burst); info->avg, info->burst);
return -EINVAL; return false;
} }
/* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */ /* 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, ...@@ -87,24 +81,27 @@ static int ebt_limit_check(const char *tablename, unsigned int hookmask,
info->credit = user2credits(info->avg * info->burst); info->credit = user2credits(info->avg * info->burst);
info->credit_cap = user2credits(info->avg * info->burst); info->credit_cap = user2credits(info->avg * info->burst);
info->cost = user2credits(info->avg); info->cost = user2credits(info->avg);
return 0; return true;
} }
static struct ebt_match ebt_limit_reg __read_mostly = { static struct xt_match ebt_limit_mt_reg __read_mostly = {
.name = EBT_LIMIT_MATCH, .name = "limit",
.match = ebt_limit_match, .revision = 0,
.check = ebt_limit_check, .family = NFPROTO_BRIDGE,
.match = ebt_limit_mt,
.checkentry = ebt_limit_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_limit_info)),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static int __init ebt_limit_init(void) 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) 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); module_init(ebt_limit_init);
......
...@@ -8,10 +8,6 @@ ...@@ -8,10 +8,6 @@
* April, 2002 * 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/module.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/in.h> #include <linux/in.h>
...@@ -21,22 +17,23 @@ ...@@ -21,22 +17,23 @@
#include <linux/ipv6.h> #include <linux/ipv6.h>
#include <net/ipv6.h> #include <net/ipv6.h>
#include <linux/in6.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 DEFINE_SPINLOCK(ebt_log_lock);
static int ebt_log_check(const char *tablename, unsigned int hookmask, static bool ebt_log_tg_check(const struct xt_tgchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
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) if (info->bitmask & ~EBT_LOG_MASK)
return -EINVAL; return false;
if (info->loglevel >= 8) if (info->loglevel >= 8)
return -EINVAL; return false;
info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0'; info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0';
return 0; return true;
} }
struct tcpudphdr struct tcpudphdr
...@@ -84,7 +81,7 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset) ...@@ -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] #define myNIPQUAD(a) a[0], a[1], a[2], a[3]
static void 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 sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct nf_loginfo *loginfo, const struct net_device *out, const struct nf_loginfo *loginfo,
const char *prefix) const char *prefix)
...@@ -194,11 +191,10 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum, ...@@ -194,11 +191,10 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
} }
static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, static unsigned int
const struct net_device *in, const struct net_device *out, ebt_log_tg(struct sk_buff *skb, const struct xt_target_param *par)
const void *data, unsigned int datalen)
{ {
const struct ebt_log_info *info = data; const struct ebt_log_info *info = par->targinfo;
struct nf_loginfo li; struct nf_loginfo li;
li.type = NF_LOG_TYPE_LOG; li.type = NF_LOG_TYPE_LOG;
...@@ -206,18 +202,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, ...@@ -206,18 +202,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
li.u.log.logflags = info->bitmask; li.u.log.logflags = info->bitmask;
if (info->bitmask & EBT_LOG_NFLOG) if (info->bitmask & EBT_LOG_NFLOG)
nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, nf_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
"%s", info->prefix); par->out, &li, "%s", info->prefix);
else else
ebt_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, ebt_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
info->prefix); par->out, &li, info->prefix);
return EBT_CONTINUE;
} }
static struct ebt_watcher log = static struct xt_target ebt_log_tg_reg __read_mostly = {
{ .name = "log",
.name = EBT_LOG_WATCHER, .revision = 0,
.watcher = ebt_log, .family = NFPROTO_BRIDGE,
.check = ebt_log_check, .target = ebt_log_tg,
.checkentry = ebt_log_tg_check,
.targetsize = XT_ALIGN(sizeof(struct ebt_log_info)),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
...@@ -231,17 +230,17 @@ static int __init ebt_log_init(void) ...@@ -231,17 +230,17 @@ static int __init ebt_log_init(void)
{ {
int ret; int ret;
ret = ebt_register_watcher(&log); ret = xt_register_target(&ebt_log_tg_reg);
if (ret < 0) if (ret < 0)
return ret; return ret;
nf_log_register(PF_BRIDGE, &ebt_log_logger); nf_log_register(NFPROTO_BRIDGE, &ebt_log_logger);
return 0; return 0;
} }
static void __exit ebt_log_fini(void) static void __exit ebt_log_fini(void)
{ {
nf_log_unregister(&ebt_log_logger); nf_log_unregister(&ebt_log_logger);
ebt_unregister_watcher(&log); xt_unregister_target(&ebt_log_tg_reg);
} }
module_init(ebt_log_init); module_init(ebt_log_init);
......
...@@ -13,15 +13,15 @@ ...@@ -13,15 +13,15 @@
* Marking a frame doesn't really change anything in the frame anyway. * 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/ebtables.h>
#include <linux/netfilter_bridge/ebt_mark_t.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, static unsigned int
const struct net_device *in, const struct net_device *out, ebt_mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
const void *data, unsigned int datalen)
{ {
const struct ebt_mark_t_info *info = data; const struct ebt_mark_t_info *info = par->targinfo;
int action = info->target & -16; int action = info->target & -16;
if (action == MARK_SET_VALUE) if (action == MARK_SET_VALUE)
...@@ -36,42 +36,41 @@ static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr, ...@@ -36,42 +36,41 @@ static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr,
return info->target | ~EBT_VERDICT_BITS; return info->target | ~EBT_VERDICT_BITS;
} }
static int ebt_target_mark_check(const char *tablename, unsigned int hookmask, static bool ebt_mark_tg_check(const struct xt_tgchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
const struct ebt_mark_t_info *info = data; const struct ebt_mark_t_info *info = par->targinfo;
int tmp; int tmp;
if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
return -EINVAL;
tmp = info->target | ~EBT_VERDICT_BITS; tmp = info->target | ~EBT_VERDICT_BITS;
if (BASE_CHAIN && tmp == EBT_RETURN) if (BASE_CHAIN && tmp == EBT_RETURN)
return -EINVAL; return false;
CLEAR_BASE_CHAIN_BIT;
if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
return -EINVAL; return false;
tmp = info->target & ~EBT_VERDICT_BITS; tmp = info->target & ~EBT_VERDICT_BITS;
if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE && if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE) tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
return -EINVAL; return false;
return 0; return true;
} }
static struct ebt_target mark_target __read_mostly = { static struct xt_target ebt_mark_tg_reg __read_mostly = {
.name = EBT_MARK_TARGET, .name = "mark",
.target = ebt_target_mark, .revision = 0,
.check = ebt_target_mark_check, .family = NFPROTO_BRIDGE,
.target = ebt_mark_tg,
.checkentry = ebt_mark_tg_check,
.targetsize = XT_ALIGN(sizeof(struct ebt_mark_t_info)),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static int __init ebt_mark_init(void) 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) static void __exit ebt_mark_fini(void)
{ {
ebt_unregister_target(&mark_target); xt_unregister_target(&ebt_mark_tg_reg);
} }
module_init(ebt_mark_init); module_init(ebt_mark_init);
......
...@@ -7,53 +7,52 @@ ...@@ -7,53 +7,52 @@
* July, 2002 * July, 2002
* *
*/ */
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h> #include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_mark_m.h> #include <linux/netfilter_bridge/ebt_mark_m.h>
#include <linux/module.h>
static int ebt_filter_mark(const struct sk_buff *skb, static bool
const struct net_device *in, const struct net_device *out, const void *data, ebt_mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
unsigned int datalen)
{ {
const struct ebt_mark_m_info *info = data; const struct ebt_mark_m_info *info = par->matchinfo;
if (info->bitmask & EBT_MARK_OR) if (info->bitmask & EBT_MARK_OR)
return !(!!(skb->mark & info->mask) ^ info->invert); return !!(skb->mark & info->mask) ^ info->invert;
return !(((skb->mark & info->mask) == info->mark) ^ info->invert); return ((skb->mark & info->mask) == info->mark) ^ info->invert;
} }
static int ebt_mark_check(const char *tablename, unsigned int hookmask, static bool ebt_mark_mt_check(const struct xt_mtchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
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) if (info->bitmask & ~EBT_MARK_MASK)
return -EINVAL; return false;
if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND)) if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND))
return -EINVAL; return false;
if (!info->bitmask) if (!info->bitmask)
return -EINVAL; return false;
return 0; return true;
} }
static struct ebt_match filter_mark __read_mostly = { static struct xt_match ebt_mark_mt_reg __read_mostly = {
.name = EBT_MARK_MATCH, .name = "mark_m",
.match = ebt_filter_mark, .revision = 0,
.check = ebt_mark_check, .family = NFPROTO_BRIDGE,
.match = ebt_mark_mt,
.checkentry = ebt_mark_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_mark_m_info)),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static int __init ebt_mark_m_init(void) 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) 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); module_init(ebt_mark_m_init);
......
...@@ -14,17 +14,15 @@ ...@@ -14,17 +14,15 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h> #include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nflog.h> #include <linux/netfilter_bridge/ebt_nflog.h>
#include <net/netfilter/nf_log.h> #include <net/netfilter/nf_log.h>
static void ebt_nflog(const struct sk_buff *skb, static unsigned int
unsigned int hooknr, ebt_nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
const struct net_device *in,
const struct net_device *out,
const void *data, unsigned int datalen)
{ {
struct ebt_nflog_info *info = (struct ebt_nflog_info *)data; const struct ebt_nflog_info *info = par->targinfo;
struct nf_loginfo li; struct nf_loginfo li;
li.type = NF_LOG_TYPE_ULOG; li.type = NF_LOG_TYPE_ULOG;
...@@ -32,39 +30,39 @@ static void ebt_nflog(const struct sk_buff *skb, ...@@ -32,39 +30,39 @@ static void ebt_nflog(const struct sk_buff *skb,
li.u.ulog.group = info->group; li.u.ulog.group = info->group;
li.u.ulog.qthreshold = info->threshold; 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, static bool ebt_nflog_tg_check(const struct xt_tgchk_param *par)
unsigned int hookmask,
const struct ebt_entry *e,
void *data, unsigned int datalen)
{ {
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) if (info->flags & ~EBT_NFLOG_MASK)
return -EINVAL; return false;
info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0'; info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0';
return 0; return true;
} }
static struct ebt_watcher nflog __read_mostly = { static struct xt_target ebt_nflog_tg_reg __read_mostly = {
.name = EBT_NFLOG_WATCHER, .name = "nflog",
.watcher = ebt_nflog, .revision = 0,
.check = ebt_nflog_check, .family = NFPROTO_BRIDGE,
.me = THIS_MODULE, .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) 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) static void __exit ebt_nflog_fini(void)
{ {
ebt_unregister_watcher(&nflog); xt_unregister_target(&ebt_nflog_tg_reg);
} }
module_init(ebt_nflog_init); module_init(ebt_nflog_init);
......
...@@ -7,50 +7,47 @@ ...@@ -7,50 +7,47 @@
* April, 2003 * April, 2003
* *
*/ */
#include <linux/module.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h> #include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_pkttype.h> #include <linux/netfilter_bridge/ebt_pkttype.h>
#include <linux/module.h>
static int ebt_filter_pkttype(const struct sk_buff *skb, static bool
const struct net_device *in, ebt_pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par)
const struct net_device *out,
const void *data,
unsigned int datalen)
{ {
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, static bool ebt_pkttype_mt_check(const struct xt_mtchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
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) if (info->invert != 0 && info->invert != 1)
return -EINVAL; return false;
/* Allow any pkt_type value */ /* Allow any pkt_type value */
return 0; return true;
} }
static struct ebt_match filter_pkttype __read_mostly = { static struct xt_match ebt_pkttype_mt_reg __read_mostly = {
.name = EBT_PKTTYPE_MATCH, .name = "pkttype",
.match = ebt_filter_pkttype, .revision = 0,
.check = ebt_pkttype_check, .family = NFPROTO_BRIDGE,
.match = ebt_pkttype_mt,
.checkentry = ebt_pkttype_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_pkttype_info)),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static int __init ebt_pkttype_init(void) 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) static void __exit ebt_pkttype_fini(void)
{ {
ebt_unregister_match(&filter_pkttype); xt_unregister_match(&ebt_pkttype_mt_reg);
} }
module_init(ebt_pkttype_init); module_init(ebt_pkttype_init);
......
...@@ -7,65 +7,70 @@ ...@@ -7,65 +7,70 @@
* April, 2002 * April, 2002
* *
*/ */
#include <linux/netfilter.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_redirect.h>
#include <linux/module.h> #include <linux/module.h>
#include <net/sock.h> #include <net/sock.h>
#include "../br_private.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, static unsigned int
const struct net_device *in, const struct net_device *out, ebt_redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)
const void *data, unsigned int datalen)
{ {
const struct ebt_redirect_info *info = data; const struct ebt_redirect_info *info = par->targinfo;
if (!skb_make_writable(skb, 0)) if (!skb_make_writable(skb, 0))
return EBT_DROP; return EBT_DROP;
if (hooknr != NF_BR_BROUTING) if (par->hooknum != NF_BR_BROUTING)
memcpy(eth_hdr(skb)->h_dest, 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 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; skb->pkt_type = PACKET_HOST;
return info->target; return info->target;
} }
static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask, static bool ebt_redirect_tg_check(const struct xt_tgchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
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) if (BASE_CHAIN && info->target == EBT_RETURN)
return -EINVAL; return false;
CLEAR_BASE_CHAIN_BIT;
if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) && hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
(strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) if ((strcmp(par->table, "nat") != 0 ||
return -EINVAL; hook_mask & ~(1 << NF_BR_PRE_ROUTING)) &&
(strcmp(par->table, "broute") != 0 ||
hook_mask & ~(1 << NF_BR_BROUTING)))
return false;
if (INVALID_TARGET) if (INVALID_TARGET)
return -EINVAL; return false;
return 0; return true;
} }
static struct ebt_target redirect_target __read_mostly = { static struct xt_target ebt_redirect_tg_reg __read_mostly = {
.name = EBT_REDIRECT_TARGET, .name = "redirect",
.target = ebt_target_redirect, .revision = 0,
.check = ebt_target_redirect_check, .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, .me = THIS_MODULE,
}; };
static int __init ebt_redirect_init(void) 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) static void __exit ebt_redirect_fini(void)
{ {
ebt_unregister_target(&redirect_target); xt_unregister_target(&ebt_redirect_tg_reg);
} }
module_init(ebt_redirect_init); module_init(ebt_redirect_init);
......
...@@ -7,20 +7,19 @@ ...@@ -7,20 +7,19 @@
* June, 2002 * June, 2002
* *
*/ */
#include <linux/netfilter.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nat.h>
#include <linux/module.h> #include <linux/module.h>
#include <net/sock.h> #include <net/sock.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <net/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, static unsigned int
const struct net_device *in, const struct net_device *out, ebt_snat_tg(struct sk_buff *skb, const struct xt_target_param *par)
const void *data, unsigned int datalen)
{ {
const struct ebt_nat_info *info = data; const struct ebt_nat_info *info = par->targinfo;
if (!skb_make_writable(skb, 0)) if (!skb_make_writable(skb, 0))
return EBT_DROP; return EBT_DROP;
...@@ -43,46 +42,43 @@ static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr, ...@@ -43,46 +42,43 @@ static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr,
return info->target | ~EBT_VERDICT_BITS; return info->target | ~EBT_VERDICT_BITS;
} }
static int ebt_target_snat_check(const char *tablename, unsigned int hookmask, static bool ebt_snat_tg_check(const struct xt_tgchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
const struct ebt_nat_info *info = data; const struct ebt_nat_info *info = par->targinfo;
int tmp; int tmp;
if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info)))
return -EINVAL;
tmp = info->target | ~EBT_VERDICT_BITS; tmp = info->target | ~EBT_VERDICT_BITS;
if (BASE_CHAIN && tmp == EBT_RETURN) if (BASE_CHAIN && tmp == EBT_RETURN)
return -EINVAL; return false;
CLEAR_BASE_CHAIN_BIT;
if (strcmp(tablename, "nat"))
return -EINVAL;
if (hookmask & ~(1 << NF_BR_POST_ROUTING))
return -EINVAL;
if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
return -EINVAL; return false;
tmp = info->target | EBT_VERDICT_BITS; tmp = info->target | EBT_VERDICT_BITS;
if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT) if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT)
return -EINVAL; return false;
return 0; return true;
} }
static struct ebt_target snat __read_mostly = { static struct xt_target ebt_snat_tg_reg __read_mostly = {
.name = EBT_SNAT_TARGET, .name = "snat",
.target = ebt_target_snat, .revision = 0,
.check = ebt_target_snat_check, .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, .me = THIS_MODULE,
}; };
static int __init ebt_snat_init(void) 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) static void __exit ebt_snat_fini(void)
{ {
ebt_unregister_target(&snat); xt_unregister_target(&ebt_snat_tg_reg);
} }
module_init(ebt_snat_init); module_init(ebt_snat_init);
......
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
* *
* July, 2003 * July, 2003
*/ */
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_stp.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/module.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_CONFIG 0
#define BPDU_TYPE_TCN 0x80 #define BPDU_TYPE_TCN 0x80
...@@ -40,7 +40,7 @@ struct stp_config_pdu { ...@@ -40,7 +40,7 @@ struct stp_config_pdu {
#define NR16(p) (p[0] << 8 | p[1]) #define NR16(p) (p[0] << 8 | p[1])
#define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]) #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 stp_config_pdu *stpc)
{ {
const struct ebt_stp_config_info *c; const struct ebt_stp_config_info *c;
...@@ -51,12 +51,12 @@ static int ebt_filter_config(const struct ebt_stp_info *info, ...@@ -51,12 +51,12 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
c = &info->config; c = &info->config;
if ((info->bitmask & EBT_STP_FLAGS) && if ((info->bitmask & EBT_STP_FLAGS) &&
FWINV(c->flags != stpc->flags, EBT_STP_FLAGS)) FWINV(c->flags != stpc->flags, EBT_STP_FLAGS))
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_STP_ROOTPRIO) { if (info->bitmask & EBT_STP_ROOTPRIO) {
v16 = NR16(stpc->root); v16 = NR16(stpc->root);
if (FWINV(v16 < c->root_priol || if (FWINV(v16 < c->root_priol ||
v16 > c->root_priou, EBT_STP_ROOTPRIO)) v16 > c->root_priou, EBT_STP_ROOTPRIO))
return EBT_NOMATCH; return false;
} }
if (info->bitmask & EBT_STP_ROOTADDR) { if (info->bitmask & EBT_STP_ROOTADDR) {
verdict = 0; verdict = 0;
...@@ -64,19 +64,19 @@ static int ebt_filter_config(const struct ebt_stp_info *info, ...@@ -64,19 +64,19 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
verdict |= (stpc->root[2+i] ^ c->root_addr[i]) & verdict |= (stpc->root[2+i] ^ c->root_addr[i]) &
c->root_addrmsk[i]; c->root_addrmsk[i];
if (FWINV(verdict != 0, EBT_STP_ROOTADDR)) if (FWINV(verdict != 0, EBT_STP_ROOTADDR))
return EBT_NOMATCH; return false;
} }
if (info->bitmask & EBT_STP_ROOTCOST) { if (info->bitmask & EBT_STP_ROOTCOST) {
v32 = NR32(stpc->root_cost); v32 = NR32(stpc->root_cost);
if (FWINV(v32 < c->root_costl || if (FWINV(v32 < c->root_costl ||
v32 > c->root_costu, EBT_STP_ROOTCOST)) v32 > c->root_costu, EBT_STP_ROOTCOST))
return EBT_NOMATCH; return false;
} }
if (info->bitmask & EBT_STP_SENDERPRIO) { if (info->bitmask & EBT_STP_SENDERPRIO) {
v16 = NR16(stpc->sender); v16 = NR16(stpc->sender);
if (FWINV(v16 < c->sender_priol || if (FWINV(v16 < c->sender_priol ||
v16 > c->sender_priou, EBT_STP_SENDERPRIO)) v16 > c->sender_priou, EBT_STP_SENDERPRIO))
return EBT_NOMATCH; return false;
} }
if (info->bitmask & EBT_STP_SENDERADDR) { if (info->bitmask & EBT_STP_SENDERADDR) {
verdict = 0; verdict = 0;
...@@ -84,60 +84,60 @@ static int ebt_filter_config(const struct ebt_stp_info *info, ...@@ -84,60 +84,60 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) & verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) &
c->sender_addrmsk[i]; c->sender_addrmsk[i];
if (FWINV(verdict != 0, EBT_STP_SENDERADDR)) if (FWINV(verdict != 0, EBT_STP_SENDERADDR))
return EBT_NOMATCH; return false;
} }
if (info->bitmask & EBT_STP_PORT) { if (info->bitmask & EBT_STP_PORT) {
v16 = NR16(stpc->port); v16 = NR16(stpc->port);
if (FWINV(v16 < c->portl || if (FWINV(v16 < c->portl ||
v16 > c->portu, EBT_STP_PORT)) v16 > c->portu, EBT_STP_PORT))
return EBT_NOMATCH; return false;
} }
if (info->bitmask & EBT_STP_MSGAGE) { if (info->bitmask & EBT_STP_MSGAGE) {
v16 = NR16(stpc->msg_age); v16 = NR16(stpc->msg_age);
if (FWINV(v16 < c->msg_agel || if (FWINV(v16 < c->msg_agel ||
v16 > c->msg_ageu, EBT_STP_MSGAGE)) v16 > c->msg_ageu, EBT_STP_MSGAGE))
return EBT_NOMATCH; return false;
} }
if (info->bitmask & EBT_STP_MAXAGE) { if (info->bitmask & EBT_STP_MAXAGE) {
v16 = NR16(stpc->max_age); v16 = NR16(stpc->max_age);
if (FWINV(v16 < c->max_agel || if (FWINV(v16 < c->max_agel ||
v16 > c->max_ageu, EBT_STP_MAXAGE)) v16 > c->max_ageu, EBT_STP_MAXAGE))
return EBT_NOMATCH; return false;
} }
if (info->bitmask & EBT_STP_HELLOTIME) { if (info->bitmask & EBT_STP_HELLOTIME) {
v16 = NR16(stpc->hello_time); v16 = NR16(stpc->hello_time);
if (FWINV(v16 < c->hello_timel || if (FWINV(v16 < c->hello_timel ||
v16 > c->hello_timeu, EBT_STP_HELLOTIME)) v16 > c->hello_timeu, EBT_STP_HELLOTIME))
return EBT_NOMATCH; return false;
} }
if (info->bitmask & EBT_STP_FWDD) { if (info->bitmask & EBT_STP_FWDD) {
v16 = NR16(stpc->forward_delay); v16 = NR16(stpc->forward_delay);
if (FWINV(v16 < c->forward_delayl || if (FWINV(v16 < c->forward_delayl ||
v16 > c->forward_delayu, EBT_STP_FWDD)) 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, static bool
const struct net_device *out, const void *data, unsigned int datalen) 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; const struct stp_header *sp;
struct stp_header _stph; struct stp_header _stph;
const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00}; const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph); sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph);
if (sp == NULL) if (sp == NULL)
return EBT_NOMATCH; return false;
/* The stp code only considers these */ /* The stp code only considers these */
if (memcmp(sp, header, sizeof(header))) if (memcmp(sp, header, sizeof(header)))
return EBT_NOMATCH; return false;
if (info->bitmask & EBT_STP_TYPE if (info->bitmask & EBT_STP_TYPE
&& FWINV(info->type != sp->type, EBT_STP_TYPE)) && FWINV(info->type != sp->type, EBT_STP_TYPE))
return EBT_NOMATCH; return false;
if (sp->type == BPDU_TYPE_CONFIG && if (sp->type == BPDU_TYPE_CONFIG &&
info->bitmask & EBT_STP_CONFIG_MASK) { 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 ...@@ -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), st = skb_header_pointer(skb, sizeof(_stph),
sizeof(_stpc), &_stpc); sizeof(_stpc), &_stpc);
if (st == NULL) if (st == NULL)
return EBT_NOMATCH; return false;
return ebt_filter_config(info, st); return ebt_filter_config(info, st);
} }
return EBT_MATCH; return true;
} }
static int ebt_stp_check(const char *tablename, unsigned int hookmask, static bool ebt_stp_mt_check(const struct xt_mtchk_param *par)
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
const struct ebt_stp_info *info = data; const struct ebt_stp_info *info = par->matchinfo;
const unsigned int len = EBT_ALIGN(sizeof(struct ebt_stp_info));
const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00}; const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00};
const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 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 || if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK ||
!(info->bitmask & EBT_STP_MASK)) !(info->bitmask & EBT_STP_MASK))
return -EINVAL; return false;
if (datalen != len)
return -EINVAL;
/* Make sure the match only receives stp frames */ /* Make sure the match only receives stp frames */
if (compare_ether_addr(e->destmac, bridge_ula) || if (compare_ether_addr(e->destmac, bridge_ula) ||
compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC)) compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC))
return -EINVAL; return false;
return 0; return true;
} }
static struct ebt_match filter_stp __read_mostly = { static struct xt_match ebt_stp_mt_reg __read_mostly = {
.name = EBT_STP_MATCH, .name = "stp",
.match = ebt_filter_stp, .revision = 0,
.check = ebt_stp_check, .family = NFPROTO_BRIDGE,
.match = ebt_stp_mt,
.checkentry = ebt_stp_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_stp_info)),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static int __init ebt_stp_init(void) 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) static void __exit ebt_stp_fini(void)
{ {
ebt_unregister_match(&filter_stp); xt_unregister_match(&ebt_stp_mt_reg);
} }
module_init(ebt_stp_init); module_init(ebt_stp_init);
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h> #include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_ulog.h> #include <linux/netfilter_bridge/ebt_ulog.h>
#include <net/netfilter/nf_log.h> #include <net/netfilter/nf_log.h>
...@@ -223,7 +224,7 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb, ...@@ -223,7 +224,7 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
} }
/* this function is registered with the netfilter core */ /* 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 sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct nf_loginfo *li, const struct net_device *out, const struct nf_loginfo *li,
const char *prefix) const char *prefix)
...@@ -245,24 +246,20 @@ static void ebt_log_packet(unsigned int pf, unsigned int hooknum, ...@@ -245,24 +246,20 @@ static void ebt_log_packet(unsigned int pf, unsigned int hooknum,
ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
} }
static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, static unsigned int
const struct net_device *in, const struct net_device *out, ebt_ulog_tg(struct sk_buff *skb, const struct xt_target_param *par)
const void *data, unsigned int datalen)
{ {
const struct ebt_ulog_info *uloginfo = data; ebt_ulog_packet(par->hooknum, skb, par->in, par->out,
par->targinfo, NULL);
ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL); return EBT_CONTINUE;
} }
static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par)
static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
struct ebt_ulog_info *uloginfo = data; struct ebt_ulog_info *uloginfo = par->targinfo;
if (datalen != EBT_ALIGN(sizeof(struct ebt_ulog_info)) || if (uloginfo->nlgroup > 31)
uloginfo->nlgroup > 31) return false;
return -EINVAL;
uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0'; uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0';
...@@ -272,27 +269,31 @@ static int ebt_ulog_check(const char *tablename, unsigned int hookmask, ...@@ -272,27 +269,31 @@ static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
return 0; return 0;
} }
static struct ebt_watcher ulog __read_mostly = { static struct xt_target ebt_ulog_tg_reg __read_mostly = {
.name = EBT_ULOG_WATCHER, .name = "ulog",
.watcher = ebt_ulog, .revision = 0,
.check = ebt_ulog_check, .family = NFPROTO_BRIDGE,
.target = ebt_ulog_tg,
.checkentry = ebt_ulog_tg_check,
.targetsize = XT_ALIGN(sizeof(struct ebt_ulog_info)),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static const struct nf_logger ebt_ulog_logger = { static const struct nf_logger ebt_ulog_logger = {
.name = EBT_ULOG_WATCHER, .name = "ulog",
.logfn = &ebt_log_packet, .logfn = &ebt_log_packet,
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
static int __init ebt_ulog_init(void) static int __init ebt_ulog_init(void)
{ {
int i, ret = 0; bool ret = true;
int i;
if (nlbufsiz >= 128*1024) { if (nlbufsiz >= 128*1024) {
printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB," printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB,"
" please try a smaller nlbufsiz parameter.\n"); " please try a smaller nlbufsiz parameter.\n");
return -EINVAL; return false;
} }
/* initialize ulog_buffers */ /* initialize ulog_buffers */
...@@ -304,13 +305,16 @@ static int __init ebt_ulog_init(void) ...@@ -304,13 +305,16 @@ static int __init ebt_ulog_init(void)
ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
EBT_ULOG_MAXNLGROUPS, NULL, NULL, EBT_ULOG_MAXNLGROUPS, NULL, NULL,
THIS_MODULE); THIS_MODULE);
if (!ebtulognl) if (!ebtulognl) {
ret = -ENOMEM; printk(KERN_WARNING KBUILD_MODNAME ": out of memory trying to "
else if ((ret = ebt_register_watcher(&ulog))) "call netlink_kernel_create\n");
ret = false;
} else if (xt_register_target(&ebt_ulog_tg_reg) != 0) {
netlink_kernel_release(ebtulognl); netlink_kernel_release(ebtulognl);
}
if (ret == 0) if (ret)
nf_log_register(PF_BRIDGE, &ebt_ulog_logger); nf_log_register(NFPROTO_BRIDGE, &ebt_ulog_logger);
return ret; return ret;
} }
...@@ -321,7 +325,7 @@ static void __exit ebt_ulog_fini(void) ...@@ -321,7 +325,7 @@ static void __exit ebt_ulog_fini(void)
int i; int i;
nf_log_unregister(&ebt_ulog_logger); 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++) { for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
ub = &ulog_buffers[i]; ub = &ulog_buffers[i];
if (timer_pending(&ub->timer)) if (timer_pending(&ub->timer))
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h> #include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_vlan.h> #include <linux/netfilter_bridge/ebt_vlan.h>
...@@ -37,15 +38,12 @@ MODULE_LICENSE("GPL"); ...@@ -37,15 +38,12 @@ MODULE_LICENSE("GPL");
#define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args) #define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args)
#define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_ #define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_
#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return EBT_NOMATCH;} #define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return false; }
static int static bool
ebt_filter_vlan(const struct sk_buff *skb, ebt_vlan_mt(const struct sk_buff *skb, const struct xt_match_param *par)
const struct net_device *in,
const struct net_device *out,
const void *data, unsigned int datalen)
{ {
const struct ebt_vlan_info *info = data; const struct ebt_vlan_info *info = par->matchinfo;
const struct vlan_hdr *fp; const struct vlan_hdr *fp;
struct vlan_hdr _frame; struct vlan_hdr _frame;
...@@ -57,7 +55,7 @@ ebt_filter_vlan(const struct sk_buff *skb, ...@@ -57,7 +55,7 @@ ebt_filter_vlan(const struct sk_buff *skb,
fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame); fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame);
if (fp == NULL) if (fp == NULL)
return EBT_NOMATCH; return false;
/* Tag Control Information (TCI) consists of the following elements: /* Tag Control Information (TCI) consists of the following elements:
* - User_priority. The user_priority field is three bits in length, * - User_priority. The user_priority field is three bits in length,
...@@ -83,30 +81,20 @@ ebt_filter_vlan(const struct sk_buff *skb, ...@@ -83,30 +81,20 @@ ebt_filter_vlan(const struct sk_buff *skb,
if (GET_BITMASK(EBT_VLAN_ENCAP)) if (GET_BITMASK(EBT_VLAN_ENCAP))
EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP); EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP);
return EBT_MATCH; return true;
} }
static int static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
ebt_check_vlan(const char *tablename,
unsigned int hooknr,
const struct ebt_entry *e, void *data, unsigned int datalen)
{ {
struct ebt_vlan_info *info = data; struct ebt_vlan_info *info = par->matchinfo;
const struct ebt_entry *e = par->entryinfo;
/* 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;
}
/* Is it 802.1Q frame checked? */ /* Is it 802.1Q frame checked? */
if (e->ethproto != htons(ETH_P_8021Q)) { if (e->ethproto != htons(ETH_P_8021Q)) {
DEBUG_MSG DEBUG_MSG
("passed entry proto %2.4X is not 802.1Q (8100)\n", ("passed entry proto %2.4X is not 802.1Q (8100)\n",
(unsigned short) ntohs(e->ethproto)); (unsigned short) ntohs(e->ethproto));
return -EINVAL; return false;
} }
/* Check for bitmask range /* Check for bitmask range
...@@ -114,14 +102,14 @@ ebt_check_vlan(const char *tablename, ...@@ -114,14 +102,14 @@ ebt_check_vlan(const char *tablename,
if (info->bitmask & ~EBT_VLAN_MASK) { if (info->bitmask & ~EBT_VLAN_MASK) {
DEBUG_MSG("bitmask %2X is out of mask (%2X)\n", DEBUG_MSG("bitmask %2X is out of mask (%2X)\n",
info->bitmask, EBT_VLAN_MASK); info->bitmask, EBT_VLAN_MASK);
return -EINVAL; return false;
} }
/* Check for inversion flags range */ /* Check for inversion flags range */
if (info->invflags & ~EBT_VLAN_MASK) { if (info->invflags & ~EBT_VLAN_MASK) {
DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n", DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n",
info->invflags, EBT_VLAN_MASK); info->invflags, EBT_VLAN_MASK);
return -EINVAL; return false;
} }
/* Reserved VLAN ID (VID) values /* Reserved VLAN ID (VID) values
...@@ -136,7 +124,7 @@ ebt_check_vlan(const char *tablename, ...@@ -136,7 +124,7 @@ ebt_check_vlan(const char *tablename,
DEBUG_MSG DEBUG_MSG
("id %d is out of range (1-4096)\n", ("id %d is out of range (1-4096)\n",
info->id); info->id);
return -EINVAL; return false;
} }
/* Note: This is valid VLAN-tagged frame point. /* Note: This is valid VLAN-tagged frame point.
* Any value of user_priority are acceptable, * Any value of user_priority are acceptable,
...@@ -151,7 +139,7 @@ ebt_check_vlan(const char *tablename, ...@@ -151,7 +139,7 @@ ebt_check_vlan(const char *tablename,
if ((unsigned char) info->prio > 7) { if ((unsigned char) info->prio > 7) {
DEBUG_MSG("prio %d is out of range (0-7)\n", DEBUG_MSG("prio %d is out of range (0-7)\n",
info->prio); info->prio);
return -EINVAL; return false;
} }
} }
/* Check for encapsulated proto range - it is possible to be /* Check for encapsulated proto range - it is possible to be
...@@ -162,17 +150,20 @@ ebt_check_vlan(const char *tablename, ...@@ -162,17 +150,20 @@ ebt_check_vlan(const char *tablename,
DEBUG_MSG DEBUG_MSG
("encap frame length %d is less than minimal\n", ("encap frame length %d is less than minimal\n",
ntohs(info->encap)); ntohs(info->encap));
return -EINVAL; return false;
} }
} }
return 0; return true;
} }
static struct ebt_match filter_vlan __read_mostly = { static struct xt_match ebt_vlan_mt_reg __read_mostly = {
.name = EBT_VLAN_MATCH, .name = "vlan",
.match = ebt_filter_vlan, .revision = 0,
.check = ebt_check_vlan, .family = NFPROTO_BRIDGE,
.match = ebt_vlan_mt,
.checkentry = ebt_vlan_mt_check,
.matchsize = XT_ALIGN(sizeof(struct ebt_vlan_info)),
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
...@@ -181,12 +172,12 @@ static int __init ebt_vlan_init(void) ...@@ -181,12 +172,12 @@ static int __init ebt_vlan_init(void)
DEBUG_MSG("ebtables 802.1Q extension module v" DEBUG_MSG("ebtables 802.1Q extension module v"
MODULE_VERS "\n"); MODULE_VERS "\n");
DEBUG_MSG("module debug=%d\n", !!debug); 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) static void __exit ebt_vlan_fini(void)
{ {
ebt_unregister_match(&filter_vlan); xt_unregister_match(&ebt_vlan_mt_reg);
} }
module_init(ebt_vlan_init); module_init(ebt_vlan_init);
......
This diff is collapsed.
...@@ -18,6 +18,7 @@ static struct list_head *first_device = &pernet_list; ...@@ -18,6 +18,7 @@ static struct list_head *first_device = &pernet_list;
static DEFINE_MUTEX(net_mutex); static DEFINE_MUTEX(net_mutex);
LIST_HEAD(net_namespace_list); LIST_HEAD(net_namespace_list);
EXPORT_SYMBOL_GPL(net_namespace_list);
struct net init_net; struct net init_net;
EXPORT_SYMBOL(init_net); EXPORT_SYMBOL(init_net);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */ /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) 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); const struct iphdr *iph = ip_hdr(skb);
struct rtable *rt; struct rtable *rt;
struct flowi fl = {}; struct flowi fl = {};
...@@ -19,7 +20,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) ...@@ -19,7 +20,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
unsigned int hh_len; unsigned int hh_len;
unsigned int type; 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) if (skb->sk && inet_sk(skb->sk)->transparent)
type = RTN_LOCAL; type = RTN_LOCAL;
if (addr_type == RTN_UNSPEC) if (addr_type == RTN_UNSPEC)
...@@ -36,7 +37,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) ...@@ -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.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
fl.mark = skb->mark; fl.mark = skb->mark;
fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; 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; return -1;
/* Drop old route. */ /* Drop old route. */
...@@ -46,7 +47,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) ...@@ -46,7 +47,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
/* non-local src, find valid iif to satisfy /* non-local src, find valid iif to satisfy
* rp-filter when calling ip_route_input. */ * rp-filter when calling ip_route_input. */
fl.nl_u.ip4_u.daddr = iph->saddr; 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; return -1;
odst = skb->dst; odst = skb->dst;
......
...@@ -5,10 +5,15 @@ ...@@ -5,10 +5,15 @@
menu "IP: Netfilter Configuration" menu "IP: Netfilter Configuration"
depends on INET && NETFILTER depends on INET && NETFILTER
config NF_DEFRAG_IPV4
tristate
default n
config NF_CONNTRACK_IPV4 config NF_CONNTRACK_IPV4
tristate "IPv4 connection tracking support (required for NAT)" tristate "IPv4 connection tracking support (required for NAT)"
depends on NF_CONNTRACK depends on NF_CONNTRACK
default m if NETFILTER_ADVANCED=n default m if NETFILTER_ADVANCED=n
select NF_DEFRAG_IPV4
---help--- ---help---
Connection tracking keeps a record of what packets have passed Connection tracking keeps a record of what packets have passed
through your machine, in order to figure out how they are related through your machine, in order to figure out how they are related
...@@ -56,23 +61,30 @@ config IP_NF_IPTABLES ...@@ -56,23 +61,30 @@ config IP_NF_IPTABLES
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
if IP_NF_IPTABLES
# The matches. # The matches.
config IP_NF_MATCH_RECENT config IP_NF_MATCH_ADDRTYPE
tristate '"recent" match support' tristate '"addrtype" address type match support'
depends on IP_NF_IPTABLES
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
help help
This match is used for creating one or many lists of recently This option allows you to match what routing thinks of an address,
used addresses and then matching against that/those list(s). eg. UNICAST, LOCAL, BROADCAST, ...
Short options are available by using 'iptables -m recent -h' If you want to compile it as a module, say M here and read
Official Website: <http://snowman.net/projects/ipt_recent/> <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. To compile it as a module, choose M here. If unsure, say N.
config IP_NF_MATCH_ECN config IP_NF_MATCH_ECN
tristate '"ecn" match support' tristate '"ecn" match support'
depends on IP_NF_IPTABLES
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
help help
This option adds a `ECN' match, which allows you to match against This option adds a `ECN' match, which allows you to match against
...@@ -80,19 +92,8 @@ config IP_NF_MATCH_ECN ...@@ -80,19 +92,8 @@ config IP_NF_MATCH_ECN
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config 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 config IP_NF_MATCH_TTL
tristate '"ttl" match support' tristate '"ttl" match support'
depends on IP_NF_IPTABLES
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
help help
This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user
...@@ -100,21 +101,9 @@ config IP_NF_MATCH_TTL ...@@ -100,21 +101,9 @@ config IP_NF_MATCH_TTL
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config 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,
eg. UNICAST, LOCAL, BROADCAST, ...
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
# `filter', generic and specific targets # `filter', generic and specific targets
config IP_NF_FILTER config IP_NF_FILTER
tristate "Packet filtering" tristate "Packet filtering"
depends on IP_NF_IPTABLES
default m if NETFILTER_ADVANCED=n default m if NETFILTER_ADVANCED=n
help help
Packet filtering defines a table `filter', which has a series of Packet filtering defines a table `filter', which has a series of
...@@ -136,7 +125,6 @@ config IP_NF_TARGET_REJECT ...@@ -136,7 +125,6 @@ config IP_NF_TARGET_REJECT
config IP_NF_TARGET_LOG config IP_NF_TARGET_LOG
tristate "LOG target support" tristate "LOG target support"
depends on IP_NF_IPTABLES
default m if NETFILTER_ADVANCED=n default m if NETFILTER_ADVANCED=n
help help
This option adds a `LOG' target, which allows you to create rules in This option adds a `LOG' target, which allows you to create rules in
...@@ -146,7 +134,6 @@ config IP_NF_TARGET_LOG ...@@ -146,7 +134,6 @@ config IP_NF_TARGET_LOG
config IP_NF_TARGET_ULOG config IP_NF_TARGET_ULOG
tristate "ULOG target support" tristate "ULOG target support"
depends on IP_NF_IPTABLES
default m if NETFILTER_ADVANCED=n default m if NETFILTER_ADVANCED=n
---help--- ---help---
...@@ -167,7 +154,7 @@ config IP_NF_TARGET_ULOG ...@@ -167,7 +154,7 @@ config IP_NF_TARGET_ULOG
# NAT + specific targets: nf_conntrack # NAT + specific targets: nf_conntrack
config NF_NAT config NF_NAT
tristate "Full NAT" tristate "Full NAT"
depends on IP_NF_IPTABLES && NF_CONNTRACK_IPV4 depends on NF_CONNTRACK_IPV4
default m if NETFILTER_ADVANCED=n default m if NETFILTER_ADVANCED=n
help help
The Full NAT option allows masquerading, port forwarding and other The Full NAT option allows masquerading, port forwarding and other
...@@ -194,26 +181,26 @@ config IP_NF_TARGET_MASQUERADE ...@@ -194,26 +181,26 @@ config IP_NF_TARGET_MASQUERADE
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TARGET_REDIRECT config IP_NF_TARGET_NETMAP
tristate "REDIRECT target support" tristate "NETMAP target support"
depends on NF_NAT depends on NF_NAT
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
help help
REDIRECT is a special case of NAT: all incoming connections are NETMAP is an implementation of static 1:1 NAT mapping of network
mapped onto the incoming interface's address, causing the packets to addresses. It maps the network address part, while keeping the host
come to the local machine instead of passing through. This is address part intact.
useful for transparent proxies.
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config IP_NF_TARGET_NETMAP config IP_NF_TARGET_REDIRECT
tristate "NETMAP target support" tristate "REDIRECT target support"
depends on NF_NAT depends on NF_NAT
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
help help
NETMAP is an implementation of static 1:1 NAT mapping of network REDIRECT is a special case of NAT: all incoming connections are
addresses. It maps the network address part, while keeping the host mapped onto the incoming interface's address, causing the packets to
address part intact. come to the local machine instead of passing through. This is
useful for transparent proxies.
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
...@@ -262,44 +249,43 @@ config NF_NAT_PROTO_SCTP ...@@ -262,44 +249,43 @@ config NF_NAT_PROTO_SCTP
config NF_NAT_FTP config NF_NAT_FTP
tristate tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_FTP default NF_NAT && NF_CONNTRACK_FTP
config NF_NAT_IRC config NF_NAT_IRC
tristate tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_IRC default NF_NAT && NF_CONNTRACK_IRC
config NF_NAT_TFTP config NF_NAT_TFTP
tristate tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_TFTP default NF_NAT && NF_CONNTRACK_TFTP
config NF_NAT_AMANDA config NF_NAT_AMANDA
tristate tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_AMANDA default NF_NAT && NF_CONNTRACK_AMANDA
config NF_NAT_PPTP config NF_NAT_PPTP
tristate tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_PPTP default NF_NAT && NF_CONNTRACK_PPTP
select NF_NAT_PROTO_GRE select NF_NAT_PROTO_GRE
config NF_NAT_H323 config NF_NAT_H323
tristate tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_H323 default NF_NAT && NF_CONNTRACK_H323
config NF_NAT_SIP config NF_NAT_SIP
tristate tristate
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT depends on NF_CONNTRACK && NF_NAT
default NF_NAT && NF_CONNTRACK_SIP default NF_NAT && NF_CONNTRACK_SIP
# mangle + specific targets # mangle + specific targets
config IP_NF_MANGLE config IP_NF_MANGLE
tristate "Packet mangling" tristate "Packet mangling"
depends on IP_NF_IPTABLES
default m if NETFILTER_ADVANCED=n default m if NETFILTER_ADVANCED=n
help help
This option adds a `mangle' table to iptables: see the man page for This option adds a `mangle' table to iptables: see the man page for
...@@ -308,6 +294,19 @@ config IP_NF_MANGLE ...@@ -308,6 +294,19 @@ config IP_NF_MANGLE
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config 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 config IP_NF_TARGET_ECN
tristate "ECN target support" tristate "ECN target support"
depends on IP_NF_MANGLE depends on IP_NF_MANGLE
...@@ -338,23 +337,9 @@ config IP_NF_TARGET_TTL ...@@ -338,23 +337,9 @@ config IP_NF_TARGET_TTL
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config 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 # raw + specific targets
config IP_NF_RAW config IP_NF_RAW
tristate 'raw table support (required for NOTRACK/TRACE)' tristate 'raw table support (required for NOTRACK/TRACE)'
depends on IP_NF_IPTABLES
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
help help
This option adds a `raw' table to iptables. This table is the very This option adds a `raw' table to iptables. This table is the very
...@@ -367,7 +352,6 @@ config IP_NF_RAW ...@@ -367,7 +352,6 @@ config IP_NF_RAW
# security table for MAC policy # security table for MAC policy
config IP_NF_SECURITY config IP_NF_SECURITY
tristate "Security table" tristate "Security table"
depends on IP_NF_IPTABLES
depends on SECURITY depends on SECURITY
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
help help
...@@ -376,6 +360,8 @@ config IP_NF_SECURITY ...@@ -376,6 +360,8 @@ config IP_NF_SECURITY
If unsure, say N. If unsure, say N.
endif # IP_NF_IPTABLES
# ARP tables # ARP tables
config IP_NF_ARPTABLES config IP_NF_ARPTABLES
tristate "ARP tables support" tristate "ARP tables support"
...@@ -388,9 +374,10 @@ config IP_NF_ARPTABLES ...@@ -388,9 +374,10 @@ config IP_NF_ARPTABLES
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
if IP_NF_ARPTABLES
config IP_NF_ARPFILTER config IP_NF_ARPFILTER
tristate "ARP packet filtering" tristate "ARP packet filtering"
depends on IP_NF_ARPTABLES
help help
ARP packet filtering defines a table `filter', which has a series of ARP packet filtering defines a table `filter', which has a series of
rules for simple ARP packet filtering at local input and rules for simple ARP packet filtering at local input and
...@@ -401,10 +388,11 @@ config IP_NF_ARPFILTER ...@@ -401,10 +388,11 @@ config IP_NF_ARPFILTER
config IP_NF_ARP_MANGLE config IP_NF_ARP_MANGLE
tristate "ARP payload mangling" tristate "ARP payload mangling"
depends on IP_NF_ARPTABLES
help help
Allows altering the ARP packet payload: source and destination Allows altering the ARP packet payload: source and destination
hardware and network addresses. hardware and network addresses.
endif # IP_NF_ARPTABLES
endmenu endmenu
...@@ -18,6 +18,9 @@ obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o ...@@ -18,6 +18,9 @@ obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
obj-$(CONFIG_NF_NAT) += nf_nat.o obj-$(CONFIG_NF_NAT) += nf_nat.o
# defrag
obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
# NAT helpers (nf_conntrack) # NAT helpers (nf_conntrack)
obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
...@@ -48,7 +51,6 @@ obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.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_ADDRTYPE) += ipt_addrtype.o
obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.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 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
# targets # targets
......
This diff is collapsed.
...@@ -9,12 +9,9 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); ...@@ -9,12 +9,9 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
MODULE_DESCRIPTION("arptables arp payload mangle target"); MODULE_DESCRIPTION("arptables arp payload mangle target");
static unsigned int static unsigned int
target(struct sk_buff *skb, target(struct sk_buff *skb, const struct xt_target_param *par)
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *target,
const void *targinfo)
{ {
const struct arpt_mangle *mangle = targinfo; const struct arpt_mangle *mangle = par->targinfo;
const struct arphdr *arp; const struct arphdr *arp;
unsigned char *arpptr; unsigned char *arpptr;
int pln, hln; int pln, hln;
...@@ -57,11 +54,9 @@ target(struct sk_buff *skb, ...@@ -57,11 +54,9 @@ target(struct sk_buff *skb,
return mangle->target; return mangle->target;
} }
static bool static bool checkentry(const struct xt_tgchk_param *par)
checkentry(const char *tablename, const void *e, const struct xt_target *target,
void *targinfo, unsigned int hook_mask)
{ {
const struct arpt_mangle *mangle = targinfo; const struct arpt_mangle *mangle = par->targinfo;
if (mangle->flags & ~ARPT_MANGLE_MASK || if (mangle->flags & ~ARPT_MANGLE_MASK ||
!(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, ...@@ -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 = { static struct xt_target arpt_mangle_reg __read_mostly = {
.name = "mangle", .name = "mangle",
.family = NF_ARP, .family = NFPROTO_ARP,
.target = target, .target = target,
.targetsize = sizeof(struct arpt_mangle), .targetsize = sizeof(struct arpt_mangle),
.checkentry = checkentry, .checkentry = checkentry,
......
...@@ -51,7 +51,7 @@ static struct xt_table packet_filter = { ...@@ -51,7 +51,7 @@ static struct xt_table packet_filter = {
.lock = __RW_LOCK_UNLOCKED(packet_filter.lock), .lock = __RW_LOCK_UNLOCKED(packet_filter.lock),
.private = NULL, .private = NULL,
.me = THIS_MODULE, .me = THIS_MODULE,
.af = NF_ARP, .af = NFPROTO_ARP,
}; };
/* The work comes in here from netfilter.c */ /* The work comes in here from netfilter.c */
...@@ -89,21 +89,21 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = { ...@@ -89,21 +89,21 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = {
{ {
.hook = arpt_in_hook, .hook = arpt_in_hook,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pf = NF_ARP, .pf = NFPROTO_ARP,
.hooknum = NF_ARP_IN, .hooknum = NF_ARP_IN,
.priority = NF_IP_PRI_FILTER, .priority = NF_IP_PRI_FILTER,
}, },
{ {
.hook = arpt_out_hook, .hook = arpt_out_hook,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pf = NF_ARP, .pf = NFPROTO_ARP,
.hooknum = NF_ARP_OUT, .hooknum = NF_ARP_OUT,
.priority = NF_IP_PRI_FILTER, .priority = NF_IP_PRI_FILTER,
}, },
{ {
.hook = arpt_forward_hook, .hook = arpt_forward_hook,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pf = NF_ARP, .pf = NFPROTO_ARP,
.hooknum = NF_ARP_FORWARD, .hooknum = NF_ARP_FORWARD,
.priority = NF_IP_PRI_FILTER, .priority = NF_IP_PRI_FILTER,
}, },
......
...@@ -171,31 +171,25 @@ ip_checkentry(const struct ipt_ip *ip) ...@@ -171,31 +171,25 @@ ip_checkentry(const struct ipt_ip *ip)
} }
static unsigned int static unsigned int
ipt_error(struct sk_buff *skb, ipt_error(struct sk_buff *skb, const struct xt_target_param *par)
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
{ {
if (net_ratelimit()) if (net_ratelimit())
printk("ip_tables: error: `%s'\n", (char *)targinfo); printk("ip_tables: error: `%s'\n",
(const char *)par->targinfo);
return NF_DROP; return NF_DROP;
} }
/* Performance critical - called for every packet */ /* Performance critical - called for every packet */
static inline bool static inline bool
do_match(struct ipt_entry_match *m, do_match(struct ipt_entry_match *m, const struct sk_buff *skb,
const struct sk_buff *skb, struct xt_match_param *par)
const struct net_device *in,
const struct net_device *out,
int offset,
bool *hotdrop)
{ {
par->match = m->u.kernel.match;
par->matchinfo = m->data;
/* Stop iteration if it doesn't match */ /* Stop iteration if it doesn't match */
if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data, if (!m->u.kernel.match->match(skb, par))
offset, ip_hdrlen(skb), hotdrop))
return true; return true;
else else
return false; return false;
...@@ -326,7 +320,6 @@ ipt_do_table(struct sk_buff *skb, ...@@ -326,7 +320,6 @@ ipt_do_table(struct sk_buff *skb,
struct xt_table *table) struct xt_table *table)
{ {
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
u_int16_t offset;
const struct iphdr *ip; const struct iphdr *ip;
u_int16_t datalen; u_int16_t datalen;
bool hotdrop = false; bool hotdrop = false;
...@@ -336,6 +329,8 @@ ipt_do_table(struct sk_buff *skb, ...@@ -336,6 +329,8 @@ ipt_do_table(struct sk_buff *skb,
void *table_base; void *table_base;
struct ipt_entry *e, *back; struct ipt_entry *e, *back;
struct xt_table_info *private; struct xt_table_info *private;
struct xt_match_param mtpar;
struct xt_target_param tgpar;
/* Initialization */ /* Initialization */
ip = ip_hdr(skb); ip = ip_hdr(skb);
...@@ -348,7 +343,13 @@ ipt_do_table(struct sk_buff *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 * things we don't know, ie. tcp syn flag or ports). If the
* rule is also a fragment-specific rule, non-fragments won't * rule is also a fragment-specific rule, non-fragments won't
* match it. */ * 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); read_lock_bh(&table->lock);
IP_NF_ASSERT(table->valid_hooks & (1 << hook)); IP_NF_ASSERT(table->valid_hooks & (1 << hook));
...@@ -362,12 +363,11 @@ ipt_do_table(struct sk_buff *skb, ...@@ -362,12 +363,11 @@ ipt_do_table(struct sk_buff *skb,
do { do {
IP_NF_ASSERT(e); IP_NF_ASSERT(e);
IP_NF_ASSERT(back); 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; struct ipt_entry_target *t;
if (IPT_MATCH_ITERATE(e, do_match, if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0)
skb, in, out,
offset, &hotdrop) != 0)
goto no_match; goto no_match;
ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
...@@ -413,16 +413,14 @@ ipt_do_table(struct sk_buff *skb, ...@@ -413,16 +413,14 @@ ipt_do_table(struct sk_buff *skb,
} else { } else {
/* Targets which reenter must return /* Targets which reenter must return
abs. verdicts */ abs. verdicts */
tgpar.target = t->u.kernel.target;
tgpar.targinfo = t->data;
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
((struct ipt_entry *)table_base)->comefrom ((struct ipt_entry *)table_base)->comefrom
= 0xeeeeeeec; = 0xeeeeeeec;
#endif #endif
verdict = t->u.kernel.target->target(skb, verdict = t->u.kernel.target->target(skb,
in, out, &tgpar);
hook,
t->u.kernel.target,
t->data);
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
if (((struct ipt_entry *)table_base)->comefrom if (((struct ipt_entry *)table_base)->comefrom
!= 0xeeeeeeec != 0xeeeeeeec
...@@ -575,12 +573,17 @@ mark_source_chains(struct xt_table_info *newinfo, ...@@ -575,12 +573,17 @@ mark_source_chains(struct xt_table_info *newinfo,
static int static int
cleanup_match(struct ipt_entry_match *m, unsigned int *i) cleanup_match(struct ipt_entry_match *m, unsigned int *i)
{ {
struct xt_mtdtor_param par;
if (i && (*i)-- == 0) if (i && (*i)-- == 0)
return 1; return 1;
if (m->u.kernel.match->destroy) par.match = m->u.kernel.match;
m->u.kernel.match->destroy(m->u.kernel.match, m->data); par.matchinfo = m->data;
module_put(m->u.kernel.match->me); par.family = NFPROTO_IPV4;
if (par.match->destroy != NULL)
par.match->destroy(&par);
module_put(par.match->me);
return 0; return 0;
} }
...@@ -606,34 +609,28 @@ check_entry(struct ipt_entry *e, const char *name) ...@@ -606,34 +609,28 @@ check_entry(struct ipt_entry *e, const char *name)
} }
static int static int
check_match(struct ipt_entry_match *m, const char *name, check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
const struct ipt_ip *ip, unsigned int *i)
unsigned int hookmask, unsigned int *i)
{ {
struct xt_match *match; const struct ipt_ip *ip = par->entryinfo;
int ret; int ret;
match = m->u.kernel.match; par->match = m->u.kernel.match;
ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m), par->matchinfo = m->data;
name, hookmask, ip->proto,
ip->invflags & IPT_INV_PROTO); ret = xt_check_match(par, m->u.match_size - sizeof(*m),
if (!ret && m->u.kernel.match->checkentry ip->proto, ip->invflags & IPT_INV_PROTO);
&& !m->u.kernel.match->checkentry(name, ip, match, m->data, if (ret < 0) {
hookmask)) {
duprintf("ip_tables: check failed for `%s'.\n", duprintf("ip_tables: check failed for `%s'.\n",
m->u.kernel.match->name); par.match->name);
ret = -EINVAL; return ret;
} }
if (!ret) ++*i;
(*i)++; return 0;
return ret;
} }
static int static int
find_check_match(struct ipt_entry_match *m, find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
const char *name,
const struct ipt_ip *ip,
unsigned int hookmask,
unsigned int *i) unsigned int *i)
{ {
struct xt_match *match; struct xt_match *match;
...@@ -648,7 +645,7 @@ find_check_match(struct ipt_entry_match *m, ...@@ -648,7 +645,7 @@ find_check_match(struct ipt_entry_match *m,
} }
m->u.kernel.match = match; m->u.kernel.match = match;
ret = check_match(m, name, ip, hookmask, i); ret = check_match(m, par, i);
if (ret) if (ret)
goto err; goto err;
...@@ -660,23 +657,25 @@ find_check_match(struct ipt_entry_match *m, ...@@ -660,23 +657,25 @@ find_check_match(struct ipt_entry_match *m,
static int check_target(struct ipt_entry *e, const char *name) static int check_target(struct ipt_entry *e, const char *name)
{ {
struct ipt_entry_target *t; struct ipt_entry_target *t = ipt_get_target(e);
struct xt_target *target; 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; int ret;
t = ipt_get_target(e); ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
target = t->u.kernel.target; e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), if (ret < 0) {
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)) {
duprintf("ip_tables: check failed for `%s'.\n", duprintf("ip_tables: check failed for `%s'.\n",
t->u.kernel.target->name); t->u.kernel.target->name);
ret = -EINVAL; return ret;
} }
return ret; return 0;
} }
static int static int
...@@ -687,14 +686,18 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size, ...@@ -687,14 +686,18 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
struct xt_target *target; struct xt_target *target;
int ret; int ret;
unsigned int j; unsigned int j;
struct xt_mtchk_param mtpar;
ret = check_entry(e, name); ret = check_entry(e, name);
if (ret) if (ret)
return ret; return ret;
j = 0; j = 0;
ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip, mtpar.table = name;
e->comefrom, &j); 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) if (ret != 0)
goto cleanup_matches; goto cleanup_matches;
...@@ -769,6 +772,7 @@ check_entry_size_and_hooks(struct ipt_entry *e, ...@@ -769,6 +772,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
static int static int
cleanup_entry(struct ipt_entry *e, unsigned int *i) cleanup_entry(struct ipt_entry *e, unsigned int *i)
{ {
struct xt_tgdtor_param par;
struct ipt_entry_target *t; struct ipt_entry_target *t;
if (i && (*i)-- == 0) if (i && (*i)-- == 0)
...@@ -777,9 +781,13 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i) ...@@ -777,9 +781,13 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i)
/* Cleanup all matches */ /* Cleanup all matches */
IPT_MATCH_ITERATE(e, cleanup_match, NULL); IPT_MATCH_ITERATE(e, cleanup_match, NULL);
t = ipt_get_target(e); t = ipt_get_target(e);
if (t->u.kernel.target->destroy)
t->u.kernel.target->destroy(t->u.kernel.target, t->data); par.target = t->u.kernel.target;
module_put(t->u.kernel.target->me); par.targinfo = t->data;
par.family = NFPROTO_IPV4;
if (par.target->destroy != NULL)
par.target->destroy(&par);
module_put(par.target->me);
return 0; return 0;
} }
...@@ -1648,12 +1656,16 @@ static int ...@@ -1648,12 +1656,16 @@ static int
compat_check_entry(struct ipt_entry *e, const char *name, compat_check_entry(struct ipt_entry *e, const char *name,
unsigned int *i) unsigned int *i)
{ {
struct xt_mtchk_param mtpar;
unsigned int j; unsigned int j;
int ret; int ret;
j = 0; j = 0;
ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, mtpar.table = name;
e->comefrom, &j); mtpar.entryinfo = &e->ip;
mtpar.hook_mask = e->comefrom;
mtpar.family = NFPROTO_IPV4;
ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j);
if (ret) if (ret)
goto cleanup_matches; 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, ...@@ -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 static bool
icmp_match(const struct sk_buff *skb, icmp_match(const struct sk_buff *skb, const struct xt_match_param *par)
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 icmphdr *ic; const struct icmphdr *ic;
struct icmphdr _icmph; struct icmphdr _icmph;
const struct ipt_icmp *icmpinfo = matchinfo; const struct ipt_icmp *icmpinfo = par->matchinfo;
/* Must not be a fragment. */ /* Must not be a fragment. */
if (offset) if (par->fragoff != 0)
return false; return false;
ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
if (ic == NULL) { if (ic == NULL) {
/* We've been asked to examine this packet, and we /* We've been asked to examine this packet, and we
* can't. Hence, no choice but to drop. * can't. Hence, no choice but to drop.
*/ */
duprintf("Dropping evil ICMP tinygram.\n"); duprintf("Dropping evil ICMP tinygram.\n");
*hotdrop = true; *par->hotdrop = true;
return false; return false;
} }
...@@ -2155,15 +2160,9 @@ icmp_match(const struct sk_buff *skb, ...@@ -2155,15 +2160,9 @@ icmp_match(const struct sk_buff *skb,
!!(icmpinfo->invflags&IPT_ICMP_INV)); !!(icmpinfo->invflags&IPT_ICMP_INV));
} }
/* Called when user tries to insert an entry of this type. */ static bool icmp_checkentry(const struct xt_mtchk_param *par)
static bool
icmp_checkentry(const char *tablename,
const void *entry,
const struct xt_match *match,
void *matchinfo,
unsigned int hook_mask)
{ {
const struct ipt_icmp *icmpinfo = matchinfo; const struct ipt_icmp *icmpinfo = par->matchinfo;
/* Must specify no unknown invflags */ /* Must specify no unknown invflags */
return !(icmpinfo->invflags & ~IPT_ICMP_INV); return !(icmpinfo->invflags & ~IPT_ICMP_INV);
......
...@@ -281,11 +281,9 @@ clusterip_responsible(const struct clusterip_config *config, u_int32_t hash) ...@@ -281,11 +281,9 @@ clusterip_responsible(const struct clusterip_config *config, u_int32_t hash)
***********************************************************************/ ***********************************************************************/
static unsigned int static unsigned int
clusterip_tg(struct sk_buff *skb, const struct net_device *in, clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par)
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
{ {
const struct ipt_clusterip_tgt_info *cipinfo = targinfo; const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
struct nf_conn *ct; struct nf_conn *ct;
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;
u_int32_t hash; u_int32_t hash;
...@@ -349,13 +347,10 @@ clusterip_tg(struct sk_buff *skb, const struct net_device *in, ...@@ -349,13 +347,10 @@ clusterip_tg(struct sk_buff *skb, const struct net_device *in,
return XT_CONTINUE; return XT_CONTINUE;
} }
static bool static bool clusterip_tg_check(const struct xt_tgchk_param *par)
clusterip_tg_check(const char *tablename, const void *e_void,
const struct xt_target *target, void *targinfo,
unsigned int hook_mask)
{ {
struct ipt_clusterip_tgt_info *cipinfo = targinfo; struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
const struct ipt_entry *e = e_void; const struct ipt_entry *e = par->entryinfo;
struct clusterip_config *config; struct clusterip_config *config;
...@@ -406,9 +401,9 @@ clusterip_tg_check(const char *tablename, const void *e_void, ...@@ -406,9 +401,9 @@ clusterip_tg_check(const char *tablename, const void *e_void,
} }
cipinfo->config = config; 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 " printk(KERN_WARNING "can't load conntrack support for "
"proto=%u\n", target->family); "proto=%u\n", par->target->family);
return false; return false;
} }
...@@ -416,9 +411,9 @@ clusterip_tg_check(const char *tablename, const void *e_void, ...@@ -416,9 +411,9 @@ clusterip_tg_check(const char *tablename, const void *e_void,
} }
/* drop reference count of cluster config when rule is deleted */ /* 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 /* if no more entries are referencing the config, remove it
* from the list and destroy the proc entry */ * from the list and destroy the proc entry */
...@@ -426,7 +421,7 @@ static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo) ...@@ -426,7 +421,7 @@ static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo)
clusterip_config_put(cipinfo->config); clusterip_config_put(cipinfo->config);
nf_ct_l3proto_module_put(target->family); nf_ct_l3proto_module_put(par->target->family);
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
...@@ -445,7 +440,7 @@ struct compat_ipt_clusterip_tgt_info ...@@ -445,7 +440,7 @@ struct compat_ipt_clusterip_tgt_info
static struct xt_target clusterip_tg_reg __read_mostly = { static struct xt_target clusterip_tg_reg __read_mostly = {
.name = "CLUSTERIP", .name = "CLUSTERIP",
.family = AF_INET, .family = NFPROTO_IPV4,
.target = clusterip_tg, .target = clusterip_tg,
.checkentry = clusterip_tg_check, .checkentry = clusterip_tg_check,
.destroy = clusterip_tg_destroy, .destroy = clusterip_tg_destroy,
...@@ -546,7 +541,7 @@ arp_mangle(unsigned int hook, ...@@ -546,7 +541,7 @@ arp_mangle(unsigned int hook,
static struct nf_hook_ops cip_arp_ops __read_mostly = { static struct nf_hook_ops cip_arp_ops __read_mostly = {
.hook = arp_mangle, .hook = arp_mangle,
.pf = NF_ARP, .pf = NFPROTO_ARP,
.hooknum = NF_ARP_OUT, .hooknum = NF_ARP_OUT,
.priority = -1 .priority = -1
}; };
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment