歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux 2.6.18.8內核中netfilter分析

Linux 2.6.18.8內核中netfilter分析

日期:2017/2/28 16:20:53   编辑:Linux教程
1 簡單介紹

在2.6.16內核的netfilter中,netfilter一個重大修正思想就是將netfilter作為一個協議無關的框架,表現在內核結構樹中單獨建立net/netfilter目錄,而在以前netfilter是附著在各個協議目錄之下的,如在net/ipv4, net/ipv6等目錄下。現在雖然各協議目錄下也都有,但主要是處理和各協議相關的東西了,而一些共同的東西,就都放在net/netfilter目錄下,文件名也有所改變,雖然現在還不是很獨立,比如說net/netfilter/nf_conntrack_core.c和net/ipv4/netfilter/ip_conntrack_core.c就仍然很相似,讓人覺得沒必要那麼分,但不少和協議無關的匹配和目標模塊已經和協議分離,只在此目錄下有,而不放在協議目錄下了。

在net/netfilter下的匹配和目標模塊文件名稱都以“xt_”打頭,如 xt_comment.c,xt_policy.c等

目標模塊有:

xt_CLASSIFY.c
xt_NFQUEUE.c
xt_NOTRACK.c

為了和iptables兼容(因為iptables找模塊文件前綴是按“ipt_”或“ip6t_”找的),這些文件中增加了一個新的宏定義:MODULE_ALIAS,來表示模塊的別名。

如在xt_limit.c中就如下定義:
MODULE_ALIAS("ipt_limit");
MODULE_ALIAS("ip6t_limit");

在include/linux/netfilter_ipv4/ip_tables.h中進行了以下定義:
#define ipt_match xt_match
#define ipt_target xt_target
#define ipt_table xt_table

2 代碼分析

以下是新匹配和目標模塊的結構定義:
struct xt_match
{
struct list_head list;

const char name[XT_FUNCTION_MAXNAMELEN-1];

/* 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 struct xt_match *match,
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,
const struct xt_match *match,
void *matchinfo,
unsigned int matchinfosize,
unsigned int hook_mask);

/* Called when entry of this type deleted. */
void (*destroy)(const struct xt_match *match, void *matchinfo,
unsigned int matchinfosize);

/* Called when userspace align differs from kernel space one */
int (*compat)(void *match, void **dstptr, int *size, int convert);

/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;

char *table;
unsigned int matchsize;
unsigned int hooks;
unsigned short proto;

unsigned short family;
u_int8_t revision;
};

/* Registration hooks for targets. */
struct xt_target
{
struct list_head list;

const char name[XT_FUNCTION_MAXNAMELEN-1];

/* 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 struct xt_target *target,
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,
const struct xt_target *target,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask);

/* Called when entry of this type deleted. */
void (*destroy)(const struct xt_target *target, void *targinfo,
unsigned int targinfosize);

/* Called when userspace align differs from kernel space one */
int (*compat)(void *target, void **dstptr, int *size, int convert);

/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;

char *table;
unsigned int targetsize;
unsigned int hooks;
unsigned short proto;

unsigned short family;
u_int8_t revision;
};

/* 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 */
};

/* 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];
};

/* 主要結構 */
struct xt_af {
struct mutex mutex;
struct list_head match;
struct list_head target;
struct list_head tables;
struct mutex compat_mutex;
};

/*數據結構的管理模塊 */
static struct xt_af *xt;

/* netfilter模塊初始化*/
static int __init xt_init(void)
{
int i;

/* 每種協議分配一個資源 */
xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL);
if (!xt)
return -ENOMEM;

for (i = 0; i < NPROTO; i++) {
mutex_init(&xt.mutex);
#ifdef CONFIG_COMPAT
mutex_init(&xt.compat_mutex);
#endif

/* 初始化table, target, match資源 */
INIT_LIST_HEAD(&xt.target);
INIT_LIST_HEAD(&xt.match);
INIT_LIST_HEAD(&xt.tables);
}
return 0;
}
Copyright © Linux教程網 All Rights Reserved