#ifndef _X_TABLES_H
#define _X_TABLES_H
-
+#include <linux/kernel.h>
#include <linux/types.h>
#define XT_FUNCTION_MAXNAMELEN 30
__u64 u64;
};
-#define XT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) \
- & ~(__alignof__(struct _xt_align)-1))
+#define XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _xt_align))
/* Standard return verdict, or do jump. */
#define XT_STANDARD_TARGET ""
#define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */
+#ifndef __KERNEL__
/* fn returns 0 to continue iteration */
#define XT_MATCH_ITERATE(type, e, fn, args...) \
({ \
#define XT_ENTRY_ITERATE(type, entries, size, fn, args...) \
XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args)
+#endif /* !__KERNEL__ */
+
+/* pos is normally a struct ipt_entry/ip6t_entry/etc. */
+#define xt_entry_foreach(pos, ehead, esize) \
+ for ((pos) = (typeof(pos))(ehead); \
+ (pos) < (typeof(pos))((char *)(ehead) + (esize)); \
+ (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset))
+
+/* can only be xt_entry_match, so no use of typeof here */
+#define xt_ematch_foreach(pos, entry) \
+ for ((pos) = (struct xt_entry_match *)entry->elems; \
+ (pos) < (struct xt_entry_match *)((char *)(entry) + \
+ (entry)->target_offset); \
+ (pos) = (struct xt_entry_match *)((char *)(pos) + \
+ (pos)->u.match_size))
+
#ifdef __KERNEL__
#include <linux/netdevice.h>
* @family: Actual NFPROTO_* through which the function is invoked
* (helpful when match->family == NFPROTO_UNSPEC)
* @hotdrop: drop packet if we had inspection problems
+ * Network namespace obtainable using dev_net(in/out)
*/
struct xt_match_param {
const struct net_device *in, *out;
* struct xt_mtchk_param - parameters for match extensions'
* checkentry functions
*
+ * @net: network namespace through which the check was invoked
* @table: table the rule is tried to be inserted into
* @entryinfo: the family-specific rule data
- * (struct ipt_ip, ip6t_ip, ebt_entry)
+ * (struct ipt_ip, ip6t_ip, arpt_arp or (note) ebt_entry)
* @match: struct xt_match through which this function was invoked
* @matchinfo: per-match data
* @hook_mask: via which hooks the new rule is reachable
+ * Other fields as above.
*/
struct xt_mtchk_param {
+ struct net *net;
const char *table;
const void *entryinfo;
const struct xt_match *match;
u_int8_t family;
};
-/* Match destructor parameters */
+/**
+ * struct xt_mdtor_param - match destructor parameters
+ * Fields as above.
+ */
struct xt_mtdtor_param {
+ struct net *net;
const struct xt_match *match;
void *matchinfo;
u_int8_t family;
* Other fields see above.
*/
struct xt_tgchk_param {
+ struct net *net;
const char *table;
const void *entryinfo;
const struct xt_target *target;
/* Target destructor parameters */
struct xt_tgdtor_param {
+ struct net *net;
const struct xt_target *target;
void *targinfo;
u_int8_t family;
const struct xt_match_param *);
/* Called when user tries to insert an entry of this type. */
- bool (*checkentry)(const struct xt_mtchk_param *);
+ int (*checkentry)(const struct xt_mtchk_param *);
/* Called when entry of this type deleted. */
void (*destroy)(const struct xt_mtdtor_param *);
-
+#ifdef CONFIG_COMPAT
/* Called when userspace align differs from kernel space one */
- void (*compat_from_user)(void *dst, void *src);
- int (*compat_to_user)(void __user *dst, void *src);
-
+ void (*compat_from_user)(void *dst, const void *src);
+ int (*compat_to_user)(void __user *dst, const void *src);
+#endif
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;
- /* Free to use by each match */
- unsigned long data;
-
const char *table;
unsigned int matchsize;
+#ifdef CONFIG_COMPAT
unsigned int compatsize;
+#endif
unsigned int hooks;
unsigned short proto;
struct list_head list;
const char name[XT_FUNCTION_MAXNAMELEN-1];
+ u_int8_t revision;
/* Returns verdict. Argument order changed since 2.6.9, as this
must now handle non-linear skbs, using skb_copy_bits and
/* Called when user tries to insert an entry of this type:
hook_mask is a bitmask of hooks from which it can be
called. */
- /* Should return true or false. */
- bool (*checkentry)(const struct xt_tgchk_param *);
+ /* Should return true or false, or an error code (-Exxxx). */
+ int (*checkentry)(const struct xt_tgchk_param *);
/* Called when entry of this type deleted. */
void (*destroy)(const struct xt_tgdtor_param *);
-
+#ifdef CONFIG_COMPAT
/* Called when userspace align differs from kernel space one */
- void (*compat_from_user)(void *dst, void *src);
- int (*compat_to_user)(void __user *dst, void *src);
-
+ void (*compat_from_user)(void *dst, const void *src);
+ int (*compat_to_user)(void __user *dst, const void *src);
+#endif
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;
const char *table;
unsigned int targetsize;
+#ifdef CONFIG_COMPAT
unsigned int compatsize;
+#endif
unsigned int hooks;
unsigned short proto;
unsigned short family;
- u_int8_t revision;
};
/* Furniture shopping... */
struct module *me;
u_int8_t af; /* address/protocol family */
+ int priority; /* hook order */
/* A unique name... */
const char name[XT_TABLE_MAXNAMELEN];
unsigned int hook_entry[NF_INET_NUMHOOKS];
unsigned int underflow[NF_INET_NUMHOOKS];
+ /*
+ * Number of user chains. Since tables cannot have loops, at most
+ * @stacksize jumps (number of user chains) can possibly be made.
+ */
+ unsigned int stacksize;
+ unsigned int *stackptr;
+ void ***jumpstack;
/* ipt_entry tables: one per CPU */
/* Note : this field MUST be the last one, see XT_TABLE_INFO_SZ */
void *entries[1];
extern struct xt_match *xt_find_match(u8 af, const char *name, u8 revision);
extern struct xt_target *xt_find_target(u8 af, const char *name, u8 revision);
+extern struct xt_match *xt_request_find_match(u8 af, const char *name,
+ u8 revision);
extern struct xt_target *xt_request_find_target(u8 af, const char *name,
u8 revision);
extern int xt_find_revision(u8 af, const char *name, u8 revision,
return ret;
}
+extern struct nf_hook_ops *xt_hook_link(const struct xt_table *, nf_hookfn *);
+extern void xt_hook_unlink(const struct xt_table *, struct nf_hook_ops *);
+
#ifdef CONFIG_COMPAT
#include <net/compat.h>
* current task alignment */
struct compat_xt_counters {
-#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
- u_int32_t cnt[4];
-#else
- u_int64_t cnt[2];
-#endif
+ compat_u64 pcnt, bcnt; /* Packet and byte counters */
};
struct compat_xt_counters_info {
struct compat_xt_counters counters[0];
};
-#define COMPAT_XT_ALIGN(s) (((s) + (__alignof__(struct compat_xt_counters)-1)) \
- & ~(__alignof__(struct compat_xt_counters)-1))
+struct _compat_xt_align {
+ __u8 u8;
+ __u16 u16;
+ __u32 u32;
+ compat_u64 u64;
+};
+
+#define COMPAT_XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _compat_xt_align))
extern void xt_compat_lock(u_int8_t af);
extern void xt_compat_unlock(u_int8_t af);
extern int xt_compat_add_offset(u_int8_t af, unsigned int offset, short delta);
extern void xt_compat_flush_offsets(u_int8_t af);
-extern short xt_compat_calc_jump(u_int8_t af, unsigned int offset);
+extern int xt_compat_calc_jump(u_int8_t af, unsigned int offset);
extern int xt_compat_match_offset(const struct xt_match *match);
extern int xt_compat_match_from_user(struct xt_entry_match *m,
void **dstptr, unsigned int *size);
-extern int xt_compat_match_to_user(struct xt_entry_match *m,
+extern int xt_compat_match_to_user(const struct xt_entry_match *m,
void __user **dstptr, unsigned int *size);
extern int xt_compat_target_offset(const struct xt_target *target);
extern void xt_compat_target_from_user(struct xt_entry_target *t,
void **dstptr, unsigned int *size);
-extern int xt_compat_target_to_user(struct xt_entry_target *t,
+extern int xt_compat_target_to_user(const struct xt_entry_target *t,
void __user **dstptr, unsigned int *size);
#endif /* CONFIG_COMPAT */