Commit 2e4e6a17 authored by Harald Welte's avatar Harald Welte Committed by David S. Miller
Browse files

[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables



This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables.  In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.

o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
  wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
  are now implemented as xt_FOOBAR.c files and provide module aliases
  to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
  include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
  around the xt_FOOBAR.h headers

Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.
Signed-off-by: default avatarHarald Welte <laforge@netfilter.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 880b005f
......@@ -154,6 +154,9 @@ struct ip_conntrack_stat
unsigned int expect_delete;
};
/* call to create an explicit dependency on nf_conntrack. */
extern void need_conntrack(void);
#endif /* __KERNEL__ */
#endif /* _NF_CONNTRACK_COMMON_H */
#ifndef _X_TABLES_H
#define _X_TABLES_H
#define XT_FUNCTION_MAXNAMELEN 30
#define XT_TABLE_MAXNAMELEN 32
/* The argument to IPT_SO_GET_REVISION_*. Returns highest revision
* kernel supports, if >= revision. */
struct xt_get_revision
{
char name[XT_FUNCTION_MAXNAMELEN-1];
u_int8_t revision;
};
/* CONTINUE verdict for targets */
#define XT_CONTINUE 0xFFFFFFFF
/* For standard target */
#define XT_RETURN (-NF_REPEAT - 1)
#define XT_ALIGN(s) (((s) + (__alignof__(void *)-1)) & ~(__alignof__(void *)-1))
/* Standard return verdict, or do jump. */
#define XT_STANDARD_TARGET ""
/* Error verdict. */
#define XT_ERROR_TARGET "ERROR"
/*
* New IP firewall options for [gs]etsockopt at the RAW IP level.
* Unlike BSD Linux inherits IP options so you don't have to use a raw
* socket for this. Instead we check rights in the calls. */
#define XT_BASE_CTL 64 /* base for firewall socket options */
#define XT_SO_SET_REPLACE (XT_BASE_CTL)
#define XT_SO_SET_ADD_COUNTERS (XT_BASE_CTL + 1)
#define XT_SO_SET_MAX XT_SO_SET_ADD_COUNTERS
#define XT_SO_GET_INFO (XT_BASE_CTL)
#define XT_SO_GET_ENTRIES (XT_BASE_CTL + 1)
#define XT_SO_GET_REVISION_MATCH (XT_BASE_CTL + 2)
#define XT_SO_GET_REVISION_TARGET (XT_BASE_CTL + 3)
#define XT_SO_GET_MAX XT_SO_GET_REVISION_TARGET
#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
struct xt_counters
{
u_int64_t pcnt, bcnt; /* Packet and byte counters */
};
/* The argument to IPT_SO_ADD_COUNTERS. */
struct xt_counters_info
{
/* Which table. */
char name[XT_TABLE_MAXNAMELEN];
unsigned int num_counters;
/* The counters (actually `number' of these). */
struct xt_counters counters[0];
};
#define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */
#ifdef __KERNEL__
#include <linux/netdevice.h>
#define ASSERT_READ_LOCK(x)
#define ASSERT_WRITE_LOCK(x)
#include <linux/netfilter_ipv4/listhelp.h>
struct xt_match
{
struct list_head list;
const char name[XT_FUNCTION_MAXNAMELEN-1];
u_int8_t revision;
/* Return true or false: return FALSE and set *hotdrop = 1 to
force immediate packet drop. */
/* Arguments changed since 2.6.9, as this must now handle
non-linear skb, using skb_header_pointer and
skb_ip_make_writable. */
int (*match)(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
unsigned int protoff,
int *hotdrop);
/* Called when user tries to insert an entry of this type. */
/* Should return true or false. */
int (*checkentry)(const char *tablename,
const void *ip,
void *matchinfo,
unsigned int matchinfosize,
unsigned int hook_mask);
/* Called when entry of this type deleted. */
void (*destroy)(void *matchinfo, unsigned int matchinfosize);
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;
};
/* Registration hooks for targets. */
struct xt_target
{
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
skb_ip_make_writable. */
unsigned int (*target)(struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const void *targinfo,
void *userdata);
/* 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. */
int (*checkentry)(const char *tablename,
const void *entry,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask);
/* Called when entry of this type deleted. */
void (*destroy)(void *targinfo, unsigned int targinfosize);
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;
};
/* Furniture shopping... */
struct xt_table
{
struct list_head list;
/* A unique name... */
char name[XT_TABLE_MAXNAMELEN];
/* What hooks you will enter on */
unsigned int valid_hooks;
/* Lock for the curtain */
rwlock_t lock;
/* Man behind the curtain... */
//struct ip6t_table_info *private;
void *private;
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;
int af; /* address/protocol family */
};
#include <linux/netfilter_ipv4.h>
/* The table itself */
struct xt_table_info
{
/* Size per table */
unsigned int size;
/* Number of entries: FIXME. --RR */
unsigned int number;
/* Initial number of entries. Needed for module usage count */
unsigned int initial_entries;
/* Entry points and underflows */
unsigned int hook_entry[NF_IP_NUMHOOKS];
unsigned int underflow[NF_IP_NUMHOOKS];
/* ipt_entry tables: one per CPU */
char *entries[NR_CPUS];
};
extern int xt_register_target(int af, struct xt_target *target);
extern void xt_unregister_target(int af, struct xt_target *target);
extern int xt_register_match(int af, struct xt_match *target);
extern void xt_unregister_match(int af, struct xt_match *target);
extern int xt_register_table(struct xt_table *table,
struct xt_table_info *bootstrap,
struct xt_table_info *newinfo);
extern void *xt_unregister_table(struct xt_table *table);
extern struct xt_table_info *xt_replace_table(struct xt_table *table,
unsigned int num_counters,
struct xt_table_info *newinfo,
int *error);
extern struct xt_match *xt_find_match(int af, const char *name, u8 revision);
extern struct xt_target *xt_find_target(int af, const char *name, u8 revision);
extern struct xt_target *xt_request_find_target(int af, const char *name,
u8 revision);
extern int xt_find_revision(int af, const char *name, u8 revision, int target,
int *err);
extern struct xt_table *xt_find_table_lock(int af, const char *name);
extern void xt_table_unlock(struct xt_table *t);
extern int xt_proto_init(int af);
extern void xt_proto_fini(int af);
extern struct xt_table_info *xt_alloc_table_info(unsigned int size);
extern void xt_free_table_info(struct xt_table_info *info);
#endif /* __KERNEL__ */
#endif /* _X_TABLES_H */
#ifndef _XT_CLASSIFY_H
#define _XT_CLASSIFY_H
struct xt_classify_target_info {
u_int32_t priority;
};
#endif /*_XT_CLASSIFY_H */
#ifndef _XT_CONNMARK_H_target
#define _XT_CONNMARK_H_target
/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
* by Henrik Nordstrom <hno@marasystems.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
enum {
XT_CONNMARK_SET = 0,
XT_CONNMARK_SAVE,
XT_CONNMARK_RESTORE
};
struct xt_connmark_target_info {
unsigned long mark;
unsigned long mask;
u_int8_t mode;
};
#endif /*_XT_CONNMARK_H_target*/
#ifndef _XT_MARK_H_target
#define _XT_MARK_H_target
/* Version 0 */
struct xt_mark_target_info {
unsigned long mark;
};
/* Version 1 */
enum {
XT_MARK_SET=0,
XT_MARK_AND,
XT_MARK_OR,
};
struct xt_mark_target_info_v1 {
unsigned long mark;
u_int8_t mode;
};
#endif /*_XT_MARK_H_target */
/* iptables module for using NFQUEUE mechanism
*
* (C) 2005 Harald Welte <laforge@netfilter.org>
*
* This software is distributed under GNU GPL v2, 1991
*
*/
#ifndef _XT_NFQ_TARGET_H
#define _XT_NFQ_TARGET_H
/* target info */
struct xt_NFQ_info {
u_int16_t queuenum;
};
#endif /* _XT_NFQ_TARGET_H */
#ifndef _XT_COMMENT_H
#define _XT_COMMENT_H
#define XT_MAX_COMMENT_LEN 256
struct xt_comment_info {
unsigned char comment[XT_MAX_COMMENT_LEN];
};
#endif /* XT_COMMENT_H */
#ifndef _XT_CONNBYTES_H
#define _XT_CONNBYTES_H
enum xt_connbytes_what {
XT_CONNBYTES_PKTS,
XT_CONNBYTES_BYTES,
XT_CONNBYTES_AVGPKT,
};
enum xt_connbytes_direction {
XT_CONNBYTES_DIR_ORIGINAL,
XT_CONNBYTES_DIR_REPLY,
XT_CONNBYTES_DIR_BOTH,
};
struct xt_connbytes_info
{
struct {
aligned_u64 from; /* count to be matched */
aligned_u64 to; /* count to be matched */
} count;
u_int8_t what; /* ipt_connbytes_what */
u_int8_t direction; /* ipt_connbytes_direction */
};
#endif
#ifndef _XT_CONNMARK_H
#define _XT_CONNMARK_H
/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
* by Henrik Nordstrom <hno@marasystems.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
struct xt_connmark_info {
unsigned long mark, mask;
u_int8_t invert;
};
#endif /*_XT_CONNMARK_H*/
/* Header file for kernel module to match connection tracking information.
* GPL (C) 2001 Marc Boucher (marc@mbsi.ca).
*/
#ifndef _XT_CONNTRACK_H
#define _XT_CONNTRACK_H
#include <linux/netfilter/nf_conntrack_tuple_common.h>
#include <linux/in.h>
#define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
#define XT_CONNTRACK_STATE_INVALID (1 << 0)
#define XT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1))
#define XT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2))
#define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
/* flags, invflags: */
#define XT_CONNTRACK_STATE 0x01
#define XT_CONNTRACK_PROTO 0x02
#define XT_CONNTRACK_ORIGSRC 0x04
#define XT_CONNTRACK_ORIGDST 0x08
#define XT_CONNTRACK_REPLSRC 0x10
#define XT_CONNTRACK_REPLDST 0x20
#define XT_CONNTRACK_STATUS 0x40
#define XT_CONNTRACK_EXPIRES 0x80
/* This is exposed to userspace, so remains frozen in time. */
struct ip_conntrack_old_tuple
{
struct {
__u32 ip;
union {
__u16 all;
} u;
} src;
struct {
__u32 ip;
union {
__u16 all;
} u;
/* The protocol. */
u16 protonum;
} dst;
};
struct xt_conntrack_info
{
unsigned int statemask, statusmask;
struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX];
struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX];
unsigned long expires_min, expires_max;
/* Flags word */
u_int8_t flags;
/* Inverse flags */
u_int8_t invflags;
};
#endif /*_XT_CONNTRACK_H*/
#ifndef _XT_DCCP_H_
#define _XT_DCCP_H_
#define XT_DCCP_SRC_PORTS 0x01
#define XT_DCCP_DEST_PORTS 0x02
#define XT_DCCP_TYPE 0x04
#define XT_DCCP_OPTION 0x08
#define XT_DCCP_VALID_FLAGS 0x0f
struct xt_dccp_info {
u_int16_t dpts[2]; /* Min, Max */
u_int16_t spts[2]; /* Min, Max */
u_int16_t flags;
u_int16_t invflags;
u_int16_t typemask;
u_int8_t option;
};
#endif /* _XT_DCCP_H_ */
#ifndef _XT_HELPER_H
#define _XT_HELPER_H
struct xt_helper_info {
int invert;
char name[30];
};
#endif /* _XT_HELPER_H */
#ifndef _XT_LENGTH_H
#define _XT_LENGTH_H
struct xt_length_info {
u_int16_t min, max;
u_int8_t invert;
};
#endif /*_XT_LENGTH_H*/
#ifndef _XT_RATE_H
#define _XT_RATE_H
/* timings are in milliseconds. */
#define XT_LIMIT_SCALE 10000
/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490
seconds, or one every 59 hours. */
struct xt_rateinfo {
u_int32_t avg; /* Average secs between packets * scale */
u_int32_t burst; /* Period multiplier for upper limit. */
/* Used internally by the kernel */
unsigned long prev;
u_int32_t credit;
u_int32_t credit_cap, cost;
/* Ugly, ugly fucker. */
struct xt_rateinfo *master;
};
#endif /*_XT_RATE_H*/
#ifndef _XT_MAC_H
#define _XT_MAC_H
struct xt_mac_info {
unsigned char srcaddr[ETH_ALEN];
int invert;
};
#endif /*_XT_MAC_H*/
#ifndef _XT_MARK_H
#define _XT_MARK_H
struct xt_mark_info {
unsigned long mark, mask;
u_int8_t invert;
};
#endif /*_XT_MARK_H*/
#ifndef _XT_PHYSDEV_H
#define _XT_PHYSDEV_H
#ifdef __KERNEL__
#include <linux/if.h>
#endif
#define XT_PHYSDEV_OP_IN 0x01
#define XT_PHYSDEV_OP_OUT 0x02
#define XT_PHYSDEV_OP_BRIDGED 0x04
#define XT_PHYSDEV_OP_ISIN 0x08
#define XT_PHYSDEV_OP_ISOUT 0x10
#define XT_PHYSDEV_OP_MASK (0x20 - 1)
struct xt_physdev_info {
char physindev[IFNAMSIZ];
char in_mask[IFNAMSIZ];
char physoutdev[IFNAMSIZ];
char out_mask[IFNAMSIZ];
u_int8_t invert;
u_int8_t bitmask;
};
#endif /*_XT_PHYSDEV_H*/
#ifndef _XT_PKTTYPE_H
#define _XT_PKTTYPE_H
struct xt_pkttype_info {
int pkttype;
int invert;
};
#endif /*_XT_PKTTYPE_H*/
#ifndef _XT_REALM_H
#define _XT_REALM_H
struct xt_realm_info {
u_int32_t id;
u_int32_t mask;
u_int8_t invert;
};
#endif /* _XT_REALM_H */
#ifndef _XT_SCTP_H_
#define _XT_SCTP_H_
#define XT_SCTP_SRC_PORTS 0x01
#define XT_SCTP_DEST_PORTS 0x02
#define XT_SCTP_CHUNK_TYPES 0x04
#define XT_SCTP_VALID_FLAGS 0x07
#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
struct xt_sctp_flag_info {
u_int8_t chunktype;
u_int8_t flag;
u_int8_t flag_mask;
};
#define XT_NUM_SCTP_FLAGS 4
struct xt_sctp_info {
u_int16_t dpts[2]; /* Min, Max */
u_int16_t spts[2]; /* Min, Max */
u_int32_t chunkmap[256 / sizeof (u_int32_t)]; /* Bit mask of chunks to be matched according to RFC 2960 */
#define SCTP_CHUNK_MATCH_ANY 0x01 /* Match if any of the chunk types are present */
#define SCTP_CHUNK_MATCH_ALL 0x02 /* Match if all of the chunk types are present */
#define SCTP_CHUNK_MATCH_ONLY 0x04 /* Match if these are the only chunk types present */
u_int32_t chunk_match_type;
struct xt_sctp_flag_info flag_info[XT_NUM_SCTP_FLAGS];
int flag_count;
u_int32_t flags;
u_int32_t invflags;
};
#define bytes(type) (sizeof(type) * 8)
#define SCTP_CHUNKMAP_SET(chunkmap, type) \
do { \
chunkmap[type / bytes(u_int32_t)] |= \
1 << (type % bytes(u_int32_t)); \
} while (0)
#define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \
do { \
chunkmap[type / bytes(u_int32_t)] &= \
~(1 << (type % bytes(u_int32_t))); \
} while (0)
#define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \
({ \
(chunkmap[type / bytes (u_int32_t)] & \
(1 << (type % bytes (u_int32_t)))) ? 1: 0; \
})